use rusqlite::{params, Connection};
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ApiKey {
    pub id: String,
    pub name: String,
    pub provider: String,
    pub api_key: String,
    pub base_url: Option<String>,
    pub model: Option<String>,
    pub notes: Option<String>,
    pub created_at: Option<String>,
    pub updated_at: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct SaveApiKeyInput {
    pub name: String,
    pub provider: String,
    pub api_key: String,
    pub base_url: Option<String>,
    pub model: Option<String>,
    pub notes: Option<String>,
}

fn row_to_api_key(row: &rusqlite::Row<'_>) -> rusqlite::Result<ApiKey> {
    Ok(ApiKey {
        id:         row.get(0)?,
        name:       row.get(1)?,
        provider:   row.get(2)?,
        api_key:    row.get(3)?,
        base_url:   row.get(4)?,
        model:      row.get(5)?,
        notes:      row.get(6)?,
        created_at: row.get(7)?,
        updated_at: row.get(8)?,
    })
}

const SELECT_COLS: &str = "id, name, provider, api_key, base_url, model, notes, created_at, updated_at";

pub fn list_api_keys(conn: &Connection) -> Vec<ApiKey> {
    let sql = format!("SELECT {SELECT_COLS} FROM api_keys ORDER BY updated_at DESC");
    let mut stmt = match conn.prepare(&sql) {
        Ok(s) => s,
        Err(_) => return vec![],
    };
    stmt.query_map([], row_to_api_key)
        .map(|iter| iter.filter_map(|r| r.ok()).collect())
        .unwrap_or_default()
}

pub fn create_api_key(conn: &Connection, input: &SaveApiKeyInput) -> Result<ApiKey, String> {
    let id = format!("ak-{}", uuid::Uuid::new_v4());
    conn.execute(
        "INSERT INTO api_keys (id, name, provider, api_key, base_url, model, notes)
         VALUES (?1,?2,?3,?4,?5,?6,?7)",
        params![id, input.name, input.provider, input.api_key, input.base_url, input.model, input.notes],
    )
    .map_err(|e| e.to_string())?;
    get_api_key(conn, &id).ok_or_else(|| "创建后查询失败".into())
}

pub fn get_api_key(conn: &Connection, id: &str) -> Option<ApiKey> {
    let sql = format!("SELECT {SELECT_COLS} FROM api_keys WHERE id = ?1");
    conn.query_row(&sql, params![id], row_to_api_key).ok()
}

pub fn update_api_key(conn: &Connection, id: &str, input: &SaveApiKeyInput) -> Result<ApiKey, String> {
    let rows = conn.execute(
        "UPDATE api_keys SET name=?1, provider=?2, api_key=?3, base_url=?4, model=?5, notes=?6, updated_at=datetime('now')
         WHERE id=?7",
        params![input.name, input.provider, input.api_key, input.base_url, input.model, input.notes, id],
    )
    .map_err(|e| e.to_string())?;
    if rows == 0 { return Err(format!("API Key {} 不存在", id)); }
    get_api_key(conn, id).ok_or_else(|| "更新后查询失败".into())
}

pub fn delete_api_key_fn(conn: &Connection, id: &str) -> Result<(), String> {
    conn.execute("DELETE FROM api_keys WHERE id=?1", params![id]).map_err(|e| e.to_string())?;
    Ok(())
}

// ── Tauri commands ───────────────────────────────────────────────────────────

#[tauri::command]
pub fn get_api_keys() -> Result<Vec<ApiKey>, String> {
    let conn = crate::db::pool().get().map_err(|e| e.to_string())?;
    Ok(list_api_keys(&conn))
}

#[tauri::command]
pub fn add_api_key(input: SaveApiKeyInput) -> Result<ApiKey, String> {
    let conn = crate::db::pool().get().map_err(|e| e.to_string())?;
    create_api_key(&conn, &input)
}

#[tauri::command]
pub fn edit_api_key(id: String, input: SaveApiKeyInput) -> Result<ApiKey, String> {
    let conn = crate::db::pool().get().map_err(|e| e.to_string())?;
    update_api_key(&conn, &id, &input)
}

#[tauri::command]
pub fn delete_api_key(id: String) -> Result<(), String> {
    let conn = crate::db::pool().get().map_err(|e| e.to_string())?;
    delete_api_key_fn(&conn, &id)
}
