// filepath: src-tauri/src/storage.rs
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;
use tauri::{AppHandle, Manager};
use anyhow::Result;
use chrono::{DateTime, Utc};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Settings {
    pub download_path: String,
    pub cookies_path: Option<String>,
    pub theme: String, // 'light', 'dark', 'system'
    pub last_updated: Option<DateTime<Utc>>,
}

impl Default for Settings {
    fn default() -> Self {
        // We'll resolve the actual download path at runtime if empty, 
        // but for default struct we can keep it empty or a placeholder.
        Self {
            download_path: "".to_string(),
            cookies_path: None,
            theme: "system".to_string(),
            last_updated: None,
        }
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct HistoryItem {
    pub id: String,
    pub title: String,
    pub thumbnail: String,
    pub url: String,
    pub output_path: String,
    pub timestamp: DateTime<Utc>,
    pub status: String, // "success", "failed"
    pub format: String,
}

pub fn get_app_data_dir(app: &AppHandle) -> Result<PathBuf> {
    // In Tauri v2, we use app.path().app_data_dir()
    let path = app.path().app_data_dir()?;
    if !path.exists() {
        fs::create_dir_all(&path)?;
    }
    Ok(path)
}

pub fn get_settings_path(app: &AppHandle) -> Result<PathBuf> {
    Ok(get_app_data_dir(app)?.join("settings.json"))
}

pub fn get_history_path(app: &AppHandle) -> Result<PathBuf> {
    Ok(get_app_data_dir(app)?.join("history.json"))
}

pub fn load_settings(app: &AppHandle) -> Result<Settings> {
    let path = get_settings_path(app)?;
    if path.exists() {
        let content = fs::read_to_string(&path)?;
        let settings: Settings = serde_json::from_str(&content)?;
        return Ok(settings);
    }
    
    // If not exists, return default. 
    // Note: We might want to set a default download path here if possible.
    let mut settings = Settings::default();
    if let Ok(download_dir) = app.path().download_dir() {
        settings.download_path = download_dir.to_string_lossy().to_string();
    }
    Ok(settings)
}

pub fn save_settings(app: &AppHandle, settings: &Settings) -> Result<()> {
    let path = get_settings_path(app)?;
    let content = serde_json::to_string_pretty(settings)?;
    fs::write(path, content)?;
    Ok(())
}

pub fn load_history(app: &AppHandle) -> Result<Vec<HistoryItem>> {
    let path = get_history_path(app)?;
    if path.exists() {
        let content = fs::read_to_string(&path)?;
        let history: Vec<HistoryItem> = serde_json::from_str(&content)?;
        Ok(history)
    } else {
        Ok(Vec::new())
    }
}

pub fn save_history(app: &AppHandle, history: &[HistoryItem]) -> Result<()> {
    let path = get_history_path(app)?;
    let content = serde_json::to_string_pretty(history)?;
    fs::write(path, content)?;
    Ok(())
}

pub fn add_history_item(app: &AppHandle, item: HistoryItem) -> Result<()> {
    let mut history = load_history(app)?;
    // Prepend
    history.insert(0, item);
    save_history(app, &history)?;
    Ok(())
}

pub fn clear_history(app: &AppHandle) -> Result<()> {
    save_history(app, &[])
}

pub fn delete_history_item(app: &AppHandle, id: &str) -> Result<()> {
    let mut history = load_history(app)?;
    history.retain(|item| item.id != id);
    save_history(app, &history)?;
    Ok(())
}
