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

/// 工作流执行状态枚举
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum ExecutionStatus {
    /// 等待执行
    Pending,
    /// 正在执行
    Running,
    /// 执行完成
    Completed,
    /// 执行失败
    Failed,
    /// 已取消
    Cancelled,
    /// 超时
    Timeout,
}

impl std::fmt::Display for ExecutionStatus {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ExecutionStatus::Pending => write!(f, "pending"),
            ExecutionStatus::Running => write!(f, "running"),
            ExecutionStatus::Completed => write!(f, "completed"),
            ExecutionStatus::Failed => write!(f, "failed"),
            ExecutionStatus::Cancelled => write!(f, "cancelled"),
            ExecutionStatus::Timeout => write!(f, "timeout"),
        }
    }
}

impl From<String> for ExecutionStatus {
    fn from(s: String) -> Self {
        match s.as_str() {
            "pending" => ExecutionStatus::Pending,
            "running" => ExecutionStatus::Running,
            "completed" => ExecutionStatus::Completed,
            "failed" => ExecutionStatus::Failed,
            "cancelled" => ExecutionStatus::Cancelled,
            "timeout" => ExecutionStatus::Timeout,
            _ => ExecutionStatus::Pending,
        }
    }
}

/// 工作流执行记录数据模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkflowExecutionRecord {
    pub id: Option<i64>,
    
    // 工作流信息
    pub workflow_template_id: i64,
    pub workflow_name: String,
    pub workflow_version: String,
    
    // 执行环境信息
    pub execution_environment_id: Option<i64>,
    pub execution_environment_name: Option<String>,
    
    // 执行数据
    pub input_data_json: serde_json::Value,
    pub output_data_json: Option<serde_json::Value>,
    
    // 执行状态
    pub status: ExecutionStatus,
    pub progress: i32, // 0-100
    
    // ComfyUI相关
    pub comfyui_prompt_id: Option<String>,
    pub comfyui_workflow_name: Option<String>,
    
    // 时间信息
    pub started_at: Option<DateTime<Utc>>,
    pub completed_at: Option<DateTime<Utc>>,
    pub duration_seconds: Option<i32>,
    
    // 错误信息
    pub error_message: Option<String>,
    pub error_details_json: Option<serde_json::Value>,
    
    // 用户信息
    pub user_id: Option<String>,
    pub session_id: Option<String>,
    
    // 元数据
    pub metadata_json: Option<serde_json::Value>,
    pub tags: Option<Vec<String>>,
    
    // 时间戳
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// 创建执行记录请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateExecutionRecordRequest {
    pub workflow_template_id: i64,
    pub workflow_name: String,
    pub workflow_version: String,
    pub execution_environment_id: Option<i64>,
    pub execution_environment_name: Option<String>,
    pub input_data_json: serde_json::Value,
    pub user_id: Option<String>,
    pub session_id: Option<String>,
    pub metadata_json: Option<serde_json::Value>,
    pub tags: Option<Vec<String>>,
}

/// 更新执行记录请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateExecutionRecordRequest {
    pub status: Option<ExecutionStatus>,
    pub progress: Option<i32>,
    pub output_data_json: Option<serde_json::Value>,
    pub comfyui_prompt_id: Option<String>,
    pub comfyui_workflow_name: Option<String>,
    pub started_at: Option<DateTime<Utc>>,
    pub completed_at: Option<DateTime<Utc>>,
    pub error_message: Option<String>,
    pub error_details_json: Option<serde_json::Value>,
    pub metadata_json: Option<serde_json::Value>,
}

/// 执行记录查询过滤器
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ExecutionRecordFilter {
    pub workflow_template_id: Option<i64>,
    pub status: Option<ExecutionStatus>,
    pub user_id: Option<String>,
    pub session_id: Option<String>,
    pub comfyui_prompt_id: Option<String>,
    pub date_from: Option<DateTime<Utc>>,
    pub date_to: Option<DateTime<Utc>>,
}

