use tauri::State;

use crate::db::connection::DbManager;
use crate::domains::book::service::CompleteSeries;
use crate::domains::series_sync::service;
use crate::error::AppError;
use crate::shared::session::SessionState;
use crate::shared::types::Lang;

fn get_session(session: &State<SessionState>) -> Result<(String, Lang), AppError> {
    let session_guard = session.lock().map_err(|e| AppError::Internal(format!("Session lock failed: {}", e)))?;
    let user_id = session_guard.get_user_id().map_err(|e| AppError::Auth(e))?.to_string();
    let lang = session_guard.lang;
    Ok((user_id, lang))
}

#[tauri::command]
pub fn upload_series_to_server(series_id: String, db: State<DbManager>, session: State<SessionState>) -> Result<CompleteSeries, AppError> {
    let (user_id, lang) = get_session(&session)?;
    let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
    let conn = db_manager.get_connection(&user_id)?;
    service::get_complete_series_for_upload(conn, &user_id, &series_id, lang)
}

#[tauri::command]
pub fn sync_save_series(data: CompleteSeries, db: State<DbManager>, session: State<SessionState>) -> Result<bool, AppError> {
    let (user_id, lang) = get_session(&session)?;
    let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
    let conn = db_manager.get_connection(&user_id)?;
    service::save_complete_series(conn, &user_id, &data, lang)
}

#[tauri::command]
pub fn sync_series_to_client(data: CompleteSeries, db: State<DbManager>, session: State<SessionState>) -> Result<bool, AppError> {
    let (user_id, lang) = get_session(&session)?;
    let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
    let conn = db_manager.get_connection(&user_id)?;
    service::sync_series_from_server_to_client(conn, &user_id, &data, lang)
}

#[tauri::command]
pub fn sync_series_to_server(series_id: String, db: State<DbManager>, session: State<SessionState>) -> Result<CompleteSeries, AppError> {
    let (user_id, lang) = get_session(&session)?;
    let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
    let conn = db_manager.get_connection(&user_id)?;
    service::get_complete_series_for_upload(conn, &user_id, &series_id, lang)
}

#[tauri::command]
pub fn series_sync_upload(data: service::SeriesSyncUploadPayload, db: State<DbManager>, session: State<SessionState>) -> Result<service::SeriesSyncResult, AppError> {
    let (user_id, lang) = get_session(&session)?;
    let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
    let conn = db_manager.get_connection(&user_id)?;
    service::upload_field_to_series(conn, &user_id, &data, lang)
}
