use axum::{extract::{Path, State}, Json};
use common_contracts::config_models::{AnalysisTemplateSets, AnalysisTemplateSet, AnalysisTemplateSummary};
use service_kit::api;
use crate::{db::system_config, AppState, ServerError};

#[api(GET, "/api/v1/templates", output(detail = "Vec<AnalysisTemplateSummary>"))]
pub async fn get_templates(
    State(state): State<AppState>,
) -> Result<Json<Vec<AnalysisTemplateSummary>>, ServerError> {
    let pool = state.pool();
    // Note: This fetches the entire config blob. Optimization would be to query JSONB fields directly,
    // but for now we follow the document-store pattern as requested.
    let config = system_config::get_config::<AnalysisTemplateSets>(pool, "analysis_template_sets").await?;
    
    let mut summaries: Vec<AnalysisTemplateSummary> = config.iter()
        .map(|(id, template)| AnalysisTemplateSummary {
            id: id.clone(),
            name: template.name.clone(),
        })
        .collect();
    
    // Sort by name for consistency
    summaries.sort_by(|a, b| a.name.cmp(&b.name));

    Ok(Json(summaries))
}

#[api(GET, "/api/v1/templates/{id}", output(detail = "AnalysisTemplateSet"))]
pub async fn get_template_by_id(
    State(state): State<AppState>,
    Path(id): Path<String>,
) -> Result<Json<AnalysisTemplateSet>, ServerError> {
    let pool = state.pool();
    let mut config = system_config::get_config::<AnalysisTemplateSets>(pool, "analysis_template_sets").await?;
    
    let template = config.remove(&id).ok_or_else(|| ServerError::NotFound(format!("Template {} not found", id)))?;
    
    Ok(Json(template))
}

#[api(PUT, "/api/v1/templates/{id}", output(detail = "AnalysisTemplateSet"))]
pub async fn update_template(
    State(state): State<AppState>,
    Path(id): Path<String>,
    Json(payload): Json<AnalysisTemplateSet>,
) -> Result<Json<AnalysisTemplateSet>, ServerError> {
    let pool = state.pool();
    // 1. Fetch the whole config blob
    let mut config = system_config::get_config::<AnalysisTemplateSets>(pool, "analysis_template_sets").await?;
    
    // 2. Update the specific template in the map
    config.insert(id.clone(), payload);
    
    // 3. Save the whole blob back
    let _ = system_config::update_config(pool, "analysis_template_sets", &config).await?;
    
    // 4. Return the updated template
    Ok(Json(config.remove(&id).unwrap()))
}

#[api(DELETE, "/api/v1/templates/{id}")]
pub async fn delete_template(
    State(state): State<AppState>,
    Path(id): Path<String>,
) -> Result<axum::http::StatusCode, ServerError> {
    let pool = state.pool();
    // 1. Fetch the whole config blob
    let mut config = system_config::get_config::<AnalysisTemplateSets>(pool, "analysis_template_sets").await?;
    
    // 2. Remove the specific template
    if config.remove(&id).is_none() {
        return Err(ServerError::NotFound(format!("Template {} not found", id)));
    }
    
    // 3. Save the whole blob back
    let _ = system_config::update_config(pool, "analysis_template_sets", &config).await?;
    
    Ok(axum::http::StatusCode::NO_CONTENT)
}

