//! 应用配置存储
//!
//! 存储路径: {app_local_data_dir}/config.json
//!
//! 运行模式（生产/调试）控制桌面端行为，API 地址固定为 dev 环境。

use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::storage::engine::{read_json, atomic_write_json, StorageError};

const API_BASE_URL: &str = "https://dev.tapi.meijiaka.cn/api/v1";

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct AppConfig {
    pub api_base_url: String,
    pub environment: String,
}

/// 运行模式预设（唯一数据源，前端通过 IPC 获取）
#[derive(Serialize, Clone, Debug)]
pub struct EnvironmentPreset {
    pub label: String,
    pub url: String,
    pub env: String,
}

fn presets() -> Vec<EnvironmentPreset> {
    vec![
        EnvironmentPreset {
            label: "生产模式".to_string(),
            url: API_BASE_URL.to_string(),
            env: "production".to_string(),
        },
        EnvironmentPreset {
            label: "调试模式".to_string(),
            url: API_BASE_URL.to_string(),
            env: "debug".to_string(),
        },
    ]
}

impl Default for AppConfig {
    fn default() -> Self {
        // 默认生产模式
        let preset = &presets()[0];
        Self {
            api_base_url: preset.url.clone(),
            environment: preset.env.clone(),
        }
    }
}

fn get_config_path() -> Result<PathBuf, StorageError> {
    crate::storage::paths::get_app_config_json_path()
}

/// 同步读取 API Base URL（供 Rust 命令内部使用）
pub fn get_api_base_url_sync() -> String {
    API_BASE_URL.to_string()
}

#[tauri::command]
pub async fn load_app_config() -> Result<AppConfig, String> {
    let path = get_config_path().map_err(|e| e.to_string())?;
    match read_json::<AppConfig>(&path) {
        Ok(Some(config)) => {
            // 兼容旧环境值：旧值（staging/development/custom）统一映射为 debug
            let environment = match config.environment.as_str() {
                "production" => "production".to_string(),
                _ => "debug".to_string(),
            };
            Ok(AppConfig {
                api_base_url: API_BASE_URL.to_string(),
                environment,
            })
        }
        Ok(None) => Ok(AppConfig::default()),
        Err(e) => Err(e.to_string()),
    }
}

#[tauri::command]
pub async fn get_environment_presets() -> Result<Vec<EnvironmentPreset>, String> {
    Ok(presets())
}

#[tauri::command]
pub async fn save_app_config(environment: String, _custom_url: Option<String>) -> Result<(), String> {
    let config = AppConfig {
        api_base_url: API_BASE_URL.to_string(),
        environment,
    };

    let path = get_config_path().map_err(|e| e.to_string())?;
    if let Some(parent) = path.parent() {
        std::fs::create_dir_all(parent).map_err(|e| e.to_string())?;
    }
    atomic_write_json(&path, &config).map_err(|e| e.to_string())
}
