use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;
use tauri::{AppHandle, Manager};

const DATA_FILE: &str = "data.json";

/// 应用全量持久化数据（JSON 根对象）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppState {
    #[serde(default)]
    pub tasks: serde_json::Value,
    #[serde(default)]
    pub shortcuts: serde_json::Value,
    #[serde(default)]
    pub pomodoro: serde_json::Value,
    #[serde(default)]
    pub settings: serde_json::Value,
}

impl Default for AppState {
    fn default() -> Self {
        AppState {
            tasks: serde_json::json!([]),
            shortcuts: serde_json::json!([
                {
                    "id": "demo-1",
                    "label": "GitHub",
                    "icon": "github",
                    "type": "url",
                    "target": "https://github.com",
                    "args": []
                },
                {
                    "id": "demo-2",
                    "label": "记事本",
                    "icon": "file-text",
                    "type": "app",
                    "target": "notepad.exe",
                    "args": []
                }
            ]),
            pomodoro: serde_json::json!({
                "workMin": 25,
                "breakMin": 5,
                "soundOn": true
            }),
            settings: serde_json::json!({
                "alwaysOnTop": true,
                "opacity": 0.85,
                "globalHotkeys": {
                    "newTask": "Ctrl+Alt+T",
                    "togglePomodoro": "Ctrl+Alt+P",
                    "showHide": "Ctrl+Alt+`"
                },
                "autoStart": false
            }),
        }
    }
}

/// 获取数据文件完整路径，若目录不存在则创建
pub fn data_path(app: &AppHandle) -> Result<PathBuf> {
    let dir = app
        .path()
        .app_data_dir()
        .context("failed to resolve app data dir")?;
    fs::create_dir_all(&dir).with_context(|| format!("create dir {}", dir.display()))?;
    Ok(dir.join(DATA_FILE))
}

/// 启动时调用：若 data.json 不存在则写入默认值
pub fn ensure_data_file(app: &AppHandle) -> Result<()> {
    let path = data_path(app)?;
    if !path.exists() {
        let default = AppState::default();
        let json = serde_json::to_string_pretty(&default)?;
        fs::write(&path, json).with_context(|| format!("write default {}", path.display()))?;
    }
    Ok(())
}

/// 读取 JSON 字符串（前端直接解析）。若文件损坏则返回默认值。
pub fn read_state(app: &AppHandle) -> Result<String> {
    let path = data_path(app)?;
    if !path.exists() {
        ensure_data_file(app)?;
    }
    let content = fs::read_to_string(&path)
        .with_context(|| format!("read {}", path.display()))?;
    // 校验一下结构，失败则用默认覆盖
    if serde_json::from_str::<AppState>(&content).is_err() {
        let default = AppState::default();
        let json = serde_json::to_string_pretty(&default)?;
        fs::write(&path, &json)?;
        return Ok(json);
    }
    Ok(content)
}

/// 写入 JSON 字符串（前端整体保存）
pub fn write_state(app: &AppHandle, json: &str) -> Result<()> {
    let path = data_path(app)?;
    // 简单校验，避免写入非法 JSON
    let _: serde_json::Value =
        serde_json::from_str(json).context("invalid JSON when saving state")?;
    fs::write(&path, json).with_context(|| format!("write {}", path.display()))?;
    Ok(())
}
