use super::{db, DOMAIN};
use axum::{
    extract::Query,
    response::{IntoResponse, Response},
    Extension, Json,
};
use hyper::StatusCode;
use log::error;
use serde::{Deserialize, Serialize};
use sqlx::SqlitePool;

#[derive(Deserialize)]
pub struct Params {
    id: String,
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct Comment {
    id: String,
    content: String,
    published: String,
    in_reply_to: String,
    author: Author,
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct Author {
    id: String,
    name: Option<String>,
    icon: Option<String>,
}

pub async fn handle(
    Query(params): Query<Params>,
    Extension(pool): Extension<SqlitePool>,
) -> Response {
    match get_comments(&params.id, &pool).await {
        Ok(comments) => Json(comments).into_response(),
        Err(e) => {
            error!("Error getting comments: {:?}", e);
            (StatusCode::INTERNAL_SERVER_ERROR, "Couldn't get comments").into_response()
        }
    }
}

async fn get_comments(id: &str, pool: &SqlitePool) -> anyhow::Result<Vec<Comment>> {
    let full_id = format!("https://{}{}", *DOMAIN, id);
    let conversation = db::get_conversation_for_article_id(&full_id, pool).await?;
    let notes = db::get_notes(&conversation, pool).await?;

    Ok(notes
        .into_iter()
        .map(|db| Comment {
            id: db.id,
            content: db.content,
            published: db.published,
            in_reply_to: db.in_reply_to,
            author: Author {
                id: db.actor_id,
                name: db.actor_display_name,
                icon: db.actor_icon_url,
            },
        })
        .collect())
}
