//! High-level documentation generation with graceful error handling

use super::{DocumentationContext, DocumentationTemplateEngine};
use crate::route_analysis::{ApiRouteInfo, ComponentInfo, PageRouteInfo};
use std::fs;
use std::path::Path;

/// Documentation generator with graceful failure handling
pub struct DocumentationGenerator {
    engine: Option<DocumentationTemplateEngine>,
}

impl DocumentationGenerator {
    /// Create new generator with graceful template loading
    pub fn new() -> Self {
        Self {
            engine: DocumentationTemplateEngine::new(),
        }
    }

    /// Check if templates are available
    pub fn is_available(&self) -> bool {
        self.engine.is_some()
    }

    /// Generate all documentation types
    /// Returns true if any documentation was generated, false if templates unavailable
    pub fn generate_all_documentation(
        &self,
        routes: Vec<ApiRouteInfo>,
        components: Vec<ComponentInfo>,
        pages: Vec<PageRouteInfo>,
        output_dir: &str,
        languages: &[&str],
    ) -> bool {
        // Early exit if templates not available - no error, just skip
        match &self.engine {
            Some(_) => {}
            None => {
                eprintln!("📝 Skipping documentation generation - templates not available.");
                return false;
            }
        };

        let mut generated_any = false;

        // Generate for each language
        for &language in languages {
            if self.generate_language_documentation(
                &routes,
                &components,
                &pages,
                output_dir,
                language,
            ) {
                generated_any = true;
            }
        }

        if generated_any {
            println!("✅ Site-info documentation generated successfully!");
        } else {
            eprintln!("⚠️  No documentation was generated due to template issues.");
        }

        generated_any
    }

    /// Generate documentation for a specific language
    fn generate_language_documentation(
        &self,
        routes: &[ApiRouteInfo],
        components: &[ComponentInfo],
        pages: &[PageRouteInfo],
        output_dir: &str,
        language: &str,
    ) -> bool {
        let engine = self.engine.as_ref().unwrap();

        // Create documentation context
        let context = DocumentationContext::new(
            routes.to_vec(),
            components.to_vec(),
            pages.to_vec(),
            language,
            "reference",
        );

        let mut generated_any = false;

        // Generate summary documentation
        if let Some(summary_content) = engine.render_documentation("summary", &context) {
            if self.write_documentation_file(output_dir, "summary.md", &summary_content) {
                generated_any = true;
            }
        }

        // Generate reference documentation
        if let Some(reference_content) = engine.render_documentation("reference", &context) {
            if self.write_documentation_file(output_dir, "reference.md", &reference_content) {
                generated_any = true;
            }
        }

        // Generate automation guide
        if let Some(automation_content) = engine.render_documentation("automation", &context) {
            if self.write_documentation_file(output_dir, "automation.md", &automation_content) {
                generated_any = true;
            }
        }

        // Generate top-level overview (for main directory)
        if language == "en" {
            // Only generate top-level for default language
            if let Some(top_level_content) = engine.render_documentation("top_level", &context) {
                let parent_dir = Path::new(output_dir)
                    .parent()
                    .unwrap_or_else(|| Path::new("."));
                if self.write_documentation_file(
                    parent_dir.to_str().unwrap(),
                    "summary.md",
                    &top_level_content,
                ) {
                    generated_any = true;
                }
            }
        }

        generated_any
    }

    /// Write documentation file with error handling
    fn write_documentation_file(&self, dir: &str, filename: &str, content: &str) -> bool {
        let dir_path = Path::new(dir);

        // Create directory if it doesn't exist
        if let Err(e) = fs::create_dir_all(dir_path) {
            eprintln!("🚨 BIG WARNING: Failed to create documentation directory!");
            eprintln!("   Directory: {}", dir_path.display());
            eprintln!("   Error: {}", e);
            eprintln!("   📝 Skipping file: {}", filename);
            return false;
        }

        let file_path = dir_path.join(filename);

        match fs::write(&file_path, content) {
            Ok(_) => {
                println!("📄 Generated: {}", file_path.display());
                true
            }
            Err(e) => {
                eprintln!("🚨 BIG WARNING: Failed to write documentation file!");
                eprintln!("   File: {}", file_path.display());
                eprintln!("   Error: {}", e);
                eprintln!("   📝 Check file permissions and disk space.");
                false
            }
        }
    }

    /// Generate only TOML/JSON data files (fallback when templates unavailable)
    pub fn generate_data_only(
        &self,
        routes: Vec<ApiRouteInfo>,
        components: Vec<ComponentInfo>,
        pages: Vec<PageRouteInfo>,
        output_dir: &str,
    ) -> bool {
        eprintln!("📊 Generating data-only output (templates unavailable)");

        let dir_path = Path::new(output_dir);
        if let Err(e) = fs::create_dir_all(dir_path) {
            eprintln!("🚨 BIG WARNING: Failed to create output directory!");
            eprintln!("   Directory: {}", dir_path.display());
            eprintln!("   Error: {}", e);
            return false;
        }

        let mut generated_any = false;

        // Generate TOML data file
        if let Ok(toml_content) = create_toml_data(&routes, &components, &pages) {
            let toml_file = dir_path.join("data.toml");
            if fs::write(&toml_file, toml_content).is_ok() {
                println!("📄 Generated: {}", toml_file.display());
                generated_any = true;
            } else {
                eprintln!("⚠️  Failed to write TOML data file");
            }
        }

        // Generate JSON data file
        if let Ok(json_content) = create_json_data(&routes, &components, &pages) {
            let json_file = dir_path.join("data.json");
            if fs::write(&json_file, json_content).is_ok() {
                println!("📄 Generated: {}", json_file.display());
                generated_any = true;
            } else {
                eprintln!("⚠️  Failed to write JSON data file");
            }
        }

        if generated_any {
            println!("✅ Data files generated successfully (without templates)!");
        }

        generated_any
    }
}

/// Create TOML data representation
fn create_toml_data(
    routes: &[ApiRouteInfo],
    _components: &[ComponentInfo],
    _pages: &[PageRouteInfo],
) -> Result<String, Box<dyn std::error::Error>> {
    use crate::route_analysis::RouteDocumentation;

    let mut doc = RouteDocumentation::new();
    doc.api_routes = routes.to_vec();

    toml::to_string_pretty(&doc).map_err(|e| e.into())
}

/// Create JSON data representation
fn create_json_data(
    routes: &[ApiRouteInfo],
    _components: &[ComponentInfo],
    _pages: &[PageRouteInfo],
) -> Result<String, Box<dyn std::error::Error>> {
    use crate::route_analysis::RouteDocumentation;

    let mut doc = RouteDocumentation::new();
    doc.api_routes = routes.to_vec();

    serde_json::to_string_pretty(&doc).map_err(|e| e.into())
}
