use anyhow::{Result, anyhow};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use tracing::{info, warn, error, debug};

use crate::config::ComfyUISettings;
use crate::business::services::comfyui_service::ComfyUIService;
use crate::business::services::comfyui_sdk_service::{ComfyUISDKService, WorkflowExecutionResult, SDKExecutionConfig};
use crate::data::models::outfit_photo_generation::{WorkflowProgress, WorkflowNodeReplacement};

/// ComfyUI 集成服务
/// 提供统一的接口，可以选择使用原生实现或 SDK 实现
pub struct ComfyUIIntegrationService {
    legacy_service: Arc<ComfyUIService>,
    sdk_service: Option<Arc<ComfyUISDKService>>,
    use_sdk: bool,
    settings: ComfyUISettings,
}

/// 集成服务配置
#[derive(Debug, Clone)]
pub struct IntegrationConfig {
    pub prefer_sdk: bool,
    pub fallback_to_legacy: bool,
    pub timeout: Duration,
    pub retry_attempts: u32,
}

impl Default for IntegrationConfig {
    fn default() -> Self {
        Self {
            prefer_sdk: true,
            fallback_to_legacy: true,
            timeout: Duration::from_secs(300),
            retry_attempts: 3,
        }
    }
}

/// 统一的工作流执行结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnifiedWorkflowResult {
    pub prompt_id: String,
    pub outputs: HashMap<String, Vec<String>>,
    pub execution_time: Duration,
    pub node_outputs: HashMap<String, Value>,
    pub used_sdk: bool,
}

impl ComfyUIIntegrationService {
    /// 创建新的集成服务实例
    pub async fn new(settings: ComfyUISettings, config: IntegrationConfig) -> Result<Self> {
        // 创建传统服务
        let legacy_service = Arc::new(ComfyUIService::new(settings.clone()));

        // 尝试创建 SDK 服务
        let sdk_service = if config.prefer_sdk {
            match ComfyUISDKService::new(settings.clone()) {
                Ok(service) => {
                    info!("ComfyUI SDK 服务初始化成功");
                    Some(Arc::new(service))
                }
                Err(e) => {
                    warn!("ComfyUI SDK 服务初始化失败: {}, 将使用传统服务", e);
                    None
                }
            }
        } else {
            None
        };

        let use_sdk = sdk_service.is_some() && config.prefer_sdk;

        Ok(Self {
            legacy_service,
            sdk_service,
            use_sdk,
            settings,
        })
    }

    /// 检查服务健康状态
    pub async fn check_health(&self) -> Result<bool> {
        if self.use_sdk {
            if let Some(sdk_service) = &self.sdk_service {
                match sdk_service.check_health().await {
                    Ok(healthy) => return Ok(healthy),
                    Err(e) => {
                        warn!("SDK 健康检查失败，尝试传统服务: {}", e);
                    }
                }
            }
        }

        // 回退到传统服务
        self.legacy_service.check_health().await
    }

    /// 执行工作流（统一接口）
    pub async fn execute_workflow(
        &self,
        workflow: Value,
        replacements: Vec<WorkflowNodeReplacement>,
        config: IntegrationConfig,
    ) -> Result<UnifiedWorkflowResult> {
        // 应用节点替换
        let processed_workflow = self.apply_replacements(workflow, replacements)?;

        // 优先使用 SDK
        if self.use_sdk {
            if let Some(sdk_service) = &self.sdk_service {
                match self.execute_with_sdk(sdk_service.clone(), processed_workflow.clone(), &config).await {
                    Ok(result) => {
                        info!("使用 SDK 成功执行工作流");
                        return Ok(UnifiedWorkflowResult {
                            prompt_id: result.prompt_id,
                            outputs: result.outputs,
                            execution_time: result.execution_time,
                            node_outputs: result.node_outputs,
                            used_sdk: true,
                        });
                    }
                    Err(e) => {
                        warn!("SDK 执行失败: {}", e);
                        if !config.fallback_to_legacy {
                            return Err(e);
                        }
                    }
                }
            }
        }

        // 回退到传统服务
        info!("使用传统服务执行工作流");
        let result = self.execute_with_legacy(processed_workflow, &config).await?;
        
        Ok(UnifiedWorkflowResult {
            prompt_id: result.prompt_id,
            outputs: result.outputs,
            execution_time: result.execution_time,
            node_outputs: result.node_outputs,
            used_sdk: false,
        })
    }

    /// 使用 SDK 执行工作流
    async fn execute_with_sdk(
        &self,
        sdk_service: Arc<ComfyUISDKService>,
        workflow: Value,
        config: &IntegrationConfig,
    ) -> Result<WorkflowExecutionResult> {
        let sdk_config = SDKExecutionConfig {
            timeout: config.timeout,
            retry_attempts: config.retry_attempts,
        };

        sdk_service.execute_workflow(workflow, sdk_config).await
    }

    /// 使用传统服务执行工作流
    async fn execute_with_legacy(
        &self,
        workflow: Value,
        config: &IntegrationConfig,
    ) -> Result<LegacyWorkflowResult> {
        // 这里需要调用传统服务的执行方法
        // 由于原始的 ComfyUIService 可能没有统一的执行接口，我们需要适配
        
        let start_time = std::time::Instant::now();
        
        // 提交工作流
        let prompt_id = self.legacy_service.submit_workflow(workflow).await?;
        
        // 等待完成（这里需要根据实际的传统服务接口来实现）
        let outputs = self.legacy_service.wait_for_completion(&prompt_id, config.timeout).await?;
        
        let execution_time = start_time.elapsed();
        
        Ok(LegacyWorkflowResult {
            prompt_id,
            outputs,
            execution_time,
            node_outputs: HashMap::new(), // 传统服务可能不提供详细的节点输出
        })
    }

