use sonic_bridge::config::SonicConfig;
use sonic_bridge::pipeline::SonicPipeline;
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;

fn main() {
    let args: Vec<String> = env::args().collect();

    // Global interception for help/version flags before any heavy parsing
    if args
        .iter()
        .any(|arg| arg == "-h" || arg == "--help" || arg == "help")
    {
        print_usage();
        return;
    }
    if args
        .iter()
        .any(|arg| arg == "-v" || arg == "--version" || arg == "version")
    {
        print_version();
        return;
    }

    if args.len() < 2 {
        print_usage();
        return;
    }

    let mut config_path = None;
    let mut use_onset = false;
    let mut use_quiet = false;
    let mut use_render = false;
    let mut clean_args = Vec::new();

    let mut i = 1;
    while i < args.len() {
        if args[i] == "--config" {
            if i + 1 < args.len() {
                config_path = Some(args[i + 1].clone());
                i += 2;
            } else {
                eprintln!(
                    "\x1b[1;31m[-] Error:\x1b[0m --config option requires a valid file path value."
                );
                print_usage();
                std::process::exit(1);
            }
        } else if args[i] == "--onset" {
            use_onset = true;
            i += 1;
        } else if args[i] == "--quiet" || args[i] == "-q" {
            use_quiet = true;
            i += 1;
        } else if args[i] == "--render" {
            use_render = true;
            i += 1;
        } else if args[i].starts_with('-') && !Path::new(&args[i]).exists() {
            eprintln!(
                "\x1b[1;31m[-] Error:\x1b[0m Unknown option: \x1b[33m{}\x1b[0m",
                args[i]
            );
            print_usage();
            std::process::exit(1);
        } else {
            clean_args.push(args[i].clone());
            i += 1;
        }
    }

    if clean_args.is_empty() {
        print_usage();
        return;
    }

    // Load SonicConfig
    let mut config = if let Some(ref path_str) = config_path {
        SonicConfig::load_from_file(Path::new(path_str)).unwrap_or_else(|e| {
            eprintln!(
                "\x1b[1;33m[!] Warning:\x1b[0m Failed to load config from {}: {}. Falling back to default.",
                path_str, e
            );
            SonicConfig::default()
        })
    } else {
        SonicConfig::load_or_default()
    };

    // Command-line flag override
    if use_onset {
        config.onset_mode = true;
    }
    if use_quiet {
        config.quiet_mode = true;
    }

    if clean_args.len() == 1 {
        // 单音轨审美分析模式
        let audio_path = Path::new(&clean_args[0]);

        // Physical existence check
        if !audio_path.exists() {
            eprintln!(
                "\x1b[1;31m[-] Error:\x1b[0m Audio file does not exist: \x1b[33m{}\x1b[0m",
                audio_path.display()
            );
            std::process::exit(1);
        }

        // Appreciation live scrolling mode
        if use_render {
            let alrc_path = audio_path.with_extension("alrc");
            if !alrc_path.exists() {
                eprintln!(
                    "\x1b[1;31m[-] Error:\x1b[0m Aesthetic Lyrics file (.alrc) not found: \x1b[33m{}\x1b[0m\nPlease compile the .alrc file via sonic-bridge-mcp first.",
                    alrc_path.display()
                );
                std::process::exit(1);
            }
            if let Err(e) = sonic_bridge::renderer::run_live_render(&alrc_path) {
                eprintln!(
                    "\x1b[1;31m[-] Error running terminal renderer:\x1b[0m {}",
                    e
                );
                std::process::exit(1);
            }
            return;
        }

        let is_onset_active = config.onset_mode;
        if !config.quiet_mode {
            println!(
                "\x1b[1;36m[*]\x1b[0m Analyzing single track: \x1b[1m{}\x1b[0m (onset mode: \x1b[32m{}\x1b[0m, step size: \x1b[32m{:.1}s\x1b[0m) ...",
                audio_path.display(),
                is_onset_active,
                config.step_size
            );
        }

        match SonicPipeline::process_single(audio_path, &config) {
            Ok((meta, segs)) => {
                let mut report = Vec::new();
                report.push("# SonicBridge: LLM-Readable Music Descriptor (LRMD)\n".to_string());
                report.push("> [!NOTE]".to_string());
                report.push("> This is a physical-to-semantic acoustic report generated by SonicBridge. Pure-text LLMs can 'listen to' and 'appreciate' this track via this spatiotemporal matrix.\n".to_string());

                report.push("## 1. Global Acoustic & Musicological Metadata".to_string());
                report.push(format!("- **Filename**: `{}`", meta.filename));
                report.push(format!(
                    "- **Duration**: `{:.2} seconds`",
                    meta.duration_seconds
                ));
                report.push(format!(
                    "- **Tempo (BPM)**: `{:.1} BPM` ({})",
                    meta.estimated_bpm, meta.tempo_feeling
                ));
                report.push(format!(
                    "- **Estimated Key**: `{}`\n",
                    meta.estimated_global_key
                ));

                let interval_header = if is_onset_active {
                    "## 2. Spatiotemporal Track Analysis (Adaptive Onset Intervals)"
                } else {
                    &format!(
                        "## 2. Spatiotemporal Track Analysis ({:.1}-Second Intervals)",
                        config.step_size
                    )
                };
                report.push(interval_header.to_string());
                report.push("| Timeline | Chord | Dynamic Intensity | Timbral Brightness | Rhythmic & Transient Activity |".to_string());
                report.push("| :--- | :--- | :--- | :--- | :--- |".to_string());

                for seg in &segs {
                    report.push(format!(
                        "| **{}** | `{}` | {} | {} | {} |",
                        seg.time_range,
                        seg.chord,
                        seg.dynamic_level,
                        seg.timbre_brightness,
                        seg.rhythm_activity
                    ));
                }

                let report_text = report.join("\n");

                // 保存到本地
                let out_path = format!("{}.lrmd.md", clean_args[0]);
                if let Ok(mut file) = File::create(&out_path) {
                    let _ = file.write_all(report_text.as_bytes());
                    if !config.quiet_mode {
                        println!(
                            "\x1b[1;32m[+]\x1b[0m LRMD report successfully generated and saved to: \x1b[34m{}\x1b[0m",
                            out_path
                        );
                    }
                }

                if !config.quiet_mode {
                    println!("\n=== GENERATED LRMD REPORT PREVIEW ===");
                    println!("{}", report_text);
                }
            }
            Err(e) => {
                eprintln!("\x1b[1;31m[-] Error processing audio track:\x1b[0m {}", e);
            }
        }
    } else if clean_args.len() == 2 {
        // 双音轨比对模式
        let path_a = Path::new(&clean_args[0]);
        let path_b = Path::new(&clean_args[1]);

        let mut has_err = false;
        if !path_a.exists() {
            eprintln!(
                "\x1b[1;31m[-] Error:\x1b[0m Audio Track A does not exist: \x1b[33m{}\x1b[0m",
                path_a.display()
            );
            has_err = true;
        }
        if !path_b.exists() {
            eprintln!(
                "\x1b[1;31m[-] Error:\x1b[0m Audio Track B does not exist: \x1b[33m{}\x1b[0m",
                path_b.display()
            );
            has_err = true;
        }
        if has_err {
            std::process::exit(1);
        }

        if !config.quiet_mode {
            println!(
                "\x1b[1;36m[*]\x1b[0m Running DTW Comparative Analysis:\n  - Track A: \x1b[1m{}\x1b[0m\n  - Track B: \x1b[1m{}\x1b[0m",
                path_a.display(),
                path_b.display()
            );
        }

        match SonicPipeline::process_comparative(path_a, path_b) {
            Ok(report_text) => {
                let out_path = format!(
                    "{}_vs_{}.lrmd.md",
                    path_a.file_stem().unwrap().to_str().unwrap(),
                    path_b.file_stem().unwrap().to_str().unwrap()
                );
                if let Ok(mut file) = File::create(&out_path) {
                    let _ = file.write_all(report_text.as_bytes());
                    if !config.quiet_mode {
                        println!(
                            "\x1b[1;32m[+]\x1b[0m Comparative LRMD report generated and saved to: \x1b[34m{}\x1b[0m",
                            out_path
                        );
                    }
                }

                if !config.quiet_mode {
                    println!("\n=== COMPARATIVE REPORT PREVIEW ===");
                    println!("{}", report_text);
                }
            }
            Err(e) => {
                eprintln!(
                    "\x1b[1;31m[-] Error running comparative alignment:\x1b[0m {}",
                    e
                );
            }
        }
    } else {
        print_usage();
    }
}

