//! Template system for generating documentation using Tera engine
//!
//! This module provides a complete templating system for generating consistent,
//! internationalized documentation from route analysis data.

use crate::route_analysis::{ApiRouteInfo, ComponentInfo, PageRouteInfo, SourceReference};
use serde::Serialize;
use std::collections::HashMap;
// tera types are used in engine.rs

pub mod engine;
pub mod generator;
pub mod i18n;
pub mod integration;

// Re-export main types for easy usage
pub use engine::DocumentationTemplateEngine;
pub use generator::DocumentationGenerator;

// Re-export integration functions for build system
pub use integration::{
    generate_section_documentation, generate_site_documentation, legacy_save_documentation,
    save_documentation_with_templates,
};

/// Template context data for documentation generation
#[derive(Debug, Clone, Serialize)]
pub struct DocumentationContext {
    /// Metadata about the generation process
    pub metadata: DocumentMetadata,
    /// Server API routes data
    pub routes: Vec<TemplateRouteInfo>,
    /// Component information
    pub components: Vec<TemplateComponentInfo>,
    /// Page route information
    pub pages: Vec<TemplatePageInfo>,
    /// Internationalization data
    pub i18n: I18nContext,
    /// Theme and styling configuration
    pub theme: ThemeConfig,
    /// Summary statistics
    pub summary: SummaryStats,
}

/// Metadata about document generation
#[derive(Debug, Clone, Serialize)]
pub struct DocumentMetadata {
    /// When the documentation was generated
    pub generated_at: String,
    /// Language code (en, es, etc.)
    pub language: String,
    /// Document type (summary, reference, automation, etc.)
    pub doc_type: String,
    /// Project name
    pub project_name: String,
    /// Generator version
    pub generator_version: String,
}

/// Template-friendly route information
#[derive(Debug, Clone, Serialize)]
pub struct TemplateRouteInfo {
    pub path: String,
    pub methods: Vec<String>,
    pub handler: String,
    pub module: String,
    pub parameters: Vec<TemplateRouteParameter>,
    pub response_type: String,
    pub requires_auth: bool,
    pub middleware: Vec<String>,
    pub description: Option<String>,
    pub src_ref: Option<TemplateSourceRef>,
    pub anchor: String, // Generated anchor for deep linking
}

/// Template-friendly route parameter
#[derive(Debug, Clone, Serialize)]
pub struct TemplateRouteParameter {
    pub name: String,
    pub param_type: String,
    pub source: String,
    pub optional: bool,
    pub description: Option<String>,
}

/// Template-friendly component information
#[derive(Debug, Clone, Serialize)]
pub struct TemplateComponentInfo {
    pub name: String,
    pub component_type: String,
    pub module_path: String,
    pub props: Vec<String>,
    pub description: Option<String>,
    pub usage_example: Option<String>,
    pub src_ref: Option<TemplateSourceRef>,
    pub anchor: String,
}

/// Template-friendly page information
#[derive(Debug, Clone, Serialize)]
pub struct TemplatePageInfo {
    pub path: String,
    pub component: String,
    pub page_component: String,
    pub unified_component: String,
    pub module_path: Option<String>,
    pub language: String,
    pub enabled: bool,
    pub priority: f64,
    pub requires_auth: Option<bool>,
    pub menu_group: Option<String>,
    pub menu_order: Option<i32>,
    pub title_key: String,
    pub keywords: Vec<String>,
    pub src_ref: Option<TemplateSourceRef>,
    pub anchor: String,
}

/// Template-friendly source reference
#[derive(Debug, Clone, Serialize)]
pub struct TemplateSourceRef {
    pub path: String,
    pub line: usize,
    pub context: String,
    pub link: String, // Formatted link text
}

/// Internationalization context
#[derive(Debug, Clone, Serialize)]
pub struct I18nContext {
    pub language: String,
    pub direction: String, // ltr, rtl
    pub date_format: String,
    pub labels: HashMap<String, String>,
}

/// Theme configuration for documentation
#[derive(Debug, Clone, Serialize)]
pub struct ThemeConfig {
    pub name: String,
    pub compact: bool,
    pub show_toc: bool,
    pub show_anchors: bool,
    pub show_source_links: bool,
}

