use anyhow::Result;
use showen_v2::core::config::AppConfig;
use showen_v2::core::plugin_loader::PluginLoader;
use showen_v2::core::service_manager::ServiceManager;
#[cfg(not(test))]
use showen_v2::core::version_manager::VersionManager;
use showen_v2::plugins::{
    ai::AiPlugin, ble::BlePlugin, device::DevicePlugin, http::HttpPlugin, live2d::Live2DPlugin,
    screen::ScreenPlugin, video::VideoPlugin, wifi::WifiPlugin,
};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;

fn main() -> Result<()> {
    // 解析命令行参数
    let args: Vec<String> = std::env::args().collect();

    // 处理 --validate 参数
    if args.contains(&"--validate".to_string()) {
        let config_path = args
            .iter()
            .skip_while(|arg| *arg != "--config")
            .nth(1)
            .cloned()
            .unwrap_or_else(|| "configs/dog_state_machine.json".to_string());

        println!("验证配置文件: {}", config_path);
        let config = AppConfig::from_file(&config_path)?;
        config.validate_paths()?;
        println!("✓ 配置文件有效");
        return Ok(());
    }

    // 获取配置文件路径
    let config_path = args
        .iter()
        .skip_while(|arg| *arg != "--config")
        .nth(1)
        .cloned()
        .or_else(|| args.get(1).cloned())
        .unwrap_or_else(|| "configs/dog_state_machine.json".to_string());

    println!("ShowenV2 — 数字生命窗口平台");
    println!("加载配置: {}", config_path);

    let config = AppConfig::from_file(&config_path)?;
    config.validate_paths()?;

    // 在 config move 进 ServiceManager 之前，提取 AI 相关配置
    let ai_model_store = config.ai.model_store.clone();
    let ai_tools_dir = config.ai.tools_dir.clone();
    let ai_whisper_lib_dir = config.ai.whisper_lib_dir.clone();
    let ai_piper_lib_dir = config.ai.piper_lib_dir.clone();
    let ai_piper_config = config.ai.piper_config.clone();
    let ai_espeak_data_dir = config.ai.espeak_data_dir.clone();
    let ai_tmp_dir = config.ai.tmp_dir.clone();
    let ai_context_window = config.ai.context_window;

    let mut manager = ServiceManager::new(config);

    // 按依赖顺序注册插件
    // 独立插件：device, screen, wifi, video, ble, ai
    // 依赖插件：http (依赖 video)

    println!("注册插件...");
    manager.register(Box::new(DevicePlugin::new_default()));
    println!("  ✓ DevicePlugin");

    manager.register(Box::new(ScreenPlugin::new()));
    println!("  ✓ ScreenPlugin");

    manager.register(Box::new(WifiPlugin::new()));
    println!("  ✓ WifiPlugin");

    manager.register(Box::new(VideoPlugin::new()));
    println!("  ✓ VideoPlugin");

    manager.register(Box::new(Live2DPlugin::new()));
    println!("  ✓ Live2DPlugin");

    manager.register(Box::new(BlePlugin::new()));
    println!("  ✓ BlePlugin");

    // AiPlugin: 需要在注册前创建实例以获取 pipeline 句柄，再注册进 manager
    // pipeline 会传给 HttpPlugin，建立 HTTP → AI 的直接通道
    let ai_plugin = AiPlugin::new_default(
        ai_model_store,
        ai_tools_dir,
        ai_whisper_lib_dir,
        ai_piper_lib_dir,
        ai_piper_config,
        ai_espeak_data_dir,
        ai_tmp_dir,
        ai_context_window,
    );
    let ai_pipeline = ai_plugin.pipeline();
    let ai_models = ai_plugin.models();
    manager.register(Box::new(ai_plugin));
    println!("  ✓ AiPlugin");

    let mut http_plugin = HttpPlugin::new();
    // 注册 AI 句柄到 HttpState（在 http init 之前建立连接）
    http_plugin.set_ai_pipeline(ai_pipeline);
    http_plugin.set_ai_models(ai_models);
    manager.register(Box::new(http_plugin));
    println!("  ✓ HttpPlugin");

    // 加载动态插件
    let plugin_store = std::path::Path::new("plugin_store");
    if plugin_store.exists() {
        println!("扫描动态插件...");
        #[cfg(not(test))]
        manager.set_version_manager(VersionManager::new(PluginLoader::new(plugin_store)));
        let loader = PluginLoader::new(plugin_store);
        match loader.load_registry() {
            Ok(registry) => {
                for (plugin_id, entry) in &registry.plugins {
                    if !entry.enabled {
                        println!("  - {plugin_id} (禁用)");
                        continue;
                    }

                    match loader.load_plugin(plugin_id, Some(&entry.active_version)) {
                        Ok((plugin, manifest)) => {
                            manager.register_dynamic_with_manifest(
                                Box::new(plugin),
                                manifest.error_policy,
                                entry.max_errors,
                                manifest.required_capabilities,
                                manifest.capabilities,
                                manifest.auto_test,
                            );
                            println!("  ✓ {} v{} (动态)", plugin_id, entry.active_version);
                        }
                        Err(e) => {
                            eprintln!("  ✗ {} v{} 加载失败: {e}", plugin_id, entry.active_version);
                        }
                    }
                }
            }
            Err(e) => {
                eprintln!("读取插件注册表失败: {e}");
            }
        }
    }

    // 设置 Ctrl+C 信号处理
    let running = Arc::new(AtomicBool::new(true));
    let r = running.clone();
    let shutdown_tx = manager.sender();

    ctrlc::set_handler(move || {
        println!("\n收到退出信号，正在关闭...");
        r.store(false, Ordering::SeqCst);
        // 注入 Shutdown 消息，唤醒主消息循环并触发优雅停机
        let _ = shutdown_tx.send(showen_v2::core::message::Envelope {
            from: "signal".to_string(),
            to: showen_v2::core::message::Destination::Manager,
            message: showen_v2::core::message::Message::Shutdown,
        });
    })?;

    println!("启动所有插件...");
    manager.start_all()?;

    println!("ShowenV2 运行中... (按 Ctrl+C 退出)");

    // 运行主循环
    while running.load(Ordering::SeqCst) {
        manager.run()?;
    }

    println!("正在停止所有插件...");
    manager.stop_all()?;
    println!("ShowenV2 已退出");

    Ok(())
}
