//! WebSocket 消息处理器
//! 专门处理 ComfyUI WebSocket 消息的解析和事件转换

use anyhow::{Result};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::{RwLock, broadcast};
use tracing::{debug};
use serde_json::Value;

use crate::business::services::realtime_monitor_v2::RealtimeEventV2;
use crate::data::repositories::comfyui_repository::ComfyUIRepository;

/// WebSocket 消息处理器
pub struct WebSocketHandler {
    /// 事件发送器
    event_sender: broadcast::Sender<RealtimeEventV2>,
    /// 提示 ID 到执行 ID 的映射
    prompt_execution_map: Arc<RwLock<HashMap<String, String>>>,
    /// 数据仓库
    repository: Arc<ComfyUIRepository>,
}

impl WebSocketHandler {
    /// 创建新的消息处理器
    pub fn new(
        event_sender: broadcast::Sender<RealtimeEventV2>,
        prompt_execution_map: Arc<RwLock<HashMap<String, String>>>,
        repository: Arc<ComfyUIRepository>,
    ) -> Self {
        Self {
            event_sender,
            prompt_execution_map,
            repository,
        }
    }

    /// 处理 WebSocket 消息
    pub async fn handle_message(&self, message: Value) -> Result<()> {
        debug!("处理 WebSocket 消息: {:?}", message);

        // 解析消息类型
        let message_type = message.get("type")
            .and_then(|t| t.as_str())
            .unwrap_or("unknown");

        let timestamp = chrono::Utc::now().to_rfc3339();

        match message_type {
            "executing" => self.handle_executing_message(message, timestamp).await?,
            "progress" => self.handle_progress_message(message, timestamp).await?,
            "executed" => self.handle_executed_message(message, timestamp).await?,
            "execution_error" => self.handle_execution_error_message(message, timestamp).await?,
            "status" => self.handle_status_message(message, timestamp).await?,
            _ => {
                debug!("未处理的消息类型: {}", message_type);
            }
        }

        Ok(())
    }

    /// 处理执行消息
    async fn handle_executing_message(&self, message: Value, timestamp: String) -> Result<()> {
        if let Some(data) = message.get("data") {
            let prompt_id = data.get("prompt_id")
                .and_then(|p| p.as_str())
                .unwrap_or("")
                .to_string();
            
            let node_id = data.get("node")
                .and_then(|n| n.as_str())
                .map(|s| s.to_string());

            let execution_id = {
                let map = self.prompt_execution_map.read().await;
                map.get(&prompt_id).cloned()
            };

            if let Some(node_id) = node_id {
                let _ = self.event_sender.send(RealtimeEventV2::NodeExecuting {
                    prompt_id: prompt_id.clone(),
                    execution_id: execution_id.clone(),
                    node_id: node_id.clone(),
                    node_title: None,
                    timestamp: timestamp.clone(),
                });
            } else {
                let _ = self.event_sender.send(RealtimeEventV2::ExecutionStarted {
                    prompt_id,
                    execution_id,
                    node_id: None,
                    timestamp,
                });
            }
        }
        Ok(())
    }

    /// 处理进度消息
    async fn handle_progress_message(&self, message: Value, timestamp: String) -> Result<()> {
        if let Some(data) = message.get("data") {
            let prompt_id = data.get("prompt_id")
                .and_then(|p| p.as_str())
                .unwrap_or("")
                .to_string();
            
            let node_id = data.get("node")
                .and_then(|n| n.as_str())
                .unwrap_or("")
                .to_string();

            let progress = data.get("value")
                .and_then(|v| v.as_u64())
                .unwrap_or(0) as u32;

            let max_progress = data.get("max")
                .and_then(|m| m.as_u64())
                .unwrap_or(100) as u32;

            let percentage = if max_progress > 0 {
                (progress as f32 / max_progress as f32) * 100.0
            } else {
                0.0
            };

            let execution_id = {
                let map = self.prompt_execution_map.read().await;
                map.get(&prompt_id).cloned()
            };

            let _ = self.event_sender.send(RealtimeEventV2::ExecutionProgress {
                prompt_id,
                execution_id,
                node_id,
                progress,
                max_progress,
                percentage,
                timestamp,
            });
        }
        Ok(())
    }