    /// 应用节点替换
    fn apply_replacements(
        &self,
        mut workflow: Value,
        replacements: Vec<WorkflowNodeReplacement>,
    ) -> Result<Value> {
        for replacement in replacements {
            if let Some(node) = workflow.get_mut(&replacement.node_id) {
                if let Some(inputs) = node.get_mut("inputs") {
                    if let Some(inputs_obj) = inputs.as_object_mut() {
                        inputs_obj.insert(replacement.input_field, replacement.value);
                    }
                }
            }
        }
        Ok(workflow)
    }

    /// 获取队列状态
    pub async fn get_queue_status(&self) -> Result<QueueStatusInfo> {
        if self.use_sdk {
            if let Some(sdk_service) = &self.sdk_service {
                match sdk_service.get_queue_status().await {
                    Ok(status) => {
                        return Ok(QueueStatusInfo {
                            running: status.running,
                            pending: status.pending,
                            from_sdk: true,
                        });
                    }
                    Err(e) => {
                        warn!("SDK 获取队列状态失败: {}", e);
                    }
                }
            }
        }

        // 回退到传统服务
        let status = self.legacy_service.get_queue_status().await?;
        Ok(QueueStatusInfo {
            running: status.running,
            pending: status.pending,
            from_sdk: false,
        })
    }

    /// 取消工作流执行
    pub async fn cancel_workflow(&self, prompt_id: &str) -> Result<()> {
        if self.use_sdk {
            if let Some(sdk_service) = &self.sdk_service {
                if let Ok(_) = sdk_service.cancel_workflow(prompt_id).await {
                    return Ok(());
                }
            }
        }

        // 回退到传统服务
        self.legacy_service.cancel_workflow(prompt_id).await
    }

    /// 切换到 SDK 模式
    pub async fn switch_to_sdk(&mut self) -> Result<()> {
        if self.sdk_service.is_none() {
            let sdk_service = ComfyUISDKService::new(self.settings.clone())?;
            self.sdk_service = Some(Arc::new(sdk_service));
        }
        self.use_sdk = true;
        info!("已切换到 SDK 模式");
        Ok(())
    }

    /// 切换到传统模式
    pub fn switch_to_legacy(&mut self) {
        self.use_sdk = false;
        info!("已切换到传统模式");
    }

    /// 获取当前使用的服务类型
    pub fn get_current_service_type(&self) -> &'static str {
        if self.use_sdk && self.sdk_service.is_some() {
            "SDK"
        } else {
            "Legacy"
        }
    }
}

/// 传统服务工作流结果
#[derive(Debug)]
struct LegacyWorkflowResult {
    prompt_id: String,
    outputs: HashMap<String, Vec<String>>,
    execution_time: Duration,
    node_outputs: HashMap<String, Value>,
}

/// 队列状态信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QueueStatusInfo {
    pub running: usize,
    pub pending: usize,
    pub from_sdk: bool,
}

/// ComfyUIService 的扩展 trait
/// 为现有的 ComfyUIService 添加统一接口
pub trait ComfyUIServiceExt {
    async fn submit_workflow(&self, workflow: Value) -> Result<String>;
    async fn wait_for_completion(&self, prompt_id: &str, timeout: Duration) -> Result<HashMap<String, Vec<String>>>;
    async fn get_queue_status(&self) -> Result<QueueStatusInfo>;
    async fn cancel_workflow(&self, prompt_id: &str) -> Result<()>;
    async fn check_health(&self) -> Result<bool>;
}

/// 为 ComfyUIService 实现扩展 trait
impl ComfyUIServiceExt for ComfyUIService {
    async fn submit_workflow(&self, workflow: Value) -> Result<String> {
        // 调用现有的工作流执行方法
        // 这里需要根据实际的 ComfyUIService 接口来实现
        // TODO: 实现工作流提交逻辑
        // 这里需要根据实际的 ComfyUIService 接口来实现
        Ok("generated_prompt_id".to_string()) // 临时实现
    }

    async fn wait_for_completion(&self, prompt_id: &str, timeout: Duration) -> Result<HashMap<String, Vec<String>>> {
        // 实现等待逻辑
        let start_time = std::time::Instant::now();

        loop {
            if start_time.elapsed() > timeout {
                return Err(anyhow!("等待工作流完成超时"));
            }

            // 检查执行状态
            // 这里需要根据实际的 ComfyUIService 接口来实现
            tokio::time::sleep(Duration::from_secs(1)).await;

            // 临时返回空结果
            return Ok(HashMap::new());
        }
    }

    async fn get_queue_status(&self) -> Result<QueueStatusInfo> {
        // 获取队列状态
        // 这里需要根据实际的 ComfyUIService 接口来实现
        Ok(QueueStatusInfo {
            running: 0,
            pending: 0,
            from_sdk: false,
        })
    }

    async fn cancel_workflow(&self, _prompt_id: &str) -> Result<()> {
        // 取消工作流
        // 这里需要根据实际的 ComfyUIService 接口来实现
        Ok(())
    }

    async fn check_health(&self) -> Result<bool> {
        // 健康检查
        // 这里需要根据实际的 ComfyUIService 接口来实现
        Ok(true)
    }
}
