use crate::{models::*, Vpn};
use std::sync::atomic::Ordering;
use tauri::{command, AppHandle, Manager, Runtime};

#[command]
pub(crate) fn start_vpn<R: Runtime>(
    app: AppHandle<R>,
    config: TunnelConfig,
    ip: String,
    port: i32,
    sni: String,
) -> crate::Result<()> {
    let vpn = app.state::<Vpn<R>>();
    // Атомарный guard от повторного запуска (двойной клик, повторный invoke) —
    // compare_exchange проверяет и выставляет флаг одной операцией, обычная
    // проверка is_running() + set() гонки бы не исключила.
    if vpn
        .is_running
        .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
        .is_err()
    {
        return Ok(());
    }
    match vpn.start_vpn(config, ip, port, sni) {
        Ok(res) => Ok(res),
        Err(e) => {
            vpn.is_running.store(false, Ordering::SeqCst);
            Err(e)
        }
    }
}

#[command]
pub(crate) fn stop_vpn<R: Runtime>(app: AppHandle<R>) -> crate::Result<()> {
    let vpn = app.state::<Vpn<R>>();
    let result = vpn.stop_vpn();
    vpn.is_running.store(false, Ordering::SeqCst);
    result
}

#[command]
pub(crate) fn check_actual_vpn_status<R: tauri::Runtime>(
    app: tauri::AppHandle<R>,
) -> crate::Result<StatusResponse> {
    let vpn = app.state::<Vpn<R>>();
    vpn.check_actual_vpn_status()
}

#[command]
pub(crate) fn get_installed_apps<R: Runtime>(app: AppHandle<R>) -> crate::Result<Vec<AppInfo>> {
    app.state::<Vpn<R>>().get_installed_apps()
}

#[command]
pub(crate) fn launch_app<R: Runtime>(app: AppHandle<R>, package_name: String) -> crate::Result<()> {
    app.state::<Vpn<R>>().launch_app(package_name)
}
