// 下面引入了应用的各个功能模块
// app - 应用的初始化和启动相关逻辑
// audio - 音频播放和声音处理
// constants - 常量定义
// env - 环境变量和配置读取
// error - 错误类型和错误处理
// invoke - Tauri 命令处理器,处理前端调用
// menu - 应用菜单配置和事件处理
// models - 公共数据结构定义
// storage - 数据持久化存储
// task - 定时任务和计划任务
// tray - 系统托盘图标和菜单
// utils - 通用工具函数
// window - 窗口创建和管理
mod app;
mod audio;
mod constants;
mod env;
mod error;
mod invoke;
mod menu;
mod storage;
mod task;
mod tray;
mod utils;
pub mod window;

// 引入各个模块的类型和功能
use crate::constants::common::*;
use crate::window::{WindowLabel, util::show_windows_by_label};
use app::initializer::initialize_app;
use invoke::handlers::register_commands;
use menu::menu_handler::handle_menu_event;
use storage::session_storage::SessionStorage;
use task::scheduled_restart::start_scheduled_restart_task;
use tauri::Manager;
use tauri::RunEvent;
use tray::setup_tray;
/// 移动平台入口点
/// 在移动设备上运行时需要这个属性标记
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    let builder = tauri::Builder::default()
        .plugin(tauri_plugin_websocket::init())
        // 下面加载各种 Tauri 插件
        // os 插件 - 获取操作系统信息
        .plugin(tauri_plugin_os::init())
        // dialog 插件 - 显示文件选择对话框等
        .plugin(tauri_plugin_dialog::init())
        // fs 插件 - 文件系统访问
        .plugin(tauri_plugin_fs::init())
        // persisted_scope 插件 - 记住文件访问权限
        .plugin(tauri_plugin_persisted_scope::init())
        // process 插件 - 进程相关信息
        .plugin(tauri_plugin_process::init())
        // updater 插件 - 应用自动更新
        .plugin(tauri_plugin_updater::Builder::new().build())
        // http 插件 - HTTP 客户端请求
        .plugin(tauri_plugin_http::init())
        // single_instance 插件 - 保证只启动一个应用实例
        .plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
            let app_handle = app.clone();
            tauri::async_runtime::spawn(async move {
                let main_label = WindowLabel::MAIN.as_ref();
                if app_handle.get_webview_window(main_label).is_some() {
                    show_windows_by_label(&app_handle, WindowLabel::MAIN);
                } else {
                    log::warn!("{}", MSG_MAIN_WINDOW_NOT_EXIST);
                }
            });
        }))
        // 注册全局状态管理
        .manage(SessionStorage::new())
        // 下面是应用初始化和事件处理的设置
        // setup 函数会在应用构建完成后执行一次
        .setup(|app| {
            // 初始化应用,包括创建窗口、设置初始状态等
            initialize_app(app.handle())?;

            // 创建系统托盘图标
            setup_tray(app.handle())?;

            // 启动每日定时重启任务
            let app_handle = app.handle().clone();
            tauri::async_runtime::spawn(async move {
                if let Err(e) = start_scheduled_restart_task(app_handle).await {
                    log::error!("{} {}", MSG_FAILED_START_RESTART_TASK, e);
                } else {
                    log::info!("{}", MSG_RESTART_TASK_STARTED);
                }
            });

            Ok(())
        })
        // 处理菜单点击事件
        // 当用户点击菜单项时会触发这个回调
        .on_menu_event(|app, event| {
            handle_menu_event(app, event.id.as_ref());
        });

    // 注册 Tauri 命令处理器
    // 这些命令会被前端通过 invoke 调用
    let builder = register_commands(builder);

    let app = builder
        // 构建应用上下文
        .build(tauri::generate_context!())
        // 如果构建失败,输出错误信息并退出
        .unwrap_or_else(|e| {
            log::error!("{}: {:?}", MSG_FAILED_BUILD_TAURI, e);
            std::process::exit(1);
        });

    // 启动应用并处理系统事件
    app.run(|_app_handle: &tauri::AppHandle, event| {
        match event {
            // 应用退出时触发（无法阻止，确保一定执行）
            RunEvent::Exit => {
                log::info!("应用正在退出，执行资源清理...");
            }
            // 处理 macOS 上的 Reopen 事件
            // 当用户点击 Dock 图标时触发
            #[cfg(target_os = "macos")]
            RunEvent::Reopen { .. } => {
                // 获取主窗口
                if let Some(main_window) = _app_handle.get_webview_window(WindowLabel::MAIN.as_ref()) {
                    // 如果窗口被最小化了,就恢复它
                    if main_window.is_minimized().unwrap_or(false) && main_window.unminimize().is_err() {
                        log::warn!("恢复主窗口失败");
                    }

                    // 显示窗口并放到前台
                    if let Err(e) = main_window.show() {
                        log::warn!("显示主窗口失败: {:?}", e);
                    }
                    if let Err(e) = main_window.set_focus() {
                        log::warn!("设置主窗口焦点失败: {:?}", e);
                    }
                }
            }
            _ => {}
        }
    });
}
