use clap::{Parser, ValueEnum};
use collet_treemap::{generate_map, Config, Language, OutputFormat};
use serde_json::json;
use std::path::PathBuf;

#[derive(Debug, Clone, ValueEnum)]
enum FormatArg {
    Json,
    Text,
}

impl From<FormatArg> for OutputFormat {
    fn from(arg: FormatArg) -> Self {
        match arg {
            FormatArg::Json => OutputFormat::Json,
            FormatArg::Text => OutputFormat::Text,
        }
    }
}

#[derive(Debug, Clone, ValueEnum)]
enum LangArg {
    Rust,
    Python,
    #[value(name = "js")]
    JavaScript,
}

impl From<LangArg> for Language {
    fn from(arg: LangArg) -> Self {
        match arg {
            LangArg::Rust => Language::Rust,
            LangArg::Python => Language::Python,
            LangArg::JavaScript => Language::JavaScript,
        }
    }
}

#[derive(Parser)]
#[command(name = "collet-treemap")]
#[command(about = "Generate a code structure map from a repository using tree-sitter")]
#[command(version = "0.1.0")]
struct Cli {
    /// Path to analyze
    path: PathBuf,

    /// Output format
    #[arg(long, value_enum, default_value = "json")]
    format: FormatArg,

    /// Filter by programming language
    #[arg(long, value_enum)]
    lang: Option<LangArg>,

    /// Maximum directory depth to traverse
    #[arg(long, default_value = "10")]
    max_depth: usize,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let cli = Cli::parse();

    let config = Config {
        format: cli.format.into(),
        language: cli.lang.map(|l| l.into()),
        max_depth: cli.max_depth,
    };

    let map = generate_map(&cli.path, config)?;

    match config.format {
        OutputFormat::Json => {
            let json = json!({
                "root": map.root.to_string_lossy(),
                "files": map.files.iter().map(|f| {
                    json!({
                        "path": f.path.to_string_lossy(),
                        "language": f.language,
                        "lines": f.lines
                    })
                }).collect::<Vec<_>>(),
                "summary": {
                    "total_files": map.files.len(),
                    "total_symbols": map.symbols.len(),
                }
            });
            println!("{}", serde_json::to_string_pretty(&json)?);
        }
        OutputFormat::Text => {
            println!("Repository: {}", map.root.display());
            println!("Files: {}", map.files.len());
            println!();
            for file in &map.files {
                println!(
                    "  {} ({}) - {} lines",
                    file.path.display(),
                    file.language.as_deref().unwrap_or("unknown"),
                    file.lines
                );
            }
        }
    }

    Ok(())
}
