use std::collections::HashSet;

use actix_web::{HttpResponse, web};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

use crate::{AppState, auth::User, error::Result};

#[derive(Debug, Serialize, Deserialize)]
pub struct Repository {
    pub id: u64,
    pub name: String,
    pub full_name: String,
    pub description: Option<String>,
    pub language: Option<String>,
    #[serde(alias = "stargazers_count")]
    pub stars: Option<usize>,
    pub updated_at: DateTime<Utc>,
    pub private: bool,
    pub default_branch: String,
    #[serde(default)]
    pub added: bool,
}

pub async fn get_repos(
    app_state: web::Data<AppState>,
    user: web::ReqData<User>,
) -> Result<HttpResponse> {
    let token = app_state.user.get_access_token(&user.id).await?;

    let response = app_state
        .reqwest_client
        .get("https://api.github.com/user/repos?affiliation=owner&sort=updated&direction=desc&per_page=5")
        .bearer_auth(token)
        .send()
        .await?;
    response.error_for_status_ref()?;
    let added_ids = app_state
        .user
        .get_repositories_user(&user.id)
        .await?
        .into_iter()
        .map(|r| r.id)
        .collect::<HashSet<String>>();
    let data = response
        .json::<Vec<Repository>>()
        .await?
        .into_iter()
        .map(|mut r| {
            r.added = added_ids.contains(&r.id.to_string());
            r
        })
        .collect::<Vec<Repository>>();

    Ok(HttpResponse::Ok().json(data))
}