fn print_usage() {
    println!("\x1b[1;36m      ____              _      ____        _     _             \x1b[0m");
    println!("\x1b[1;36m     / ___|  ___  _ __ (_) ___| __ ) _ __ (_) __| | __ _  ___  \x1b[0m");
    println!(
        "\x1b[1;36m     \\___ \\ / _ \\| '_ \\| |/ __|  _ \\| '__|| |/ _` |/ _` |/ _ \\ \x1b[0m"
    );
    println!("\x1b[1;36m      ___) | (_) | | | | | (__| |_) | |   | | (_| | (_| |  __/ \x1b[0m");
    println!(
        "\x1b[1;36m     |____/ \\___/|_| |_|_|\\___|____/|_|   |_|\\__,_|\\__, |\\___| \x1b[0m"
    );
    println!("\x1b[1;36m                                                   |___/       \x1b[0m");
    println!();
    println!(
        "\x1b[1;32mSonicBridge CLI\x1b[0m - LLM-Readable Acoustic Transformer (\x1b[33mv{}\x1b[0m)",
        env!("CARGO_PKG_VERSION")
    );
    println!("\x1b[90m====================================================================\x1b[0m");
    println!("An ultra-fast physical-to-semantic music aesthetic encoder.");
    println!();
    println!("\x1b[1;33mUSAGE:\x1b[0m");
    println!("  \x1b[1mSingle Track Analysis (Generate LRMD Report):\x1b[0m");
    println!("    sonic-bridge \x1b[32m<path_to_audio>\x1b[0m [options]");
    println!();
    println!("  \x1b[1mComparative Track Alignment (DTW Cross-Matching):\x1b[0m");
    println!("    sonic-bridge \x1b[32m<track_A>\x1b[0m \x1b[32m<track_B>\x1b[0m");
    println!();
    println!("\x1b[1;33mOPTIONS:\x1b[0m");
    println!("  \x1b[32m--onset\x1b[0m          Enable event-driven adaptive interval segmenting (Onset detection)");
    println!("                   (Defaults to fixed step time segmenting if omitted)");
    println!("  \x1b[32m--quiet, -q\x1b[0m      Mute outputting markdown report preview in standard stdout");
    println!("  \x1b[32m--config <path>\x1b[0m  Specify target TOML config file path (Override default XDG paths)");
    println!(
        "  \x1b[32m--render\x1b[0m         Start dynamic real-time terminal appreciation scrolling"
    );
    println!("                   (Requires a matching .alrc file under the same directory)");
    println!("  \x1b[32m-h, --help\x1b[0m       Show this premium help manual");
    println!("  \x1b[32m-v, --version\x1b[0m    Show current version info");
    println!();
    println!("\x1b[1;33mENVIRONMENT:\x1b[0m");
    println!("  Configuration paths comply with XDG specs (\x1b[34m$XDG_CONFIG_HOME/sonic-bridge/\x1b[0m).");
    println!();
}

fn print_version() {
    println!("sonic-bridge version {}", env!("CARGO_PKG_VERSION"));
}
