//! Frontmatter parsing and normalization utilities

use anyhow::{Context, Result};
use std::fs;

#[cfg(feature = "content-static")]
use rustelo_server::content::file_loader::FrontMatter;

/// Normalize source frontmatter in markdown files
pub fn normalize_source_frontmatter(input_file: &str, original_content: &str) -> Result<bool> {
    if !input_file.ends_with(".md") {
        return Ok(false);
    }

    let mut changed = false;
    let mut lines: Vec<String> = original_content.lines().map(|s| s.to_string()).collect();

    // Find frontmatter boundaries
    let mut frontmatter_start = None;
    let mut frontmatter_end = None;

    for (i, line) in lines.iter().enumerate() {
        if line.trim() == "---" {
            if frontmatter_start.is_none() {
                frontmatter_start = Some(i);
            } else {
                frontmatter_end = Some(i);
                break;
            }
        }
    }

    if let (Some(start), Some(end)) = (frontmatter_start, frontmatter_end) {
        // Process frontmatter section
        for i in (start + 1)..end {
            let line = lines[i].clone();

            // Normalize boolean values
            if line.contains("published:") || line.contains("featured:") {
                let parts: Vec<&str> = line.split(':').collect();
                if parts.len() >= 2 {
                    let key = parts[0].trim();
                    let value = parts[1].trim();

                    // Normalize boolean values
                    let value_lower = value.to_lowercase();
                    let normalized_value = match value_lower.as_str() {
                        "yes" | "y" | "1" | "on" => "true",
                        "no" | "n" | "0" | "off" => "false",
                        v if v == "true" || v == "false" => v,
                        _ => value, // Keep original if not a boolean
                    };

                    if normalized_value != value {
                        lines[i] = format!("{}: {}", key, normalized_value);
                        changed = true;
                        println!(
                            "🔧 Normalized frontmatter: '{}' -> '{}'",
                            value, normalized_value
                        );
                    }
                }
            }

            // Normalize tags and categories arrays
            if line.contains("tags:") || line.contains("categories:") {
                let line_content = line.trim();

                // Convert single values to arrays
                if line_content.contains(':') && !line_content.contains('[') {
                    let parts: Vec<&str> = line_content.split(':').collect();
                    if parts.len() >= 2 {
                        let key = parts[0].trim();
                        let value = parts[1].trim();

                        if !value.is_empty() && value != "[]" {
                            // Convert single value to array format
                            if !value.starts_with('[') {
                                lines[i] = format!("{}: [{}]", key, value);
                                changed = true;
                                println!("🔧 Normalized array: '{}' -> '[{}]'", value, value);
                            }
                        }
                    }
                }
            }
        }
    }

    // Write back if changed
    if changed {
        let normalized_content = lines.join("\n");
        fs::write(input_file, normalized_content).context(format!(
            "Failed to write normalized content to {}",
            input_file
        ))?;

        println!("✅ Normalized frontmatter in: {}", input_file);
    }

    Ok(changed)
}

/// Parse frontmatter from markdown content
#[cfg(feature = "content-static")]
pub fn parse_frontmatter(content: &str) -> Result<(FrontMatter, String)> {
    if !content.starts_with("---") {
        return Ok((FrontMatter::default(), content.to_string()));
    }

    let parts: Vec<&str> = content.splitn(3, "---").collect();
    if parts.len() < 3 {
        return Ok((FrontMatter::default(), content.to_string()));
    }

    let frontmatter_yaml = parts[1];
    let body = parts[2].trim_start_matches('\n');

    let frontmatter: FrontMatter =
        serde_yaml::from_str(frontmatter_yaml).context("Failed to parse YAML frontmatter")?;

    Ok((frontmatter, body.to_string()))
}
