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

/// 工作流系统错误类型
/// 提供详细的错误分类和上下文信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum WorkflowError {
    /// 数据库相关错误
    Database(DatabaseError),
    /// 工作流执行错误
    Execution(ExecutionError),
    /// 模板相关错误
    Template(TemplateError),
    /// 环境相关错误
    Environment(EnvironmentError),
    /// 网络相关错误
    Network(NetworkError),
    /// 文件系统错误
    FileSystem(FileSystemError),
    /// 验证错误
    Validation(ValidationError),
    /// 权限错误
    Permission(PermissionError),
    /// 配置错误
    Configuration(ConfigurationError),
    /// 系统错误
    System(SystemError),
}

/// 数据库错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseError {
    pub error_type: DatabaseErrorType,
    pub message: String,
    pub query: Option<String>,
    pub table: Option<String>,
    pub constraint: Option<String>,
    pub occurred_at: DateTime<Utc>,
}

/// 数据库错误类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DatabaseErrorType {
    ConnectionFailed,
    QueryFailed,
    TransactionFailed,
    ConstraintViolation,
    DataNotFound,
    DuplicateEntry,
    MigrationFailed,
    PoolExhausted,
    Timeout,
}

/// 工作流执行错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecutionError {
    pub error_type: ExecutionErrorType,
    pub message: String,
    pub execution_id: Option<i64>,
    pub template_id: Option<i64>,
    pub environment_id: Option<i64>,
    pub step: Option<String>,
    pub retry_count: u32,
    pub occurred_at: DateTime<Utc>,
}

/// 执行错误类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ExecutionErrorType {
    TemplateNotFound,
    EnvironmentUnavailable,
    InputValidationFailed,
    ExecutionTimeout,
    ResourceExhausted,
    ComfyUIError,
    OutputProcessingFailed,
    UnexpectedTermination,
}

/// 模板错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TemplateError {
    pub error_type: TemplateErrorType,
    pub message: String,
    pub template_id: Option<i64>,
    pub template_name: Option<String>,
    pub version: Option<String>,
    pub field: Option<String>,
    pub occurred_at: DateTime<Utc>,
}

/// 模板错误类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TemplateErrorType {
    InvalidFormat,
    MissingRequiredField,
    InvalidWorkflowJson,
    InvalidUIConfig,
    InvalidSchema,
    VersionConflict,
    ImportFailed,
    ExportFailed,
}

/// 环境错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnvironmentError {
    pub error_type: EnvironmentErrorType,
    pub message: String,
    pub environment_id: Option<i64>,
    pub environment_name: Option<String>,
    pub endpoint: Option<String>,
    pub occurred_at: DateTime<Utc>,
}

/// 环境错误类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EnvironmentErrorType {
    ConnectionFailed,
    HealthCheckFailed,
    AuthenticationFailed,
    ServiceUnavailable,
    ConfigurationInvalid,
    CapacityExceeded,
    VersionMismatch,
}

/// 网络错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkError {
    pub error_type: NetworkErrorType,
    pub message: String,
    pub url: Option<String>,
    pub status_code: Option<u16>,
    pub retry_count: u32,
    pub occurred_at: DateTime<Utc>,
}

/// 网络错误类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NetworkErrorType {
    ConnectionTimeout,
    RequestTimeout,
    ServerError,
    ClientError,
    NetworkUnreachable,
    DNSResolutionFailed,
    SSLError,
}

/// 文件系统错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileSystemError {
    pub error_type: FileSystemErrorType,
    pub message: String,
    pub path: Option<String>,
    pub operation: Option<String>,
    pub occurred_at: DateTime<Utc>,
}

/// 文件系统错误类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum FileSystemErrorType {
    FileNotFound,
    PermissionDenied,
    DiskFull,
    PathTooLong,
    InvalidPath,
    ReadFailed,
    WriteFailed,
    DeleteFailed,
}

/// 验证错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationError {
    pub message: String,
    pub field: Option<String>,
    pub value: Option<String>,
    pub constraint: Option<String>,
    pub occurred_at: DateTime<Utc>,
}

/// 权限错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PermissionError {
    pub message: String,
    pub user_id: Option<String>,
    pub resource: Option<String>,
    pub action: Option<String>,
    pub occurred_at: DateTime<Utc>,
}

/// 配置错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigurationError {
    pub message: String,
    pub config_key: Option<String>,
    pub config_value: Option<String>,
    pub occurred_at: DateTime<Utc>,
}

/// 系统错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemError {
    pub message: String,
    pub component: Option<String>,
    pub error_code: Option<String>,
    pub occurred_at: DateTime<Utc>,
}

/// 错误严重程度
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ErrorSeverity {
    Low,
    Medium,
    High,
    Critical,
}

/// 错误上下文
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorContext {
    pub user_id: Option<String>,
    pub session_id: Option<String>,
    pub request_id: Option<String>,
    pub operation: Option<String>,
    pub additional_data: Option<serde_json::Value>,
}