/// Summary statistics for overview sections
#[derive(Debug, Clone, Serialize)]
pub struct SummaryStats {
    pub total_routes: usize,
    pub total_components: usize,
    pub total_pages: usize,
    pub languages: Vec<String>,
    pub auth_required_routes: usize,
    pub static_routes: usize,
    pub api_routes: usize,
}

impl DocumentationContext {
    /// Create a new documentation context from analysis data
    pub fn new(
        routes: Vec<ApiRouteInfo>,
        components: Vec<ComponentInfo>,
        pages: Vec<PageRouteInfo>,
        language: &str,
        doc_type: &str,
    ) -> Self {
        let template_routes = routes
            .into_iter()
            .map(TemplateRouteInfo::from)
            .collect::<Vec<_>>();
        let template_components = components
            .into_iter()
            .map(TemplateComponentInfo::from)
            .collect::<Vec<_>>();
        let template_pages = pages
            .into_iter()
            .map(TemplatePageInfo::from)
            .collect::<Vec<_>>();

        let summary =
            SummaryStats::calculate(&template_routes, &template_components, &template_pages);

        Self {
            metadata: DocumentMetadata {
                generated_at: chrono::Utc::now().to_rfc3339(),
                language: language.to_string(),
                doc_type: doc_type.to_string(),
                project_name: "Rustelo".to_string(),
                generator_version: env!("CARGO_PKG_VERSION").to_string(),
            },
            routes: template_routes,
            components: template_components,
            pages: template_pages,
            i18n: I18nContext::for_language(language),
            theme: ThemeConfig::default(),
            summary,
        }
    }
}

impl From<ApiRouteInfo> for TemplateRouteInfo {
    fn from(route: ApiRouteInfo) -> Self {
        Self {
            anchor: crate::route_analysis::generate_anchor("route", &route.path),
            path: route.path,
            methods: route.methods,
            handler: route.handler,
            module: route.module,
            parameters: route.parameters.into_iter().map(Into::into).collect(),
            response_type: route.response_type,
            requires_auth: route.requires_auth,
            middleware: route.middleware,
            description: route.description,
            src_ref: route.src_ref.map(Into::into),
        }
    }
}

impl From<crate::route_analysis::RouteParameter> for TemplateRouteParameter {
    fn from(param: crate::route_analysis::RouteParameter) -> Self {
        Self {
            name: param.name,
            param_type: param.param_type,
            source: param.source,
            optional: param.optional,
            description: param.description,
        }
    }
}

impl From<ComponentInfo> for TemplateComponentInfo {
    fn from(comp: ComponentInfo) -> Self {
        Self {
            anchor: crate::route_analysis::generate_anchor("component", &comp.name),
            name: comp.name,
            component_type: comp.component_type,
            module_path: comp.module_path,
            props: comp.props.into_iter().map(|p| p.to_string()).collect(),
            description: comp.description,
            usage_example: comp.usage_example,
            src_ref: comp.src_ref.map(Into::into),
        }
    }
}

impl From<PageRouteInfo> for TemplatePageInfo {
    fn from(page: PageRouteInfo) -> Self {
        Self {
            anchor: crate::route_analysis::generate_anchor("page", &page.path),
            path: page.path,
            component: page.component,
            page_component: page.page_component,
            unified_component: page.unified_component,
            module_path: page.module_path,
            language: page.language,
            enabled: page.enabled,
            priority: page.priority,
            requires_auth: page.requires_auth,
            menu_group: page.menu_group,
            menu_order: page.menu_order,
            title_key: page.title_key,
            keywords: page.keywords,
            src_ref: page.src_ref.map(Into::into),
        }
    }
}

impl From<SourceReference> for TemplateSourceRef {
    fn from(src: SourceReference) -> Self {
        Self {
            link: crate::route_analysis::format_source_link(&src),
            path: src.path,
            line: src.line,
            context: src.context,
        }
    }
}

