//! Pinning commands - protect an item's cached metadata from cache clearing.
//!
//! TRACES: UR-044 | DR-056

use std::sync::Arc;
use tauri::State;

use crate::commands::DatabaseWrapper;
use crate::storage::db_service::{DatabaseService, Query, QueryParam};

/// Pin an item's metadata (protects from cache clear)
#[tauri::command]
#[specta::specta]
pub async fn pin_item(db: State<'_, DatabaseWrapper>, item_id: String) -> Result<(), String> {
    let db_service = {
        let database = db.0.lock().map_err(|e| e.to_string())?;
        Arc::new(database.service())
    };

    let query = Query::with_params(
        "UPDATE items SET is_pinned = 1 WHERE id = ?",
        vec![QueryParam::String(item_id)],
    );

    db_service.execute(query).await.map_err(|e| e.to_string())?;
    Ok(())
}

/// Unpin an item's metadata
#[tauri::command]
#[specta::specta]
pub async fn unpin_item(db: State<'_, DatabaseWrapper>, item_id: String) -> Result<(), String> {
    let db_service = {
        let database = db.0.lock().map_err(|e| e.to_string())?;
        Arc::new(database.service())
    };

    let query = Query::with_params(
        "UPDATE items SET is_pinned = 0 WHERE id = ?",
        vec![QueryParam::String(item_id)],
    );

    db_service.execute(query).await.map_err(|e| e.to_string())?;
    Ok(())
}

/// Check if an item is pinned
#[tauri::command]
#[specta::specta]
pub async fn is_item_pinned(
    db: State<'_, DatabaseWrapper>,
    item_id: String,
) -> Result<bool, String> {
    let db_service = {
        let database = db.0.lock().map_err(|e| e.to_string())?;
        Arc::new(database.service())
    };

    let query = Query::with_params(
        "SELECT COALESCE(is_pinned, 0) FROM items WHERE id = ?",
        vec![QueryParam::String(item_id)],
    );

    let is_pinned: i32 = db_service
        .query_optional(query, |row| row.get(0))
        .await
        .map_err(|e| e.to_string())?
        .unwrap_or(0);

    Ok(is_pinned == 1)
}
