use once_cell::sync::OnceCell;
use tauri::AppHandle;
use tokio_cron_scheduler::{Job, JobScheduler};
use tracing::info;

/// 全局调度器实例
/// 使用 OnceCell 确保只创建一次,并在应用生命周期内保持活动
static SCHEDULER: OnceCell<JobScheduler> = OnceCell::new();

/// 启动每日凌晨1点定时重启任务
///
/// 注意：此函数会启动一个后台任务，调度器会在后台持续运行
/// 调度器的生命周期与应用程序相同
pub async fn start_scheduled_restart_task(app_handle: AppHandle) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    // 如果调度器已经存在,直接返回
    if SCHEDULER.get().is_some() {
        info!("定时重启任务已经启动,跳过重复初始化");
        return Ok(());
    }

    // 创建调度器
    let scheduler = JobScheduler::new().await?;

    // 创建每天凌晨1点执行的定时任务
    // cron表达式: "0 0 1 * * *" 表示每天1点0分0秒执行
    // 格式: sec min hour day_of_month month day_of_week
    let job = Job::new_async("0 0 1 * * *", move |_uuid, _l| {
        let app_handle_clone = app_handle.clone();
        Box::pin(async move {
            info!("定时重启任务已触发，正在重启应用程序...");

            // 重启应用
            app_handle_clone.restart();

            // 注意：由于重启操作会终止程序，下面的代码不会执行
        })
    })?;

    // 添加任务到调度器
    scheduler.add(job).await?;

    // 启动调度器
    scheduler.start().await?;

    // 将调度器保存到全局静态变量中,确保其不会被清理
    SCHEDULER.set(scheduler).map_err(|_| "定时任务调度器已初始化")?;

    info!("定时重启任务已启动 - 应用程序将在每天凌晨1点重启");

    Ok(())
}
