//! 聊天相关命令

use tauri::{AppHandle, Emitter};

use crate::database::Database;
use crate::models::{ChatMessage, Conversation, event_names};
use crate::state::AppState;
use crate::utils::{CommandError, CommandResult, HEARTBEAT_INTERVAL_MS};
use crate::websocket::{HeartbeatManager, WsClient, WsConnectionEvent, WsServer};

/// 启动 WebSocket 服务端
#[tauri::command]
pub async fn start_websocket_server(app: AppHandle) -> CommandResult<()> {
    let state = AppState::get();
    let local_device = state.local_device.read().clone();
    
    // 创建并启动 WS 服务端
    let mut server = WsServer::new(
        local_device.ws_port,
        local_device.device_id.clone(),
        state.connection_manager.clone(),
    );
    
    server.start().await.map_err(|e| CommandError {
        code: "WS_SERVER_ERROR".to_string(),
        message: e.to_string(),
    })?;
    
    *state.ws_server.write() = Some(server);
    
    // 创建 WS 客户端
    let client = WsClient::new(
        local_device.device_id.clone(),
        state.connection_manager.clone(),
    );
    *state.ws_client.write() = Some(client);
    
    // 启动心跳管理
    HeartbeatManager::start(
        state.connection_manager.clone(),
        local_device.device_id.clone(),
        HEARTBEAT_INTERVAL_MS,
    );
    
    // 监听连接事件
    let mut rx = state.connection_manager.subscribe();
    let app_handle = app.clone();
    
    tokio::spawn(async move {
        while let Ok(event) = rx.recv().await {
            match event {
                WsConnectionEvent::Connected { device_id } => {
                    let _ = app_handle.emit(event_names::WEBSOCKET_CONNECTED, serde_json::json!({
                        "deviceId": device_id
                    }));
                }
                WsConnectionEvent::Disconnected { device_id, reason } => {
                    let _ = app_handle.emit(event_names::WEBSOCKET_DISCONNECTED, serde_json::json!({
                        "deviceId": device_id,
                        "reason": reason
                    }));
                }
                WsConnectionEvent::MessageReceived { message } => {
                    let _ = app_handle.emit(event_names::MESSAGE_RECEIVED, &message);
                }
            }
        }
    });
    
    log::info!("WebSocket server started on port {}", local_device.ws_port);
    Ok(())
}

/// 停止 WebSocket 服务端
#[tauri::command]
pub async fn stop_websocket_server() -> CommandResult<()> {
    let state = AppState::get();
    
    // 关闭所有连接
    state.connection_manager.close_all().await;
    
    // 停止服务端
    if let Some(mut server) = state.ws_server.write().take() {
        server.stop();
    }
    
    *state.ws_client.write() = None;
    
    log::info!("WebSocket server stopped");
    Ok(())
}

/// 连接到指定设备
#[tauri::command]
pub async fn connect_to_peer(device_id: String) -> CommandResult<()> {
    let state = AppState::get();
    
    // 获取设备信息
    let device = state
        .device_manager
        .get_device(&device_id)
        .ok_or_else(|| CommandError {
            code: "DEVICE_NOT_FOUND".to_string(),
            message: format!("Device {} not found", device_id),
        })?;
    
    // 检查是否已连接 (同步检查，立即释放锁)
    {
        let client_guard = state.ws_client.read();
        if let Some(client) = client_guard.as_ref() {
            if client.is_connected(&device_id) || state.connection_manager.is_connected(&device_id) {
                return Ok(());
            }
        } else if state.connection_manager.is_connected(&device_id) {
            return Ok(());
        }
    }
    
    // 克隆客户端引用以便异步使用
    let ws_client = {
        let client_guard = state.ws_client.read();
        client_guard.as_ref().cloned()
    };
    
    let client = ws_client.ok_or_else(|| CommandError {
        code: "WS_NOT_STARTED".to_string(),
        message: "WebSocket client not started".to_string(),
    })?;
    
    client.connect(&device).await.map_err(|e| CommandError {
        code: "CONNECTION_ERROR".to_string(),
        message: e.to_string(),
    })?;
    
    // 更新设备在线状态
    state.device_manager.set_device_online(&device_id, true);
    
    log::info!("Connected to device {}", device_id);
    Ok(())
}

