//! Tauri commands for playlist management
//! Uses handle-based system: UUID -> Arc<HybridRepository>
//!
//! TRACES: UR-014 | JA-019, JA-020

use log::debug;
use tauri::State;

use super::repository::RepositoryManagerWrapper;
use crate::repository::{types::*, MediaRepository};

/// Create a new playlist
#[tauri::command]
#[specta::specta]
pub async fn playlist_create(
    manager: State<'_, RepositoryManagerWrapper>,
    handle: String,
    name: String,
    item_ids: Option<Vec<String>>,
) -> Result<PlaylistCreatedResult, String> {
    debug!("[PLAYLIST] create called: name={}", name);
    let repo = manager.0.get(&handle).ok_or("Repository not found")?;
    let ids = item_ids.unwrap_or_default();
    repo.as_ref()
        .create_playlist(&name, &ids)
        .await
        .map_err(|e| format!("{:?}", e))
}

/// Delete a playlist
#[tauri::command]
#[specta::specta]
pub async fn playlist_delete(
    manager: State<'_, RepositoryManagerWrapper>,
    handle: String,
    playlist_id: String,
) -> Result<(), String> {
    debug!("[PLAYLIST] delete called: id={}", playlist_id);
    let repo = manager.0.get(&handle).ok_or("Repository not found")?;
    repo.as_ref()
        .delete_playlist(&playlist_id)
        .await
        .map_err(|e| format!("{:?}", e))
}

/// Rename a playlist
#[tauri::command]
#[specta::specta]
pub async fn playlist_rename(
    manager: State<'_, RepositoryManagerWrapper>,
    handle: String,
    playlist_id: String,
    name: String,
) -> Result<(), String> {
    debug!(
        "[PLAYLIST] rename called: id={}, name={}",
        playlist_id, name
    );
    let repo = manager.0.get(&handle).ok_or("Repository not found")?;
    repo.as_ref()
        .rename_playlist(&playlist_id, &name)
        .await
        .map_err(|e| format!("{:?}", e))
}

/// Get playlist items with PlaylistItemId
#[tauri::command]
#[specta::specta]
pub async fn playlist_get_items(
    manager: State<'_, RepositoryManagerWrapper>,
    handle: String,
    playlist_id: String,
) -> Result<Vec<PlaylistEntry>, String> {
    debug!("[PLAYLIST] get_items called: id={}", playlist_id);
    let repo = manager.0.get(&handle).ok_or("Repository not found")?;
    repo.as_ref()
        .get_playlist_items(&playlist_id)
        .await
        .map_err(|e| format!("{:?}", e))
}

/// Add items to a playlist
#[tauri::command]
#[specta::specta]
pub async fn playlist_add_items(
    manager: State<'_, RepositoryManagerWrapper>,
    handle: String,
    playlist_id: String,
    item_ids: Vec<String>,
) -> Result<(), String> {
    debug!(
        "[PLAYLIST] add_items called: id={}, count={}",
        playlist_id,
        item_ids.len()
    );
    let repo = manager.0.get(&handle).ok_or("Repository not found")?;
    repo.as_ref()
        .add_to_playlist(&playlist_id, &item_ids)
        .await
        .map_err(|e| format!("{:?}", e))
}

/// Remove items from a playlist (uses PlaylistItemId entry IDs, NOT media item IDs)
#[tauri::command]
#[specta::specta]
pub async fn playlist_remove_items(
    manager: State<'_, RepositoryManagerWrapper>,
    handle: String,
    playlist_id: String,
    entry_ids: Vec<String>,
) -> Result<(), String> {
    debug!(
        "[PLAYLIST] remove_items called: id={}, count={}",
        playlist_id,
        entry_ids.len()
    );
    let repo = manager.0.get(&handle).ok_or("Repository not found")?;
    repo.as_ref()
        .remove_from_playlist(&playlist_id, &entry_ids)
        .await
        .map_err(|e| format!("{:?}", e))
}

/// Move a playlist item to a new position
#[tauri::command]
#[specta::specta]
pub async fn playlist_move_item(
    manager: State<'_, RepositoryManagerWrapper>,
    handle: String,
    playlist_id: String,
    item_id: String,
    new_index: u32,
) -> Result<(), String> {
    debug!(
        "[PLAYLIST] move_item called: playlist={}, item={}, index={}",
        playlist_id, item_id, new_index
    );
    let repo = manager.0.get(&handle).ok_or("Repository not found")?;
    repo.as_ref()
        .move_playlist_item(&playlist_id, &item_id, new_index)
        .await
        .map_err(|e| format!("{:?}", e))
}