    /// 处理执行完成消息
    async fn handle_executed_message(&self, message: Value, timestamp: String) -> Result<()> {
        if let Some(data) = message.get("data") {
            let prompt_id = data.get("prompt_id")
                .and_then(|p| p.as_str())
                .unwrap_or("")
                .to_string();

            let outputs = data.get("output")
                .and_then(|o| o.as_object())
                .map(|obj| {
                    obj.iter()
                        .map(|(k, v)| (k.clone(), v.clone()))
                        .collect::<HashMap<String, serde_json::Value>>()
                })
                .unwrap_or_default();

            let output_urls = self.extract_output_urls(&outputs);

            let execution_id = {
                let map = self.prompt_execution_map.read().await;
                map.get(&prompt_id).cloned()
            };

            // 更新数据库中的执行状态
            if let Some(exec_id) = &execution_id {
                if let Ok(Some(mut execution)) = self.repository.get_execution(exec_id) {
                    execution.set_results(outputs.clone(), output_urls.clone());
                    let _ = self.repository.update_execution(&execution);
                }
            }

            let _ = self.event_sender.send(RealtimeEventV2::ExecutionCompleted {
                prompt_id: prompt_id.clone(),
                execution_id: execution_id.clone(),
                outputs,
                output_urls,
                execution_time: 0, // TODO: 计算实际执行时间
                timestamp,
            });

            // 清理映射
            {
                let mut map = self.prompt_execution_map.write().await;
                map.remove(&prompt_id);
            }
        }
        Ok(())
    }

    /// 处理执行错误消息
    async fn handle_execution_error_message(&self, message: Value, timestamp: String) -> Result<()> {
        if let Some(data) = message.get("data") {
            let prompt_id = data.get("prompt_id")
                .and_then(|p| p.as_str())
                .unwrap_or("")
                .to_string();

            let node_id = data.get("node_id")
                .and_then(|n| n.as_str())
                .map(|s| s.to_string());

            let error_msg = data.get("exception_message")
                .and_then(|e| e.as_str())
                .unwrap_or("未知错误")
                .to_string();

            let details = data.get("traceback").cloned();

            let execution_id = {
                let map = self.prompt_execution_map.read().await;
                map.get(&prompt_id).cloned()
            };

            // 更新数据库中的执行状态
            if let Some(exec_id) = &execution_id {
                if let Ok(Some(mut execution)) = self.repository.get_execution(exec_id) {
                    execution.set_error(error_msg.clone());
                    let _ = self.repository.update_execution(&execution);
                }
            }

            let _ = self.event_sender.send(RealtimeEventV2::ExecutionFailed {
                prompt_id: prompt_id.clone(),
                execution_id: execution_id.clone(),
                node_id,
                error: error_msg,
                details,
                timestamp,
            });

            // 清理映射
            {
                let mut map = self.prompt_execution_map.write().await;
                map.remove(&prompt_id);
            }
        }
        Ok(())
    }

    /// 处理状态消息
    async fn handle_status_message(&self, message: Value, timestamp: String) -> Result<()> {
        if let Some(data) = message.get("data") {
            let queue_running = data.get("status")
                .and_then(|s| s.get("exec_info"))
                .and_then(|e| e.get("queue_remaining"))
                .and_then(|q| q.as_u64())
                .unwrap_or(0) as u32;

            let _ = self.event_sender.send(RealtimeEventV2::QueueUpdated {
                running_count: if queue_running > 0 { 1 } else { 0 },
                pending_count: queue_running,
                timestamp,
            });
        }
        Ok(())
    }

    /// 提取输出 URLs
    fn extract_output_urls(&self, outputs: &HashMap<String, serde_json::Value>) -> Vec<String> {
        let mut urls = Vec::new();

        for (_, output) in outputs {
            if let Some(images) = output.get("images").and_then(|v| v.as_array()) {
                for image in images {
                    if let Some(filename) = image.get("filename").and_then(|v| v.as_str()) {
                        let url = format!("/view?filename={}", filename);
                        urls.push(url);
                    }
                }
            }
        }

        urls
    }
}
