//! Template route handlers for serving localized template pages

#![allow(dead_code)]

use crate::template::TemplateService;
use axum::{
    Json,
    extract::{Path, Query, State},
    http::StatusCode,
    response::Html,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use tracing::{error, info, warn};

/// Query parameters for template requests
#[derive(Debug, Deserialize)]
pub struct TemplateQuery {
    /// Language code (e.g., "en", "es", "fr")
    #[allow(dead_code)]
    pub lang: Option<String>,
    /// Force reload from disk (for development)
    #[allow(dead_code)]
    pub reload: Option<bool>,
}

/// Template page response
#[derive(Debug, Serialize)]
pub struct TemplatePageResponse {
    pub content: String,
    pub template_name: String,
    pub language: String,
    pub source_path: String,
}

/// Template service error response
#[derive(Debug, Serialize)]
pub struct TemplateErrorResponse {
    pub error: String,
    pub message: String,
    pub language: String,
    pub content_name: String,
}

/// Handle template page requests
///
/// Route: GET /page/:content_name
/// Example: GET /page:getting-started?lang=en
pub async fn serve_template_page(
    Path(content_name): Path<String>,
    Query(query): Query<TemplateQuery>,
    State(template_service): State<Arc<TemplateService>>,
) -> Result<Html<String>, (StatusCode, Json<TemplateErrorResponse>)> {
    // Get language from query or use default
    let lang = query
        .lang
        .unwrap_or_else(|| template_service.get_default_language());

    // Handle reload request in development
    if query.reload.unwrap_or(false) {
        if let Err(e) = template_service.reload_templates().await {
            warn!("Failed to reload templates: {}", e);
        }
    }

    // Check if content name needs to be parsed from URL format
    let content_name = if content_name.starts_with(':') {
        content_name
            .strip_prefix(':')
            .unwrap_or(&content_name)
            .to_string()
    } else {
        content_name
    };

    info!("Serving template page: {} (lang: {})", content_name, lang);

    // Render the template page
    match template_service.render_page(&content_name, &lang).await {
        Ok(rendered) => {
            info!(
                "Successfully rendered template '{}' for content '{}' in language '{}'",
                rendered.config.template_name, content_name, lang
            );
            Ok(Html(rendered.content))
        }
        Err(e) => {
            error!(
                "Failed to render template page '{}' in language '{}': {}",
                content_name, lang, e
            );

            let error_response = TemplateErrorResponse {
                error: "template_render_error".to_string(),
                message: e.to_string(),
                language: lang,
                content_name,
            };

            Err((StatusCode::NOT_FOUND, Json(error_response)))
        }
    }
}

/// Handle template page API requests (returns JSON)
///
/// Route: GET /api/template/:content_name
/// Example: GET /api/template/getting-started?lang=en
pub async fn api_template_page(
    Path(content_name): Path<String>,
    Query(query): Query<TemplateQuery>,
    State(template_service): State<Arc<TemplateService>>,
) -> Result<Json<TemplatePageResponse>, (StatusCode, Json<TemplateErrorResponse>)> {
    let lang = query
        .lang
        .unwrap_or_else(|| template_service.get_default_language());

    // Handle reload request in development
    if query.reload.unwrap_or(false) {
        if let Err(e) = template_service.reload_templates().await {
            warn!("Failed to reload templates: {}", e);
        }
    }

    info!(
        "API request for template page: {} (lang: {})",
        content_name, lang
    );

    match template_service.render_page(&content_name, &lang).await {
        Ok(rendered) => {
            let response = TemplatePageResponse {
                content: rendered.content,
                template_name: rendered.config.template_name,
                language: lang,
                source_path: rendered.source_path,
            };

            Ok(Json(response))
        }
        Err(e) => {
            error!(
                "Failed to render template page '{}' in language '{}': {}",
                content_name, lang, e
            );

            let error_response = TemplateErrorResponse {
                error: "template_render_error".to_string(),
                message: e.to_string(),
                language: lang,
                content_name,
            };

            Err((StatusCode::NOT_FOUND, Json(error_response)))
        }
    }
}

/// List available content for a language
///
/// Route: GET /api/template/list/:lang
/// Example: GET /api/template/list/en
pub async fn list_template_content(
    Path(lang): Path<String>,
    State(template_service): State<Arc<TemplateService>>,
) -> Result<Json<Vec<String>>, (StatusCode, Json<TemplateErrorResponse>)> {
    info!("Listing available content for language: {}", lang);

    match template_service.get_available_content(&lang).await {
        Ok(content_list) => {
            info!(
                "Found {} content items for language '{}'",
                content_list.len(),
                lang
            );
            Ok(Json(content_list))
        }
        Err(e) => {
            error!("Failed to list content for language '{}': {}", lang, e);

            let error_response = TemplateErrorResponse {
                error: "content_list_error".to_string(),
                message: e.to_string(),
                language: lang,
                content_name: "".to_string(),
            };

            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
        }
    }
}

/// Get available languages
///
/// Route: GET /api/template/languages
pub async fn get_template_languages(
    State(template_service): State<Arc<TemplateService>>,
) -> Json<Vec<String>> {
    let languages = template_service.get_available_languages();
    info!("Available languages: {:?}", languages);
    Json(languages)
}

/// Get template service statistics
///
/// Route: GET /api/template/stats
pub async fn get_template_stats(
    State(template_service): State<Arc<TemplateService>>,
) -> Json<HashMap<String, serde_json::Value>> {
    let stats = template_service.get_engine_stats();
    info!("Template service stats: {:?}", stats);
    Json(stats)
}

/// Clear template cache
///
/// Route: POST /api/template/cache/clear
pub async fn clear_template_cache(
    State(template_service): State<Arc<TemplateService>>,
) -> Result<Json<serde_json::Value>, (StatusCode, Json<TemplateErrorResponse>)> {
    info!("Clearing template cache");

    match template_service.clear_cache().await {
        Ok(_) => {
            info!("Template cache cleared successfully");
            Ok(Json(serde_json::json!({
                "success": true,
                "message": "Template cache cleared"
            })))
        }
        Err(e) => {
            error!("Failed to clear template cache: {}", e);

            let error_response = TemplateErrorResponse {
                error: "cache_clear_error".to_string(),
                message: e.to_string(),
                language: "".to_string(),
                content_name: "".to_string(),
            };

            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
        }
    }
}

/// Reload templates from disk
///
/// Route: POST /api/template/reload
pub async fn reload_templates(
    State(template_service): State<Arc<TemplateService>>,
) -> Result<Json<serde_json::Value>, (StatusCode, Json<TemplateErrorResponse>)> {
    info!("Reloading templates from disk");

    match template_service.reload_templates().await {
        Ok(_) => {
            info!("Templates reloaded successfully");
            Ok(Json(serde_json::json!({
                "success": true,
                "message": "Templates reloaded from disk"
            })))
        }
        Err(e) => {
            error!("Failed to reload templates: {}", e);

            let error_response = TemplateErrorResponse {
                error: "template_reload_error".to_string(),
                message: e.to_string(),
                language: "".to_string(),
                content_name: "".to_string(),
            };

            Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)))
        }
    }
}

