use crate::error::AppError;
use crate::models::credential::{TuleapCredentials, TuleapCredentialsSafe};
use crate::services::crypto;
use crate::services::tuleap_client::TuleapClient;
use crate::AppState;
use tauri::State;

#[tauri::command]
pub fn set_tuleap_credentials(
    state: State<'_, AppState>,
    tuleap_url: String,
    username: String,
    password: String,
) -> Result<TuleapCredentialsSafe, AppError> {
    let password_encrypted = crypto::encrypt(&state.encryption_key, &password)
        .map_err(AppError::from)?;

    let db = state
        .db
        .lock()
        .map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;

    let creds = TuleapCredentials::upsert(&db, &tuleap_url, &username, &password_encrypted)?;
    Ok(creds.to_safe())
}

#[tauri::command]
pub fn get_tuleap_credentials(
    state: State<'_, AppState>,
) -> Result<Option<TuleapCredentialsSafe>, AppError> {
    let db = state
        .db
        .lock()
        .map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;

    let result = TuleapCredentials::get(&db)?.map(|c| c.to_safe());
    Ok(result)
}

#[tauri::command]
pub fn delete_tuleap_credentials(state: State<'_, AppState>) -> Result<(), AppError> {
    let db = state
        .db
        .lock()
        .map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;

    TuleapCredentials::delete(&db)?;
    Ok(())
}

#[tauri::command]
pub async fn test_tuleap_connection(state: State<'_, AppState>) -> Result<String, AppError> {
    let (tuleap_url, username, password) = {
        let db = state
            .db
            .lock()
            .map_err(|e| AppError::from(format!("Database lock failed: {}", e)))?;

        let creds = TuleapCredentials::get(&db)?
            .ok_or_else(|| AppError::from("No credentials configured".to_string()))?;

        let password = crypto::decrypt(&state.encryption_key, &creds.password_encrypted)
            .map_err(AppError::from)?;

        (creds.tuleap_url, creds.username, password)
    };

    let client = TuleapClient::new(&state.http_client, &tuleap_url, &username, &password);
    client.test_connection().await.map_err(AppError::from)?;

    Ok("Connection successful".to_string())
}
