use anyhow::{anyhow, Result};
use tracing::{debug, info};
use serde_json::{Value, Map};
use regex::Regex;

use crate::data::models::outfit_photo_generation::{
    ExecuteWorkflowRequest, ExecuteWorkflowResponse, NodeMapping, WorkflowNodeReplacement
};
use crate::data::models::workflow_template::{WorkflowTemplate, WorkflowType};
use crate::data::models::workflow_execution_record::{
    CreateExecutionRecordRequest, WorkflowExecutionRecord
};
use crate::business::services::comfyui_service::ComfyUIService;
use crate::data::repositories::workflow_template_repository::WorkflowTemplateRepository;
use crate::data::repositories::workflow_execution_record_repository::WorkflowExecutionRecordRepository;

/// 工作流执行服务
/// 负责处理基于映射配置的工作流执行逻辑
pub struct WorkflowExecutionService {
    comfyui_service: ComfyUIService,
}

impl WorkflowExecutionService {
    /// 创建新的工作流执行服务实例
    pub fn new(comfyui_service: ComfyUIService) -> Self {
        Self {
            comfyui_service,
        }
    }

    /// 执行工作流
    pub async fn execute_workflow(
        &self,
        request: ExecuteWorkflowRequest,
        workflow_template_repo: &WorkflowTemplateRepository,
        execution_record_repo: &WorkflowExecutionRecordRepository,
    ) -> Result<ExecuteWorkflowResponse> {
        info!("开始执行工作流，模板ID: {}", request.workflow_template_id);

        // 1. 获取工作流模板
        let template = workflow_template_repo
            .find_by_id(request.workflow_template_id)?
            .ok_or_else(|| anyhow!("工作流模板不存在: {}", request.workflow_template_id))?;

        // 2. 验证输入数据
        self.validate_input_data(&template, &request.input_data)?;

        // 3. 创建执行记录
        let execution_record = self.create_execution_record(
            &template,
            &request,
            execution_record_repo,
        ).await?;

        // 4. 生成节点替换配置
        let replacements = self.generate_node_replacements(&template, &request.input_data)?;

        // 5. 替换工作流节点
        let updated_workflow = self.comfyui_service.replace_workflow_nodes(
            template.comfyui_workflow_json.clone(),
            replacements,
        )?;

        // 6. 提交到ComfyUI
        let prompt_id = self.comfyui_service.submit_workflow(updated_workflow).await?;

        // 7. 更新执行记录
        self.update_execution_record_with_prompt_id(
            execution_record.id.unwrap(),
            &prompt_id,
            execution_record_repo,
        ).await?;

        Ok(ExecuteWorkflowResponse {
            execution_id: execution_record.id.unwrap(),
            status: "running".to_string(),
            comfyui_prompt_id: Some(prompt_id),
            error_message: None,
        })
    }

