use serde::{Serialize, Deserialize};
use tauri::State;

use crate::errors::*;
use crate::config::AppConfig;
use crate::clientinfo::Client;
use crate::state::{AppState, Session, Credentials};


#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Request {
    pub id: u64,
    pub clients: Vec<Option<Client>>,
}


#[derive(Debug, Serialize, Deserialize)]
pub struct RequestResponse {
    pub id: u64,
    pub approval: Approval,
}


#[derive(Debug, Serialize, Deserialize)]
pub enum Approval {
    Approved,
    Denied,
}


#[tauri::command]
pub fn respond(response: RequestResponse, app_state: State<'_, AppState>) -> Result<(), String> {
    app_state.send_response(response)
        .map_err(|e| format!("Error responding to request: {e}"))
}


#[tauri::command]
pub async fn unlock(passphrase: String, app_state: State<'_, AppState>) -> Result<(), UnlockError> {
    app_state.decrypt(&passphrase).await
}


#[tauri::command]
pub fn get_session_status(app_state: State<'_, AppState>) -> String {
    let session = app_state.session.read().unwrap();
    match *session {
        Session::Locked(_) => "locked".into(),
        Session::Unlocked(_) => "unlocked".into(),
        Session::Empty => "empty".into()
    }
}


#[tauri::command]
pub async fn save_credentials(
    credentials: Credentials,
    passphrase: String,
    app_state: State<'_, AppState>
) -> Result<(), UnlockError> {
    app_state.save_creds(credentials, &passphrase).await
}


#[tauri::command]
pub fn get_config(app_state: State<'_, AppState>) -> AppConfig {
    let config = app_state.config.read().unwrap();
    config.clone()
}
