use crate::cli::{err, ok, DEFAULT_PORT};
use crate::server::{self, convert, ServerConfig, ServerState};
use anyhow::{anyhow, Result};
use clap::Parser;

#[derive(Parser)]
pub struct Args {
    /// `<Library>/<Name>` path on service-kicad. Example: `Package_QFP/LQFP-64_10x10mm_P0.5mm`.
    pub lib_slash_name: String,

    #[arg(long, default_value_t = DEFAULT_PORT)]
    pub port: u16,

    #[arg(long)]
    pub no_open: bool,

    #[arg(long, default_value = "STEP Viewer")]
    pub tab_name: String,

    #[arg(long, default_value = "mdi:cube-outline")]
    pub display_icon: String,
}

pub fn run(args: Args) -> Result<()> {
    ok(format!(
        "fetching {} via service-step2glb...",
        args.lib_slash_name
    ));
    let result = match convert::convert_from_library(&args.lib_slash_name) {
        Ok(r) => r,
        Err(e) => {
            err(format!("conversion failed: {e}"));
            return Err(e);
        }
    };

    let label = if result.cache_hit {
        "cache HIT"
    } else {
        "cache MISS"
    };
    ok(format!(
        "{label} — GLB at {} ({} KB, {} meshes, {} nodes, {} ms)",
        result.glb_path.display(),
        result.size_bytes / 1024,
        result.meshes,
        result.nodes,
        result.duration_ms
    ));

    let config = ServerConfig {
        port: args.port,
        initial_glb_path: Some(result.glb_path.clone()),
        initial_source_label: Some(args.lib_slash_name.clone()),
        initial_source_type: Some("kicad-library".to_string()),
    };
    let state = ServerState::new(config);

    let shutdown_state = state.clone();
    ctrlc::set_handler(move || {
        eprintln!("\nreceived SIGINT, shutting down adom-step");
        let _ = &shutdown_state;
        std::process::exit(0);
    })?;

    if !args.no_open {
        let port = args.port;
        let tab_name = args.tab_name.clone();
        let icon = args.display_icon.clone();
        std::thread::spawn(move || {
            std::thread::sleep(std::time::Duration::from_millis(400));
            if let Err(e) =
                crate::cli::open::open_webview_tab(port, &tab_name, &icon)
            {
                eprintln!("warn: failed to open webview tab: {e}");
            }
        });
    }

    if !args.lib_slash_name.contains('/') {
        return Err(anyhow!(
            "expected <Library>/<Name>, got: {}",
            args.lib_slash_name
        ));
    }

    ok(format!("adom-step running on port {}", args.port));
    server::run(state)?;
    Ok(())
}