    /// 验证输入数据
    fn validate_input_data(&self, template: &WorkflowTemplate, input_data: &Value) -> Result<()> {
        debug!("验证输入数据");

        // 获取UI配置
        let ui_config = template.get_ui_config()
            .map_err(|e| anyhow!("解析UI配置失败，请检查工作流模板的UI配置: {}", e))?;

        // 检查输入数据格式
        let input_obj = input_data.as_object()
            .ok_or_else(|| anyhow!("输入数据必须是JSON对象格式"))?;

        let mut validation_errors = Vec::new();

        // 检查必填字段和数据类型
        for field in &ui_config.form_fields {
            let field_value = input_obj.get(&field.name);

            // 检查必填字段
            if field.required {
                if field_value.is_none() || field_value.unwrap().is_null() {
                    validation_errors.push(format!("必填字段 '{}' 不能为空", field.label));
                    continue;
                }
            }

            // 如果字段有值，进行类型和格式验证
            if let Some(value) = field_value {
                if !value.is_null() {
                    match field.field_type {
                        crate::data::models::workflow_template::UIFieldType::Number |
                        crate::data::models::workflow_template::UIFieldType::Slider => {
                            if !value.is_number() {
                                validation_errors.push(format!("字段 '{}' 必须是数字类型", field.label));
                            } else {
                                let num_value = value.as_f64().unwrap();
                                if let Some(min) = field.min {
                                    if num_value < min {
                                        validation_errors.push(format!("字段 '{}' 的值不能小于 {}", field.label, min));
                                    }
                                }
                                if let Some(max) = field.max {
                                    if num_value > max {
                                        validation_errors.push(format!("字段 '{}' 的值不能大于 {}", field.label, max));
                                    }
                                }
                            }
                        }
                        crate::data::models::workflow_template::UIFieldType::Checkbox => {
                            if !value.is_boolean() {
                                validation_errors.push(format!("字段 '{}' 必须是布尔类型", field.label));
                            }
                        }
                        crate::data::models::workflow_template::UIFieldType::Select => {
                            if let Some(options) = &field.options {
                                let str_value = value.as_str().unwrap_or("");
                                if !options.contains(&str_value.to_string()) {
                                    validation_errors.push(format!("字段 '{}' 的值必须是以下选项之一: {}", field.label, options.join(", ")));
                                }
                            }
                        }
                        _ => {
                            // 对于文本类型字段，检查正则表达式
                            if let Some(validation) = &field.validation {
                                if let Some(pattern) = validation.get("pattern").and_then(|p| p.as_str()) {
                                    let str_value = value.as_str().unwrap_or("");
                                    if let Ok(regex) = Regex::new(pattern) {
                                        if !regex.is_match(str_value) {
                                            validation_errors.push(format!("字段 '{}' 的格式不正确", field.label));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        if !validation_errors.is_empty() {
            return Err(anyhow!("输入数据验证失败:\n{}", validation_errors.join("\n")));
        }

        Ok(())
    }

    /// 创建执行记录
    async fn create_execution_record(
        &self,
        template: &WorkflowTemplate,
        request: &ExecuteWorkflowRequest,
        execution_record_repo: &WorkflowExecutionRecordRepository,
    ) -> Result<WorkflowExecutionRecord> {
        let create_request = CreateExecutionRecordRequest {
            workflow_template_id: template.id.unwrap(),
            workflow_name: template.name.clone(),
            workflow_version: template.version.clone(),
            execution_environment_id: request.execution_environment_id,
            execution_environment_name: None,
            input_data_json: request.input_data.clone(),
            user_id: None,
            session_id: None,
            metadata_json: None,
            tags: None,
        };

        let record = WorkflowExecutionRecord::new(create_request);
        let execution_id = execution_record_repo.create(&record)?;
        let record = execution_record_repo.find_by_id(execution_id)?
            .ok_or_else(|| anyhow!("创建的执行记录未找到"))?;

        info!("创建执行记录成功，ID: {}", execution_id);
        Ok(record)
    }

    /// 生成节点替换配置
    fn generate_node_replacements(
        &self,
        template: &WorkflowTemplate,
        input_data: &Value,
    ) -> Result<Vec<WorkflowNodeReplacement>> {
        debug!("生成节点替换配置");

        let replacements = Vec::new();

        // 获取UI配置
        let _ui_config = template.get_ui_config()
            .map_err(|e| anyhow!("解析UI配置失败: {}", e))?;

        // 获取输入数据对象
        let _input_obj = input_data.as_object()
            .ok_or_else(|| anyhow!("输入数据必须是对象格式"))?;

        // TODO: 遍历每个UI字段，生成对应的节点替换
        // 暂时跳过node_mapping，因为UIField结构中还没有这个字段
        // 需要在UIField中添加node_mapping字段

        info!("生成了 {} 个节点替换配置", replacements.len());
        Ok(replacements)
    }

    /// 获取字段值并进行类型转换
    fn get_field_value(
        &self,
        field: &crate::data::models::workflow_template::UIField,
        input_obj: &Map<String, Value>,
        node_mapping: &NodeMapping,
    ) -> Result<Option<Value>> {
        // 获取原始值
        let raw_value = input_obj.get(&field.name);

        // 如果字段为空，检查是否有默认值
        let value = match raw_value {
            Some(v) if !v.is_null() => v.clone(),
            _ => {
                if let Some(default) = &node_mapping.default_value {
                    default.clone()
                } else if node_mapping.required.unwrap_or(false) {
                    return Err(anyhow!("必需字段 '{}' 没有值且没有默认值", field.label));
                } else {
                    return Ok(None);
                }
            }
        };

        // 根据转换类型进行数据转换
        let transformed_value = match node_mapping.transform_type.as_deref() {
            Some("string") => Value::String(value.to_string()),
            Some("number") => {
                if let Some(num) = value.as_f64() {
                    Value::Number(serde_json::Number::from_f64(num).unwrap())
                } else {
                    return Err(anyhow!("字段 '{}' 无法转换为数字", field.label));
                }
            }
            Some("boolean") => Value::Bool(value.as_bool().unwrap_or(false)),
            Some("array") => {
                if value.is_array() {
                    value
                } else {
                    Value::Array(vec![value])
                }
            }
            Some("file_url") => {
                // 处理文件上传字段，转换为CDN URL
                let url_str = value.as_str()
                    .ok_or_else(|| anyhow!("文件URL必须是字符串格式"))?;
                // TODO: 实现文件URL转换逻辑
                Value::String(url_str.to_string())
            }
            _ => value, // 默认不转换
        };

        Ok(Some(transformed_value))
    }

    /// 更新执行记录的ComfyUI提示ID
    async fn update_execution_record_with_prompt_id(
        &self,
        execution_id: i64,
        prompt_id: &str,
        _execution_record_repo: &WorkflowExecutionRecordRepository,
    ) -> Result<()> {
        // 这里需要实现更新执行记录的逻辑
        // 由于当前的repository可能没有这个方法，我们先记录日志
        info!("执行记录 {} 的ComfyUI提示ID: {}", execution_id, prompt_id);
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;
    use chrono::Utc;
    use crate::data::models::workflow_template::WorkflowType;

    fn create_test_template() -> WorkflowTemplate {
        WorkflowTemplate {
            id: Some(1),
            name: "测试工作流".to_string(),
            base_name: "test_workflow".to_string(),
            version: "1.0".to_string(),
            workflow_type: WorkflowType::Custom("test_workflow".to_string()),
            description: Some("测试用工作流模板".to_string()),
            comfyui_workflow_json: json!({
                "1": {
                    "class_type": "LoadImage",
                    "inputs": {
                        "image_url": "default.jpg"
                    }
                }
            }),
            ui_config_json: json!({
                "form_fields": [
                    {
                        "name": "image_input",
                        "field_type": "image_upload",
                        "label": "输入图片",
                        "required": true
                    }
                ]
            }),
            execution_config_json: None,
            input_schema_json: None,
            output_schema_json: None,
            is_active: true,
            is_published: false,
            tags: None,
            category: None,
            author: None,
            created_at: Utc::now(),
            updated_at: Utc::now(),
        }
    }

    #[test]
    fn test_validate_input_data_success() {
        let comfyui_settings = crate::config::ComfyUISettings::default();
        let comfyui_service = ComfyUIService::new(comfyui_settings);
        let service = WorkflowExecutionService::new(comfyui_service);
        let template = create_test_template();

        let input_data = json!({
            "image_input": "test.jpg"
        });

        let result = service.validate_input_data(&template, &input_data);
        assert!(result.is_ok());
    }

    #[test]
    fn test_validate_input_data_missing_required_field() {
        let comfyui_settings = crate::config::ComfyUISettings::default();
        let comfyui_service = ComfyUIService::new(comfyui_settings);
        let service = WorkflowExecutionService::new(comfyui_service);
        let template = create_test_template();

        let input_data = json!({
            // 缺少必填的 image_input
        });

        let result = service.validate_input_data(&template, &input_data);
        assert!(result.is_err());
        assert!(result.unwrap_err().to_string().contains("必填字段"));
    }
}