/// 执行统计信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecutionStatistics {
    pub total_executions: i64,
    pub successful_executions: i64,
    pub failed_executions: i64,
    pub average_duration_seconds: Option<f64>,
    pub success_rate: f64,
    pub status_breakdown: HashMap<ExecutionStatus, i64>,
}

/// 错误详情
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorDetails {
    pub error_type: String,
    pub error_code: Option<String>,
    pub stack_trace: Option<String>,
    pub context: Option<HashMap<String, serde_json::Value>>,
    pub retry_count: Option<i32>,
    pub is_retryable: bool,
}

impl WorkflowExecutionRecord {
    /// 创建新的执行记录
    pub fn new(request: CreateExecutionRecordRequest) -> Self {
        let now = Utc::now();
        Self {
            id: None,
            workflow_template_id: request.workflow_template_id,
            workflow_name: request.workflow_name,
            workflow_version: request.workflow_version,
            execution_environment_id: request.execution_environment_id,
            execution_environment_name: request.execution_environment_name,
            input_data_json: request.input_data_json,
            output_data_json: None,
            status: ExecutionStatus::Pending,
            progress: 0,
            comfyui_prompt_id: None,
            comfyui_workflow_name: None,
            started_at: None,
            completed_at: None,
            duration_seconds: None,
            error_message: None,
            error_details_json: None,
            user_id: request.user_id,
            session_id: request.session_id,
            metadata_json: request.metadata_json,
            tags: request.tags,
            created_at: now,
            updated_at: now,
        }
    }

    /// 开始执行
    pub fn start_execution(&mut self) {
        self.status = ExecutionStatus::Running;
        self.started_at = Some(Utc::now());
        self.progress = 0;
        self.updated_at = Utc::now();
    }

    /// 完成执行
    pub fn complete_execution(&mut self, output_data: serde_json::Value) {
        self.status = ExecutionStatus::Completed;
        self.completed_at = Some(Utc::now());
        self.output_data_json = Some(output_data);
        self.progress = 100;
        self.updated_at = Utc::now();
        
        // 计算执行时长
        if let Some(started_at) = self.started_at {
            if let Some(completed_at) = self.completed_at {
                self.duration_seconds = Some((completed_at - started_at).num_seconds() as i32);
            }
        }
    }

    /// 标记执行失败
    pub fn fail_execution(&mut self, error_message: String, error_details: Option<ErrorDetails>) {
        self.status = ExecutionStatus::Failed;
        self.completed_at = Some(Utc::now());
        self.error_message = Some(error_message);
        self.updated_at = Utc::now();
        
        if let Some(details) = error_details {
            self.error_details_json = Some(serde_json::to_value(details).unwrap_or_default());
        }
        
        // 计算执行时长
        if let Some(started_at) = self.started_at {
            if let Some(completed_at) = self.completed_at {
                self.duration_seconds = Some((completed_at - started_at).num_seconds() as i32);
            }
        }
    }

    /// 取消执行
    pub fn cancel_execution(&mut self) {
        self.status = ExecutionStatus::Cancelled;
        self.completed_at = Some(Utc::now());
        self.updated_at = Utc::now();
        
        // 计算执行时长
        if let Some(started_at) = self.started_at {
            if let Some(completed_at) = self.completed_at {
                self.duration_seconds = Some((completed_at - started_at).num_seconds() as i32);
            }
        }
    }

    /// 更新进度
    pub fn update_progress(&mut self, progress: i32) {
        self.progress = progress.clamp(0, 100);
        self.updated_at = Utc::now();
    }

    /// 检查是否已完成（成功或失败）
    pub fn is_finished(&self) -> bool {
        matches!(
            self.status,
            ExecutionStatus::Completed | ExecutionStatus::Failed | ExecutionStatus::Cancelled | ExecutionStatus::Timeout
        )
    }

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

    /// 获取错误详情
    pub fn get_error_details(&self) -> Result<Option<ErrorDetails>, serde_json::Error> {
        match &self.error_details_json {
            Some(details) => Ok(Some(serde_json::from_value(details.clone())?)),
            None => Ok(None),
        }
    }
}