/// 断开与指定设备的连接
#[tauri::command]
pub async fn disconnect_from_peer(device_id: String) -> CommandResult<()> {
    let state = AppState::get();
    
    // 克隆客户端引用
    let ws_client = {
        let client_guard = state.ws_client.read();
        client_guard.as_ref().cloned()
    };
    
    if let Some(client) = ws_client {
        client.disconnect(&device_id).await;
    }
    
    state.device_manager.set_device_online(&device_id, false);
    
    log::info!("Disconnected from device {}", device_id);
    Ok(())
}

/// 发送聊天消息
#[tauri::command]
pub async fn send_chat_message(
    device_id: String,
    content: String,
    message_type: Option<String>,
) -> CommandResult<ChatMessage> {
    let state = AppState::get();
    
    // 获取本地设备 ID (立即释放锁)
    let local_device_id = {
        let local_device = state.local_device.read();
        local_device.device_id.clone()
    };
    
    // 创建消息
    let message = match message_type.as_deref() {
        Some("image") => ChatMessage::new_image(
            local_device_id,
            device_id.clone(),
            content,
        ),
        Some("file") => ChatMessage::new_file(
            local_device_id,
            device_id.clone(),
            content,
        ),
        _ => ChatMessage::new_text(
            local_device_id,
            device_id.clone(),
            content,
        ),
    };
    
    // 保存到数据库
    Database::save_message(&message).map_err(|e| CommandError {
        code: "DB_ERROR".to_string(),
        message: e.to_string(),
    })?;
    
    // 获取客户端 (立即释放锁)
    let ws_client = {
        let client_guard = state.ws_client.read();
        client_guard.as_ref().cloned()
    };
    
    let mut sent = false;
    
    // 尝试通过客户端发送（主动连接的情况）
    if let Some(client) = &ws_client {
        if client.is_connected(&device_id) {
            client.send_to(&device_id, &message).await.map_err(|e| CommandError {
                code: "SEND_ERROR".to_string(),
                message: e,
            })?;
            sent = true;
        }
    }
    
    // 如果客户端没有发送，尝试通过服务端连接发送（被动连接的情况）
    if !sent {
        state
            .connection_manager
            .send_to(&device_id, &message)
            .await
            .map_err(|e| CommandError {
                code: "SEND_ERROR".to_string(),
                message: e,
            })?;
    }
    
    Ok(message)
}

/// 获取聊天历史
#[tauri::command]
pub async fn get_chat_history(
    device_id: String,
    limit: Option<usize>,
    offset: Option<usize>,
) -> CommandResult<Vec<ChatMessage>> {
    let state = AppState::get();
    let local_device = state.local_device.read();
    
    let messages = Database::get_chat_history(
        &device_id,
        &local_device.device_id,
        limit.unwrap_or(50),
        offset.unwrap_or(0),
    )
    .map_err(|e| CommandError {
        code: "DB_ERROR".to_string(),
        message: e.to_string(),
    })?;
    
    Ok(messages)
}

/// 删除聊天历史
#[tauri::command]
pub async fn delete_chat_history(device_id: String) -> CommandResult<usize> {
    let state = AppState::get();
    let local_device = state.local_device.read();
    
    let count = Database::delete_chat_history(&device_id, &local_device.device_id)
        .map_err(|e| CommandError {
            code: "DB_ERROR".to_string(),
            message: e.to_string(),
        })?;
    
    Ok(count)
}

/// 获取会话列表（所有有聊天记录的设备）
#[tauri::command]
pub async fn get_conversations() -> CommandResult<Vec<Conversation>> {
    let state = AppState::get();
    let local_device_id = state.local_device.read().device_id.clone();
    
    let mut conversations = Database::get_conversations(&local_device_id)
        .map_err(|e| CommandError {
            code: "DB_ERROR".to_string(),
            message: e.to_string(),
        })?;
    
    // 更新在线状态
    for conv in &mut conversations {
        conv.online = state.device_manager.is_device_online(&conv.device_id);
    }
    
    Ok(conversations)
}
