use axum::{
    extract::{Path, Query, State},
    http::StatusCode,
    routing::get,
    Json, Router,
};
use chrono::Utc;

use crate::AppState;

pub(crate) fn router() -> Router<AppState> {
    Router::new().route("/api/v1/projects/:project_id/daily-report", get(daily_report))
}

async fn daily_report(
    State(state): State<AppState>,
    Path(project_id): Path<String>,
    Query(params): Query<std::collections::HashMap<String, String>>,
) -> Result<impl axum::response::IntoResponse, StatusCode> {
    let pid = crate::resolve_project_id(&state.db, &project_id).await?;
    let date = params
        .get("date")
        .cloned()
        .unwrap_or_else(|| Utc::now().format("%Y-%m-%d").to_string());
    let nodes = state
        .db
        .nodes_by_date(pid, &date)
        .map_err(|err| crate::db_error_status("daily_report.nodes_by_date", "node", err))?;

    // Sort by creation time
    let mut nodes = nodes;
    nodes.sort_by(|a, b| a.created_at.cmp(&b.created_at));

    // Get project name
    let project = state
        .db
        .get_project(pid)
        .map_err(|err| crate::db_error_status("daily_report.get_project", "project", err))?
        .ok_or(StatusCode::NOT_FOUND)?;

    // Generate Markdown report
    let mut md = format!("# {} 日志\n\n## {}\n\n", project.name, date);

    if nodes.is_empty() {
        md.push_str("本日暂无渗透测试记录。\n");
    } else {
        for n in &nodes {
            let cst = chrono::FixedOffset::east_opt(8 * 3600).unwrap();
            let hour = n.created_at.with_timezone(&cst).format("%H:%M").to_string();
            let verdict = n
                .properties
                .get("verdict")
                .and_then(|v| v.as_str())
                .unwrap_or("");
            let evidence = n
                .properties
                .get("evidence")
                .and_then(|v| v.as_str())
                .unwrap_or("");
            let content = n
                .properties
                .get("content")
                .and_then(|v| v.as_str())
                .unwrap_or("");

            // Status icons
            let status = match verdict {
                "success" => "✅",
                "failed" => "❌",
                _ => "▶",
            };

            md.push_str(&format!("### {} {} {}\n\n", hour, status, n.label));
            md.push_str(&format!(
                "**类型**: {} | **证据**: {}\n\n",
                n.node_type, evidence
            ));
            if !content.is_empty() {
                md.push_str(&format!("{}\n\n", content));
            }
            md.push_str("---\n\n");
        }
    }

    Ok(Json(crate::types::ApiResponse::ok(serde_json::json!({
        "date": date,
        "project": project.name,
        "node_count": nodes.len(),
        "markdown": md
    }))))
}
