use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};

/// 穿搭照片生成记录
/// 遵循 Tauri 开发规范的数据模型设计原则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OutfitPhotoGeneration {
    /// 生成记录ID
    pub id: String,
    /// 项目ID
    pub project_id: String,
    /// 模特ID
    pub model_id: String,
    /// 商品图片路径
    pub product_image_path: String,
    /// 商品图片云端URL
    pub product_image_url: Option<String>,
    /// 提示词
    pub prompt: String,
    /// 负面提示词
    pub negative_prompt: Option<String>,
    /// 生成状态
    pub status: GenerationStatus,
    /// ComfyUI工作流ID
    pub workflow_id: Option<String>,
    /// ComfyUI提示ID
    pub comfyui_prompt_id: Option<String>,
    /// 生成结果图片路径列表
    pub result_image_paths: Vec<String>,
    /// 生成结果云端URL列表
    pub result_image_urls: Vec<String>,
    /// 错误信息
    pub error_message: Option<String>,
    /// 生成开始时间
    pub started_at: DateTime<Utc>,
    /// 生成完成时间
    pub completed_at: Option<DateTime<Utc>>,
    /// 生成耗时（毫秒）
    pub generation_time_ms: Option<u64>,
    /// 创建时间
    pub created_at: DateTime<Utc>,
    /// 更新时间
    pub updated_at: DateTime<Utc>,
}

/// 生成状态枚举
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum GenerationStatus {
    /// 等待中
    Pending,
    /// 处理中
    Processing,
    /// 已完成
    Completed,
    /// 失败
    Failed,
    /// 已取消
    Cancelled,
}

impl std::fmt::Display for GenerationStatus {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            GenerationStatus::Pending => write!(f, "等待中"),
            GenerationStatus::Processing => write!(f, "处理中"),
            GenerationStatus::Completed => write!(f, "已完成"),
            GenerationStatus::Failed => write!(f, "失败"),
            GenerationStatus::Cancelled => write!(f, "已取消"),
        }
    }
}

/// 穿搭照片生成请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OutfitPhotoGenerationRequest {
    /// 项目ID
    pub project_id: String,
    /// 模特ID
    pub model_id: String,
    /// 商品图片路径
    pub product_image_path: String,
    /// 提示词
    pub prompt: String,
    /// 负面提示词
    pub negative_prompt: Option<String>,
    /// 工作流配置
    pub workflow_config: Option<WorkflowConfig>,
}

/// 工作流配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkflowConfig {
    /// 工作流文件路径
    pub workflow_file_path: String,
    /// 生成步数
    pub steps: Option<u32>,
    /// CFG比例
    pub cfg_scale: Option<f32>,
    /// 种子值
    pub seed: Option<i64>,
    /// 采样器
    pub sampler: Option<String>,
    /// 调度器
    pub scheduler: Option<String>,
    /// 去噪强度
    pub denoise: Option<f32>,
}

/// 穿搭照片生成响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OutfitPhotoGenerationResponse {
    /// 生成记录ID
    pub id: String,
    /// 生成状态
    pub status: GenerationStatus,
    /// 生成结果图片URL列表
    pub result_image_urls: Vec<String>,
    /// 错误信息
    pub error_message: Option<String>,
    /// 生成耗时（毫秒）
    pub generation_time_ms: Option<u64>,
}

/// ComfyUI 工作流节点值替换配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkflowNodeReplacement {
    /// 节点ID
    pub node_id: String,
    /// 输入字段名
    pub input_field: String,
    /// 替换值
    pub value: serde_json::Value,
}

/// 节点映射配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeMapping {
    /// 目标节点ID
    pub node_id: String,
    /// 目标输入字段名
    pub input_field: String,
    /// 数据转换类型
    pub transform_type: Option<String>,
    /// 默认值（当UI字段为空时使用）
    pub default_value: Option<serde_json::Value>,
    /// 是否必需（如果UI字段为空且没有默认值，则报错）
    pub required: Option<bool>,
}

/// 工作流执行请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecuteWorkflowRequest {
    /// 工作流模板ID
    pub workflow_template_id: i64,
    /// 用户输入的表单数据
    pub input_data: serde_json::Value,
    /// 执行环境ID（可选）
    pub execution_environment_id: Option<i64>,
    /// 执行配置覆盖（可选）
    pub execution_config_override: Option<serde_json::Value>,
}

/// 工作流执行响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecuteWorkflowResponse {
    /// 执行记录ID
    pub execution_id: i64,
    /// 执行状态
    pub status: String,
    /// ComfyUI提示ID
    pub comfyui_prompt_id: Option<String>,
    /// 错误信息
    pub error_message: Option<String>,
}

/// ComfyUI 工作流执行进度
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkflowProgress {
    /// 当前步骤
    pub current_step: u32,
    /// 总步数
    pub total_steps: u32,
    /// 当前节点ID
    pub current_node_id: Option<String>,
    /// 进度百分比
    pub progress_percentage: f32,
    /// 状态消息
    pub status_message: String,
}

impl OutfitPhotoGeneration {
    /// 创建新的穿搭照片生成记录
    pub fn new(
        project_id: String,
        model_id: String,
        product_image_path: String,
        prompt: String,
    ) -> Self {
        let now = Utc::now();
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            project_id,
            model_id,
            product_image_path,
            product_image_url: None,
            prompt,
            negative_prompt: None,
            status: GenerationStatus::Pending,
            workflow_id: None,
            comfyui_prompt_id: None,
            result_image_paths: Vec::new(),
            result_image_urls: Vec::new(),
            error_message: None,
            started_at: now,
            completed_at: None,
            generation_time_ms: None,
            created_at: now,
            updated_at: now,
        }
    }

    /// 更新生成状态
    pub fn update_status(&mut self, status: GenerationStatus) {
        let is_final_status = status == GenerationStatus::Completed || status == GenerationStatus::Failed;
        self.status = status;
        self.updated_at = Utc::now();

        if is_final_status {
            self.completed_at = Some(Utc::now());
            if let Some(completed_at) = self.completed_at {
                self.generation_time_ms = Some(
                    (completed_at - self.started_at).num_milliseconds() as u64
                );
            }
        }
    }

    /// 设置错误信息
    pub fn set_error(&mut self, error_message: String) {
        self.error_message = Some(error_message);
        self.update_status(GenerationStatus::Failed);
    }

    /// 设置 ComfyUI prompt ID
    pub fn set_comfyui_prompt_id(&mut self, prompt_id: String) {
        self.comfyui_prompt_id = Some(prompt_id);
        self.updated_at = Utc::now();
    }

    /// 添加生成结果
    pub fn add_result(&mut self, image_path: String, image_url: Option<String>) {
        self.result_image_paths.push(image_path);
        if let Some(url) = image_url {
            self.result_image_urls.push(url);
        }
        self.updated_at = Utc::now();
    }

    /// 检查是否已完成
    pub fn is_completed(&self) -> bool {
        matches!(self.status, GenerationStatus::Completed | GenerationStatus::Failed | GenerationStatus::Cancelled)
    }

    /// 检查是否成功
    pub fn is_successful(&self) -> bool {
        self.status == GenerationStatus::Completed && !self.result_image_urls.is_empty()
    }
}

impl Default for WorkflowConfig {
    fn default() -> Self {
        Self {
            workflow_file_path: "换装-MidJourney.json".to_string(),
            steps: Some(20),
            cfg_scale: Some(7.0),
            seed: None, // 随机种子
            sampler: Some("euler".to_string()),
            scheduler: Some("normal".to_string()),
            denoise: Some(1.0),
        }
    }
}
