mod commands;
mod db;
mod mcp_inject;
mod mcp_server;
mod models;
use git2;

/// 创建不弹 CMD 窗口的子进程（Windows 专用 CREATE_NO_WINDOW 标志）。
/// 所有后台静默命令都应通过此函数创建，避免在 Windows 上频繁闪出黑框。
pub(crate) fn silent_cmd(program: &str) -> std::process::Command {
    let mut cmd = std::process::Command::new(program);
    #[cfg(target_os = "windows")]
    {
        use std::os::windows::process::CommandExt;
        const CREATE_NO_WINDOW: u32 = 0x0800_0000;
        cmd.creation_flags(CREATE_NO_WINDOW);
    }
    cmd
}

use commands::{activity::*, blueprint::*, buff::{apply_blueprint_buff, remove_blueprint_buff, get_buff_status, list_buffed_projects}, canvas::*, cicd::*, claude_config::get_beast_global_status, devtools::*, git_ops::*, git_repos::*, groups::*, mentor::{add_project_note, get_group_mentor_report, get_mentor_context, get_project_notes, get_startup_alerts, run_startup_health_scan}, network::{get_wsl_ip, sync_wsl_proxy, get_wsl_proxy_status, clear_wsl_proxy, test_wsl_proxy_ip, test_win_proxy_ip}, project_scan::*, project_tools::*, projects::{batch_create_projects, create_project, delete_project, get_project, get_projects, scan_subfolders, update_project, update_project_tags}, proxy::*, publish::*, settings::{check_mcp_health, detect_editors, get_settings, run_health_check, search_editor_path, update_settings}, shell::*, spaces::*, tags::*, templates::*};

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_single_instance::init(|app, _argv, _cwd| {
            // 第二个实例启动时，激活已有窗口
            use tauri::Manager;
            if let Some(w) = app.get_webview_window("main") {
                let _ = w.show();
                let _ = w.unminimize();
                let _ = w.set_focus();
            }
        }))
        .plugin(tauri_plugin_http::init())
        .plugin(tauri_plugin_opener::init())
        .plugin(tauri_plugin_updater::Builder::new().build())
        .plugin(tauri_plugin_process::init())
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_shell::init())
        .setup(|app| {
            use tauri::{
                menu::{Menu, MenuItem},
                tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
                Manager,
            };

            let data_dir = app.path().app_data_dir().expect("no app data dir");
            db::init(data_dir.clone());
            commands::blueprint::init_user_conventions_dir(data_dir);
            // 禁用 libgit2 目录所有者验证，允许访问 WSL UNC 路径（\\wsl.localhost\...）
            unsafe {
                let _ = git2::opts::set_verify_owner_validation(false);
            }
            // 种植内置模板（首次启动时执行）
            commands::templates::seed_builtin_templates();

            // ── 启动 MCP Server ───────────────────────────────────────
            let mcp_port = mcp_server::read_port();
            tauri::async_runtime::spawn(mcp_server::start(mcp_port));

            // ── Gitea 远端轮询（G6）：每 10 分钟拉取绑定仓库 commit ───
            // 出站 HTTPS 采集，适配公网 Gitea + 内网炼境拓扑（webhook 不可达时的降级）
            std::thread::spawn(|| {
                std::thread::sleep(std::time::Duration::from_secs(30)); // 等 DB 与网络就绪
                loop {
                    let _ = commands::gitea::poll_all_repos();
                    std::thread::sleep(std::time::Duration::from_secs(600));
                }
            });

            // ── 启动健康扫描（异步，不阻塞窗口渲染）────────────────
            tauri::async_runtime::spawn(async {
                tokio::task::spawn_blocking(run_startup_health_scan).await.ok();
            });

            // ── 启动蓝图 Buff 后台轮询 ────────────────────────────
            commands::buff::start_blueprint_watchers(app.handle().clone());

            // ── 系统托盘 ──────────────────────────────────────────────
            let show_i = MenuItem::with_id(app, "show", "显示窗口", true, None::<&str>)?;
            let quit_i = MenuItem::with_id(app, "quit", "退出炼境", true, None::<&str>)?;
            let menu = Menu::with_items(app, &[&show_i, &quit_i])?;

            TrayIconBuilder::new()
                .icon(app.default_window_icon().unwrap().clone())
                .menu(&menu)
                .show_menu_on_left_click(false)
                .tooltip("炼境")
                .on_menu_event(|app, event| match event.id.as_ref() {
                    "quit" => app.exit(0),
                    "show" => {
                        if let Some(w) = app.get_webview_window("main") {
                            let _ = w.show();
                            let _ = w.set_focus();
                        }
                    }
                    _ => {}
                })
                .on_tray_icon_event(|tray, event| {
                    // 左键单击托盘图标 → 显示/聚焦窗口
                    if let TrayIconEvent::Click {
                        button: MouseButton::Left,
                        button_state: MouseButtonState::Up,
                        ..
                    } = event
                    {
                        let app = tray.app_handle();
                        if let Some(w) = app.get_webview_window("main") {
                            let _ = w.show();
                            let _ = w.set_focus();
                        }
                    }
                })
                .build(app)?;

            // ── 关闭窗口 → 最小化到托盘 ──────────────────────────────
            if let Some(window) = app.get_webview_window("main") {
                let win = window.clone();
                window.on_window_event(move |event| {
                    if let tauri::WindowEvent::CloseRequested { api, .. } = event {
                        api.prevent_close();
                        let _ = win.hide();
                    }
                });
            }

            Ok(())
        })
        .invoke_handler(tauri::generate_handler![
            // projects
            get_projects,
            get_project,
            create_project,
            update_project,
            update_project_tags,
            delete_project,
            scan_subfolders,
            batch_create_projects,
            // activity
            get_activity,
            add_activity,
            // groups
            get_groups,
            create_group,
            update_group,
            delete_group,
            reorder_groups,
            get_group_maps,
            add_group_member,
            remove_group_member,
            // settings
            get_settings,
            update_settings,
            detect_editors,
            search_editor_path,
            check_mcp_health,
            run_health_check,
            // project tools
            get_project_tools,
            add_project_tool,
            update_project_tool,
            remove_project_tool,
            launch_tool,
            // global quick launch
            get_global_tools,
            add_global_tool,
            update_global_tool,
            remove_global_tool,
            // devtools
            scan_dev_tools,
            scan_wsl_dev_tools,
            get_dev_tools,
            save_dev_tools,
            delete_dev_tool,
            upsert_dev_tool,
            // wsl proxy
            get_wsl_ip,
            sync_wsl_proxy,
            get_wsl_proxy_status,
            clear_wsl_proxy,
            test_wsl_proxy_ip,
            test_win_proxy_ip,
            // v2rayn import
            scan_v2rayn_nodes,
            detect_v2rayn_db_path,
            get_active_v2rayn_node,
            // project env scan
            scan_project_env,
            get_project_env_tools,
            save_project_env_tools,
            // shell
            open_editor,
            open_terminal,
            // git ops
            git_clone,
            git_status,
            git_fetch,
            git_pull,
            git_push,
            git_head_commit,
            git_upstream_behind,
            git_create_branch,
            git_list_branches,
            git_checkout_branch,
            // spaces
            get_spaces,
            create_space,
            update_space,
            delete_space,
            set_current_space,
            get_deploy_commands,
            add_deploy_command,
            remove_deploy_command,
            execute_deploy,
            // git repos registry
            get_git_repos,
            import_git_repos,
            update_git_repo_deploy,
            mount_repo,
            delete_git_repo,
            // 本地 git 工具
            scan_local_git,
            git_init_and_commit,
            git_remote_set,
            register_and_link_repo,
            write_gitignore,
            resolve_wsl_path,
            get_wsl_distros,
            // project templates
            list_templates,
            get_template,
            save_template,
            delete_template,
            create_project_from_template,
            // tags
            get_tags,
            create_tag,
            update_tag,
            delete_tag,
            get_project_tags,
            set_project_tags,
            get_all_project_tag_maps,
            // cicd
            get_cicd_config,
            save_cicd_config,
            generate_workflow,
            // blueprint
            get_blueprint,
            generate_blueprint_prompt,
            get_blueprint_status,
            sync_blueprint_rules,
            get_flywheel_stats,
            generate_muhe_prompt,
            archive_project_docs,
            get_user_conventions_status,
            save_user_conventions,
            reset_conventions_to_builtin,
            // canvas state
            get_canvas_state,
            save_canvas_state,
            // blueprint buff
            apply_blueprint_buff,
            remove_blueprint_buff,
            get_buff_status,
            list_buffed_projects,
            // onboarding pack
            commands::onboarding::apply_onboarding_pack,
            // agent infrastructure
            commands::agent_infra::scan_agent_infra_stack,
            commands::agent_infra::generate_agent_infra_files,
            commands::agent_infra::scan_doc_freshness,
            commands::agent_infra::get_doc_freshness_cache,
            commands::agent_infra::get_agent_health,
            commands::commit_metrics::get_commit_stats,
            commands::commit_metrics::ingest_full_git_history,
            commands::commit_metrics::get_project_commit_health,
            commands::commit_metrics::get_all_commit_health,
            // mentor
            get_mentor_context,
            get_project_notes,
            add_project_note,
            get_group_mentor_report,
            get_startup_alerts,
            // user todos
            commands::user_todos::get_user_todos,
            commands::user_todos::add_user_todo,
            commands::user_todos::toggle_user_todo,
            commands::user_todos::delete_user_todo,
            // servers
            commands::servers::get_servers,
            commands::servers::add_server,
            commands::servers::edit_server,
            commands::servers::delete_server,
            commands::servers::link_server,
            commands::servers::unlink_server,
            commands::servers::get_project_server_links,
            commands::servers::get_server_project_links,
            // ssh config & vscode remote
            commands::ssh_config::sync_ssh_config,
            commands::ssh_config::get_ssh_config_status,
            commands::ssh_config::check_vscode_status,
            commands::ssh_config::open_vscode_remote,
            commands::ssh_config::open_server_terminal,
            commands::ssh_config::parse_ssh_config_entries,
            commands::ssh_config::import_ssh_config_entries,
            // server software & mirrors
            commands::server_software::get_github_mirrors,
            commands::server_software::add_github_mirror,
            commands::server_software::delete_github_mirror,
            commands::server_software::test_mirror_local,
            commands::server_software::get_server_network_config,
            commands::server_software::set_server_mirror,
            commands::server_software::get_server_software_list,
            commands::server_software::add_server_software,
            commands::server_software::update_server_software,
            commands::server_software::delete_server_software,
            commands::server_software::generate_install_command,
            commands::server_software::get_software_categories,
            commands::server_software::add_software_category,
            commands::server_software::update_software_category,
            commands::server_software::delete_software_category,
            // api keys
            commands::api_keys::get_api_keys,
            commands::api_keys::add_api_key,
            commands::api_keys::edit_api_key,
            commands::api_keys::delete_api_key,
            // host apps
            commands::host_apps::get_host_apps,
            commands::host_apps::add_host_app,
            commands::host_apps::edit_host_app,
            commands::host_apps::delete_host_app,
            // server service configs
            commands::service_config::get_service_configs,
            commands::service_config::add_service_config,
            commands::service_config::edit_service_config,
            commands::service_config::delete_service_config,
            // gitea integration
            commands::gitea::gitea_save_instance,
            commands::gitea::gitea_list_instances,
            commands::gitea::gitea_delete_instance,
            commands::gitea::gitea_update_instance,
            commands::gitea::gitea_test_connection,
            commands::gitea::gitea_list_linked_repos,
            commands::gitea::gitea_get_repo_link,
            commands::gitea::gitea_create_repo,
            commands::gitea::gitea_migrate_repo,
            commands::gitea::gitea_link_repo,
            commands::gitea::gitea_setup_webhook,
            commands::gitea::gitea_unlink_repo,
            commands::gitea::gitea_poll_now,
            // beast status (read-only)
            get_beast_global_status,
            // source library
            commands::source_library::get_source_categories,
            commands::source_library::create_source_category,
            commands::source_library::update_source_category,
            commands::source_library::delete_source_category,
            commands::source_library::get_source_projects,
            commands::source_library::create_source_project,
            commands::source_library::update_source_project,
            commands::source_library::delete_source_project,
            commands::source_library::get_source_versions,
            commands::source_library::add_source_version,
            commands::source_library::set_primary_version,
            commands::source_library::delete_source_version,
            commands::source_library::update_version_notes,
            commands::source_library::scan_source_dir_tree,
            commands::source_library::reveal_source_in_explorer,
            commands::source_library::copy_source_to,
            // cloud products
            commands::cloud_products::get_cloud_products,
            commands::cloud_products::add_cloud_product,
            commands::cloud_products::edit_cloud_product,
            commands::cloud_products::delete_cloud_product,
            // cloud db databases
            commands::cloud_db_databases::get_cloud_databases,
            commands::cloud_db_databases::add_cloud_database,
            commands::cloud_db_databases::edit_cloud_database,
            commands::cloud_db_databases::delete_cloud_database,
            // docker apps
            commands::docker_apps::get_docker_apps,
            commands::docker_apps::add_docker_app,
            commands::docker_apps::edit_docker_app,
            commands::docker_apps::delete_docker_app,
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
