use achubb_database::data::{project::Project, PsqlData};
use askama::Template;
use axum::extract::{Extension, Path};
use axum::http::StatusCode;
use axum::response::IntoResponse;
use axum::{routing::get, Router};
use sqlx::PgPool;
use std::{collections::HashMap, error::Error};

use super::{root::AppState, ArticleTemplate, HtmlTemplate};

pub fn get_router() -> Router {
    Router::new()
        .route("/", get(projects))
        .route("/:project", get(project))
}

pub async fn projects(state: Extension<AppState>) -> impl IntoResponse {
    let db_pool = &state.db;
    let list: Vec<String> = get_projects_as_links_list(db_pool)
        .await
        .expect("couldn't get projects");
    let template = ProjectsTemplate {
        project_list: list.join("\n"),
    };
    HtmlTemplate(template)
}

#[derive(Template)]
#[template(path = "projects.html")]
struct ProjectsTemplate {
    project_list: String,
}

async fn project(
    state: Extension<AppState>,
    Path(params): Path<HashMap<String, String>>,
) -> Result<impl IntoResponse, StatusCode> {
    let db_pool = &state.db;
    let project_id: &String = params.get("project").unwrap();
    let project: Project = match Project::read_by_reference(db_pool, project_id).await {
        Ok(a) => *a,
        Err(_) => return Err(StatusCode::NOT_FOUND),
    };
    let footer: &str = "<a href=\"/projects\">Back to Projects</a>";
    let template = ArticleTemplate {
        content: project
            .content
            .expect("Should have had content if it got this far"),
        footer: footer.to_string(),
    };
    Ok(HtmlTemplate(template))
}

pub async fn get_projects_as_links_list(pool: &PgPool) -> Result<Vec<String>, Box<dyn Error>> {
    let mut projects: Vec<Project> = match Project::read_all(pool).await {
        Ok(a) => a.iter().map(|x| *x.clone()).collect(),
        Err(_) => Vec::new(),
    };

    projects.sort_by(|a, b| b.date.cmp(&a.date));

    let list: Vec<String> = projects
        .iter()
        .map(|project| {
            if project.blog {
                format!(
                    "<li><a href=\"/blog/{}\">{}</a></li>",
                    project.reference, project.title
                )
            } else {
                format!(
                    "<li><a href=\"/projects/{}\">{}</a></li>",
                    project.reference, project.title
                )
            }
        })
        .collect();
    Ok(list)
}