impl I18nContext {
    fn for_language(language: &str) -> Self {
        match language {
            "es" => Self {
                language: "es".to_string(),
                direction: "ltr".to_string(),
                date_format: "%d-%m-%Y %H:%M:%S UTC".to_string(),
                labels: spanish_labels(),
            },
            _ => Self {
                language: "en".to_string(),
                direction: "ltr".to_string(),
                date_format: "%Y-%m-%d %H:%M:%S UTC".to_string(),
                labels: english_labels(),
            },
        }
    }
}

impl Default for ThemeConfig {
    fn default() -> Self {
        Self {
            name: "default".to_string(),
            compact: false,
            show_toc: true,
            show_anchors: true,
            show_source_links: true,
        }
    }
}

impl SummaryStats {
    fn calculate(
        routes: &[TemplateRouteInfo],
        components: &[TemplateComponentInfo],
        pages: &[TemplatePageInfo],
    ) -> Self {
        let languages: std::collections::HashSet<String> =
            pages.iter().map(|p| p.language.clone()).collect();

        let auth_required_routes = routes.iter().filter(|r| r.requires_auth).count();
        let static_routes = routes
            .iter()
            .filter(|r| r.response_type == "Static Files")
            .count();
        let api_routes = routes.len() - static_routes;

        Self {
            total_routes: routes.len(),
            total_components: components.len(),
            total_pages: pages.len(),
            languages: languages.into_iter().collect(),
            auth_required_routes,
            static_routes,
            api_routes,
        }
    }
}

fn english_labels() -> HashMap<String, String> {
    let mut labels = HashMap::new();
    labels.insert("title".to_string(), "Documentation".to_string());
    labels.insert("generated_at".to_string(), "Generated at".to_string());
    labels.insert("summary".to_string(), "Summary".to_string());
    labels.insert(
        "table_of_contents".to_string(),
        "Table of Contents".to_string(),
    );
    labels.insert("routes".to_string(), "Routes".to_string());
    labels.insert("components".to_string(), "Components".to_string());
    labels.insert("pages".to_string(), "Pages".to_string());
    labels.insert("source".to_string(), "source".to_string());
    labels.insert("line".to_string(), "line".to_string());
    labels.insert("context".to_string(), "context".to_string());
    labels.insert("methods".to_string(), "Methods".to_string());
    labels.insert("handler".to_string(), "Handler".to_string());
    labels.insert("module".to_string(), "Module".to_string());
    labels.insert("parameters".to_string(), "Parameters".to_string());
    labels.insert("response_type".to_string(), "Response Type".to_string());
    labels.insert("requires_auth".to_string(), "Requires Auth".to_string());
    labels.insert("middleware".to_string(), "Middleware".to_string());
    labels.insert("description".to_string(), "Description".to_string());
    labels
}

fn spanish_labels() -> HashMap<String, String> {
    let mut labels = HashMap::new();
    labels.insert("title".to_string(), "Documentación".to_string());
    labels.insert("generated_at".to_string(), "Generado el".to_string());
    labels.insert("summary".to_string(), "Resumen".to_string());
    labels.insert(
        "table_of_contents".to_string(),
        "Índice de Contenidos".to_string(),
    );
    labels.insert("routes".to_string(), "Rutas".to_string());
    labels.insert("components".to_string(), "Componentes".to_string());
    labels.insert("pages".to_string(), "Páginas".to_string());
    labels.insert("source".to_string(), "fuente".to_string());
    labels.insert("line".to_string(), "línea".to_string());
    labels.insert("context".to_string(), "contexto".to_string());
    labels.insert("methods".to_string(), "Métodos".to_string());
    labels.insert("handler".to_string(), "Manejador".to_string());
    labels.insert("module".to_string(), "Módulo".to_string());
    labels.insert("parameters".to_string(), "Parámetros".to_string());
    labels.insert("response_type".to_string(), "Tipo de Respuesta".to_string());
    labels.insert("requires_auth".to_string(), "Requiere Auth".to_string());
    labels.insert("middleware".to_string(), "Middleware".to_string());
    labels.insert("description".to_string(), "Descripción".to_string());
    labels
}
