//! 执行引擎
//! 负责工作流和模板的执行管理

use anyhow::{Result, anyhow};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::RwLock;
use tracing::{info, warn, error, debug};

use comfyui_sdk::templates::WorkflowInstance;
use comfyui_sdk::types::{ParameterValues, PromptRequest, ExecutionOptions};

use crate::business::services::comfyui_manager::ComfyUIManager;
use crate::business::services::template_engine::TemplateEngine;
use crate::data::models::comfyui::{ExecutionModel, ExecutionStatus, WorkflowModel};
use crate::data::repositories::comfyui_repository::ComfyUIRepository;

/// 执行结果
#[derive(Debug, Clone)]
pub struct ExecutionResult {
    /// 执行记录 ID
    pub execution_id: String,
    /// ComfyUI 提示 ID
    pub prompt_id: String,
    /// 执行状态
    pub status: ExecutionStatus,
    /// 输出文件 URLs
    pub output_urls: Vec<String>,
    /// 节点输出详情
    pub node_outputs: Option<HashMap<String, serde_json::Value>>,
    /// 执行时间（毫秒）
    pub execution_time: Option<u64>,
    /// 错误信息
    pub error_message: Option<String>,
}

/// 执行配置
#[derive(Debug, Clone)]
pub struct ExecutionConfig {
    /// 超时时间
    pub timeout: Duration,
    /// 优先级
    pub priority: Option<i32>,
    /// 是否等待完成
    pub wait_for_completion: bool,
    /// 进度回调间隔
    pub progress_interval: Duration,
}

impl Default for ExecutionConfig {
    fn default() -> Self {
        Self {
            timeout: Duration::from_secs(300), // 5分钟默认超时
            priority: None,
            wait_for_completion: true,
            progress_interval: Duration::from_secs(1),
        }
    }
}

/// 执行引擎
/// 提供工作流和模板的执行管理功能
pub struct ExecutionEngine {
    /// ComfyUI 管理器
    manager: Arc<ComfyUIManager>,
    /// 模板引擎
    template_engine: Arc<TemplateEngine>,
    /// 数据仓库
    repository: Arc<ComfyUIRepository>,
    /// 正在执行的任务
    running_executions: Arc<RwLock<HashMap<String, ExecutionModel>>>,
}