impl fmt::Display for WorkflowError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            WorkflowError::Database(err) => write!(f, "数据库错误: {}", err.message),
            WorkflowError::Execution(err) => write!(f, "执行错误: {}", err.message),
            WorkflowError::Template(err) => write!(f, "模板错误: {}", err.message),
            WorkflowError::Environment(err) => write!(f, "环境错误: {}", err.message),
            WorkflowError::Network(err) => write!(f, "网络错误: {}", err.message),
            WorkflowError::FileSystem(err) => write!(f, "文件系统错误: {}", err.message),
            WorkflowError::Validation(err) => write!(f, "验证错误: {}", err.message),
            WorkflowError::Permission(err) => write!(f, "权限错误: {}", err.message),
            WorkflowError::Configuration(err) => write!(f, "配置错误: {}", err.message),
            WorkflowError::System(err) => write!(f, "系统错误: {}", err.message),
        }
    }
}

impl std::error::Error for WorkflowError {}

impl WorkflowError {
    /// 获取错误严重程度
    pub fn severity(&self) -> ErrorSeverity {
        match self {
            WorkflowError::Database(err) => match err.error_type {
                DatabaseErrorType::ConnectionFailed | DatabaseErrorType::PoolExhausted => ErrorSeverity::Critical,
                DatabaseErrorType::TransactionFailed | DatabaseErrorType::MigrationFailed => ErrorSeverity::High,
                DatabaseErrorType::QueryFailed | DatabaseErrorType::Timeout => ErrorSeverity::Medium,
                _ => ErrorSeverity::Low,
            },
            WorkflowError::Execution(err) => match err.error_type {
                ExecutionErrorType::ResourceExhausted | ExecutionErrorType::UnexpectedTermination => ErrorSeverity::Critical,
                ExecutionErrorType::ExecutionTimeout | ExecutionErrorType::ComfyUIError => ErrorSeverity::High,
                ExecutionErrorType::InputValidationFailed => ErrorSeverity::Medium,
                _ => ErrorSeverity::Low,
            },
            WorkflowError::Environment(err) => match err.error_type {
                EnvironmentErrorType::ServiceUnavailable | EnvironmentErrorType::CapacityExceeded => ErrorSeverity::Critical,
                EnvironmentErrorType::ConnectionFailed | EnvironmentErrorType::HealthCheckFailed => ErrorSeverity::High,
                _ => ErrorSeverity::Medium,
            },
            WorkflowError::Network(err) => match err.error_type {
                NetworkErrorType::NetworkUnreachable | NetworkErrorType::DNSResolutionFailed => ErrorSeverity::High,
                NetworkErrorType::ConnectionTimeout | NetworkErrorType::RequestTimeout => ErrorSeverity::Medium,
                _ => ErrorSeverity::Low,
            },
            WorkflowError::FileSystem(err) => match err.error_type {
                FileSystemErrorType::DiskFull => ErrorSeverity::Critical,
                FileSystemErrorType::PermissionDenied => ErrorSeverity::High,
                _ => ErrorSeverity::Medium,
            },
            WorkflowError::Validation(_) => ErrorSeverity::Low,
            WorkflowError::Permission(_) => ErrorSeverity::High,
            WorkflowError::Configuration(_) => ErrorSeverity::Medium,
            WorkflowError::System(_) => ErrorSeverity::High,
            WorkflowError::Template(_) => ErrorSeverity::Medium,
        }
    }

    /// 检查错误是否可重试
    pub fn is_retryable(&self) -> bool {
        match self {
            WorkflowError::Database(err) => matches!(
                err.error_type,
                DatabaseErrorType::ConnectionFailed | DatabaseErrorType::Timeout | DatabaseErrorType::PoolExhausted
            ),
            WorkflowError::Execution(err) => matches!(
                err.error_type,
                ExecutionErrorType::EnvironmentUnavailable | ExecutionErrorType::ExecutionTimeout | ExecutionErrorType::ResourceExhausted
            ),
            WorkflowError::Environment(err) => matches!(
                err.error_type,
                EnvironmentErrorType::ConnectionFailed | EnvironmentErrorType::ServiceUnavailable
            ),
            WorkflowError::Network(err) => matches!(
                err.error_type,
                NetworkErrorType::ConnectionTimeout | NetworkErrorType::RequestTimeout | NetworkErrorType::ServerError
            ),
            WorkflowError::FileSystem(err) => matches!(
                err.error_type,
                FileSystemErrorType::ReadFailed | FileSystemErrorType::WriteFailed
            ),
            _ => false,
        }
    }

    /// 获取建议的重试延迟（秒）
    pub fn retry_delay_seconds(&self) -> u64 {
        match self.severity() {
            ErrorSeverity::Low => 1,
            ErrorSeverity::Medium => 5,
            ErrorSeverity::High => 30,
            ErrorSeverity::Critical => 300, // 5分钟
        }
    }
}