/// Check if a template page exists
///
/// Route: GET /api/template/exists/:content_name
pub async fn check_template_exists(
    Path(content_name): Path<String>,
    Query(query): Query<TemplateQuery>,
    State(template_service): State<Arc<TemplateService>>,
) -> Json<serde_json::Value> {
    let lang = query
        .lang
        .unwrap_or_else(|| template_service.get_default_language());
    let exists = template_service.page_exists(&content_name, &lang);

    info!(
        "Template page '{}' exists in language '{}': {}",
        content_name, lang, exists
    );

    Json(serde_json::json!({
        "exists": exists,
        "content_name": content_name,
        "language": lang
    }))
}

/// Get template configuration for a page
///
/// Route: GET /api/template/config/:content_name
pub async fn get_template_config(
    Path(content_name): Path<String>,
    Query(query): Query<TemplateQuery>,
    State(template_service): State<Arc<TemplateService>>,
) -> Result<Json<serde_json::Value>, (StatusCode, Json<TemplateErrorResponse>)> {
    let lang = query
        .lang
        .unwrap_or_else(|| template_service.get_default_language());

    info!(
        "Getting template config for '{}' in language '{}'",
        content_name, lang
    );

    match template_service.get_page_config(&content_name, &lang).await {
        Ok(config) => Ok(Json(serde_json::json!({
            "template_name": config.template_name,
            "values": config.values,
            "metadata": config.metadata,
            "language": lang,
            "content_name": content_name
        }))),
        Err(e) => {
            error!(
                "Failed to get template config for '{}' in language '{}': {}",
                content_name, lang, e
            );

            let error_response = TemplateErrorResponse {
                error: "config_load_error".to_string(),
                message: e.to_string(),
                language: lang,
                content_name,
            };

            Err((StatusCode::NOT_FOUND, Json(error_response)))
        }
    }
}

/// Health check for template service
///
/// Route: GET /api/template/health
pub async fn template_health_check(
    State(template_service): State<Arc<TemplateService>>,
) -> Json<serde_json::Value> {
    let stats = template_service.get_engine_stats();
    let default_lang = template_service.get_default_language();
    let available_langs = template_service.get_available_languages();

    Json(serde_json::json!({
        "status": "healthy",
        "default_language": default_lang,
        "available_languages": available_langs,
        "stats": stats
    }))
}