impl ExecutionEngine {
    /// 创建新的执行引擎
    pub fn new(
        manager: Arc<ComfyUIManager>,
        template_engine: Arc<TemplateEngine>,
        repository: Arc<ComfyUIRepository>,
    ) -> Self {
        Self {
            manager,
            template_engine,
            repository,
            running_executions: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    /// 执行工作流
    pub async fn execute_workflow(
        &self,
        workflow: &WorkflowModel,
        parameters: Option<ParameterValues>,
        config: ExecutionConfig,
    ) -> Result<ExecutionResult> {
        info!("开始执行工作流: {} ({})", workflow.name, workflow.id);

        // 检查连接状态
        if !self.manager.is_connected().await {
            return Err(anyhow!("ComfyUI 服务未连接"));
        }

        // 获取客户端
        let client_arc = self.manager.get_client().await?;
        let client_guard = client_arc.read().await;
        let client = client_guard.as_ref().ok_or_else(|| anyhow!("客户端未连接"))?;

        // 创建提示请求
        let prompt_request = PromptRequest {
            prompt: workflow.workflow_data.iter()
                .map(|(k, v)| (k.clone(), serde_json::to_value(v).unwrap_or(serde_json::Value::Null)))
                .collect(),
            client_id: None,
            extra_data: None,
        };

        // 提交工作流
        let prompt_response = client.http().queue_prompt(&prompt_request).await
            .map_err(|e| anyhow!("提交工作流失败: {}", e))?;

        let prompt_id = prompt_response.prompt_id.clone();

        // 创建执行记录
        let mut execution = ExecutionModel::for_workflow(
            workflow.id.clone(),
            prompt_id.clone(),
            parameters,
        );
        execution.update_status(ExecutionStatus::Running);

        // 保存执行记录
        self.repository.create_execution(&execution)?;

        // 添加到运行中的任务
        {
            let mut running = self.running_executions.write().await;
            running.insert(execution.id.clone(), execution.clone());
        }

        debug!("工作流已提交，prompt_id: {}, execution_id: {}", prompt_id, execution.id);

        // 如果需要等待完成
        if config.wait_for_completion {
            self.wait_for_completion(&execution.id, config).await
        } else {
            Ok(ExecutionResult {
                execution_id: execution.id,
                prompt_id,
                status: ExecutionStatus::Running,
                output_urls: Vec::new(),
                node_outputs: None,
                execution_time: None,
                error_message: None,
            })
        }
    }

    /// 执行模板
    pub async fn execute_template(
        &self,
        template_id: &str,
        parameters: ParameterValues,
        config: ExecutionConfig,
    ) -> Result<ExecutionResult> {
        info!("开始执行模板: {}", template_id);

        // 检查连接状态
        if !self.manager.is_connected().await {
            return Err(anyhow!("ComfyUI 服务未连接"));
        }

        // 创建模板实例
        let instance = self.template_engine.create_instance(template_id, parameters.clone()).await?;

        // 获取客户端
        let client_arc = self.manager.get_client().await?;
        let client_guard = client_arc.read().await;
        let client = client_guard.as_ref().ok_or_else(|| anyhow!("客户端未连接"))?;

        // 创建提示请求
        let workflow_json = instance.to_workflow_json()?;
        let prompt_request = PromptRequest {
            prompt: if let serde_json::Value::Object(map) = workflow_json {
                map.into_iter().collect()
            } else {
                return Err(anyhow!("工作流必须是 JSON 对象"));
            },
            client_id: None,
            extra_data: None,
        };

        // 提交工作流
        let prompt_response = client.http().queue_prompt(&prompt_request).await
            .map_err(|e| anyhow!("提交模板失败: {}", e))?;

        let prompt_id = prompt_response.prompt_id.clone();

        // 创建执行记录
        let mut execution = ExecutionModel::for_template(
            template_id.to_string(),
            prompt_id.clone(),
            parameters,
        );
        execution.update_status(ExecutionStatus::Running);

        // 保存执行记录
        self.repository.create_execution(&execution)?;

        // 添加到运行中的任务
        {
            let mut running = self.running_executions.write().await;
            running.insert(execution.id.clone(), execution.clone());
        }

        debug!("模板已提交，prompt_id: {}, execution_id: {}", prompt_id, execution.id);

        // 如果需要等待完成
        if config.wait_for_completion {
            self.wait_for_completion(&execution.id, config).await
        } else {
            Ok(ExecutionResult {
                execution_id: execution.id,
                prompt_id,
                status: ExecutionStatus::Running,
                output_urls: Vec::new(),
                node_outputs: None,
                execution_time: None,
                error_message: None,
            })
        }
    }

    /// 取消执行
    pub async fn cancel_execution(&self, execution_id: &str) -> Result<()> {
        info!("取消执行: {}", execution_id);

        // 从运行中的任务移除
        let execution = {
            let mut running = self.running_executions.write().await;
            running.remove(execution_id)
        };

        if let Some(mut execution) = execution {
            // 更新状态为已取消
            execution.update_status(ExecutionStatus::Cancelled);
            
            // 更新数据库
            self.repository.update_execution(&execution)?;

            // TODO: 调用 ComfyUI API 取消任务
            // 这需要 SDK 支持取消操作

            info!("执行已取消: {}", execution_id);
            Ok(())
        } else {
            Err(anyhow!("执行记录不存在或已完成: {}", execution_id))
        }
    }

    /// 获取执行状态
    pub async fn get_execution_status(&self, execution_id: &str) -> Result<ExecutionResult> {
        // 先检查运行中的任务
        {
            let running = self.running_executions.read().await;
            if let Some(execution) = running.get(execution_id) {
                return Ok(ExecutionResult {
                    execution_id: execution.id.clone(),
                    prompt_id: execution.prompt_id.clone(),
                    status: execution.status.clone(),
                    output_urls: execution.output_urls.clone(),
                    node_outputs: execution.node_outputs.clone(),
                    execution_time: execution.execution_time,
                    error_message: execution.error_message.clone(),
                });
            }
        }

        // 从数据库查询
        match self.repository.get_execution(execution_id)? {
            Some(execution) => Ok(ExecutionResult {
                execution_id: execution.id,
                prompt_id: execution.prompt_id,
                status: execution.status,
                output_urls: execution.output_urls,
                node_outputs: execution.node_outputs,
                execution_time: execution.execution_time,
                error_message: execution.error_message,
            }),
            None => Err(anyhow!("执行记录不存在: {}", execution_id)),
        }
    }

    /// 等待执行完成
    async fn wait_for_completion(&self, execution_id: &str, config: ExecutionConfig) -> Result<ExecutionResult> {
        let start_time = std::time::Instant::now();
        
        loop {
            // 检查超时
            if start_time.elapsed() >= config.timeout {
                // 超时，取消执行
                let _ = self.cancel_execution(execution_id).await;
                return Err(anyhow!("执行超时: {}", execution_id));
            }

            // 获取当前状态
            let status = self.get_execution_status(execution_id).await?;

            match status.status {
                ExecutionStatus::Completed => {
                    info!("执行完成: {}", execution_id);
                    return Ok(status);
                }
                ExecutionStatus::Failed => {
                    error!("执行失败: {}", execution_id);
                    return Ok(status);
                }
                ExecutionStatus::Cancelled => {
                    warn!("执行已取消: {}", execution_id);
                    return Ok(status);
                }
                ExecutionStatus::Running | ExecutionStatus::Pending => {
                    // 继续等待
                    tokio::time::sleep(config.progress_interval).await;
                }
            }
        }
    }

    /// 获取执行历史
    pub async fn get_execution_history(&self, limit: Option<u32>) -> Result<Vec<ExecutionResult>> {
        let executions = self.repository.list_executions(limit, None)?;
        
        let results = executions
            .into_iter()
            .map(|execution| ExecutionResult {
                execution_id: execution.id,
                prompt_id: execution.prompt_id,
                status: execution.status,
                output_urls: execution.output_urls,
                node_outputs: execution.node_outputs,
                execution_time: execution.execution_time,
                error_message: execution.error_message,
            })
            .collect();

        Ok(results)
    }

    /// 清理已完成的执行记录
    pub async fn cleanup_completed_executions(&self) {
        let mut running = self.running_executions.write().await;
        let mut to_remove = Vec::new();

        for (id, execution) in running.iter() {
            if execution.is_completed() {
                to_remove.push(id.clone());
            }
        }

        for id in to_remove {
            running.remove(&id);
        }

        if !running.is_empty() {
            debug!("清理完成，剩余运行中的任务: {}", running.len());
        }
    }

    /// 获取运行统计信息
    pub async fn get_execution_stats(&self) -> ExecutionStats {
        let running = self.running_executions.read().await;
        
        ExecutionStats {
            running_count: running.len(),
            running_executions: running.keys().cloned().collect(),
        }
    }
}

/// 执行统计信息
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ExecutionStats {
    pub running_count: usize,
    pub running_executions: Vec<String>,
}
