//! 设备发现相关命令

use tauri::{AppHandle, Emitter};

use crate::database::Database;
use crate::discovery::{DiscoveryEvent, DiscoveryService};
use crate::models::{DeviceInfo, event_names};
use crate::state::AppState;
use crate::utils::CommandResult;

/// 启动设备发现服务
#[tauri::command]
pub async fn start_discovery_service(app: AppHandle) -> CommandResult<()> {
    let state = AppState::get();
    
    // 更新本机 IP
    state.update_local_ip();
    
    let local_device = state.local_device.read().clone();
    
    // 创建并启动发现服务
    let mut discovery = DiscoveryService::new(local_device);
    let mut rx = discovery.subscribe();
    
    discovery.start().await.map_err(|e| crate::utils::CommandError {
        code: "DISCOVERY_ERROR".to_string(),
        message: e.to_string(),
    })?;
    
    // 存储服务实例
    *state.discovery_service.write() = Some(discovery);
    
    // 启动设备超时检查
    state.device_manager.start_timeout_checker();
    
    // 监听发现事件并转发到前端
    let app_handle = app.clone();
    let device_manager = state.device_manager.clone();
    
    tokio::spawn(async move {
        while let Ok(event) = rx.recv().await {
            match event {
                DiscoveryEvent::DeviceFound(device) => {
                    // 保存到已知设备数据库
                    if let Err(e) = Database::save_known_device(&device) {
                        log::error!("Failed to save known device: {}", e);
                    }
                    
                    device_manager.upsert_device(device.clone());
                    let _ = app_handle.emit(event_names::DEVICE_FOUND, &device);
                }
                DiscoveryEvent::DeviceLost(device_id) => {
                    device_manager.remove_device(&device_id);
                    let _ = app_handle.emit(event_names::DEVICE_LOST, serde_json::json!({
                        "deviceId": device_id
                    }));
                }
                _ => {}
            }
        }
    });
    
    log::info!("Discovery service started");
    Ok(())
}

/// 停止设备发现服务
#[tauri::command]
pub async fn stop_discovery_service() -> CommandResult<()> {
    let state = AppState::get();
    
    // 取出 discovery 服务，释放锁后再操作
    let discovery_opt = state.discovery_service.write().take();
    
    if let Some(mut discovery) = discovery_opt {
        // 发送离线通知
        let _ = discovery.send_goodbye().await;
        discovery.stop();
    }
    
    // 清空设备列表
    state.device_manager.clear();
    
    log::info!("Discovery service stopped");
    Ok(())
}

/// 获取已发现的设备列表（在线设备）
#[tauri::command]
pub async fn get_discovered_devices() -> CommandResult<Vec<DeviceInfo>> {
    let state = AppState::get();
    let devices = state.device_manager.get_all_devices();
    Ok(devices)
}

/// 获取历史设备列表（从数据库）
/// 这些是曾经发现过的设备，可能当前已离线
#[tauri::command]
pub async fn get_known_devices() -> CommandResult<Vec<DeviceInfo>> {
    let devices = Database::get_known_devices().map_err(|e| crate::utils::CommandError {
        code: "DB_ERROR".to_string(),
        message: e.to_string(),
    })?;
    Ok(devices)
}
