use thiserror::Error;

/// 水印处理相关错误类型
/// 遵循 Tauri 开发规范的错误处理设计
#[derive(Debug, Error)]
pub enum WatermarkError {
    #[error("水印检测失败: {message}")]
    DetectionFailed { message: String },

    #[error("水印移除失败: {message}")]
    RemovalFailed { message: String },

    #[error("水印添加失败: {message}")]
    AdditionFailed { message: String },

    #[error("不支持的文件格式: {format}, 支持的格式: {supported:?}")]
    UnsupportedFormat { format: String, supported: Vec<String> },

    #[error("FFmpeg执行错误: {message}")]
    FFmpegError { message: String },

    #[error("OpenCV处理错误: {message}")]
    OpenCVError { message: String },

    #[error("模板不存在: {template_id}")]
    TemplateNotFound { template_id: String },

    #[error("模板名称已存在: {name}")]
    TemplateNameExists { name: String },

    #[error("无效的水印配置: {message}")]
    InvalidConfig { message: String },

    #[error("文件操作失败: {operation}, 路径: {path}, 错误: {message}")]
    FileOperationFailed {
        operation: String,
        path: String,
        message: String,
    },

    #[error("批量任务失败: {task_id}, 错误: {message}")]
    BatchTaskFailed { task_id: String, message: String },

    #[error("任务已取消: {task_id}")]
    TaskCancelled { task_id: String },

    #[error("任务超时: {task_id}, 超时时间: {timeout_ms}ms")]
    TaskTimeout { task_id: String, timeout_ms: u64 },

    #[error("数据库操作失败: {operation}, 错误: {message}")]
    DatabaseError { operation: String, message: String },

    #[error("网络请求失败: {url}, 错误: {message}")]
    NetworkError { url: String, message: String },

    #[error("权限不足: {operation}")]
    PermissionDenied { operation: String },

    #[error("资源不足: {resource}, 需要: {required}, 可用: {available}")]
    InsufficientResources {
        resource: String,
        required: String,
        available: String,
    },

    #[error("配置错误: {key}, 值: {value}, 错误: {message}")]
    ConfigurationError {
        key: String,
        value: String,
        message: String,
    },

    #[error("验证失败: {field}, 值: {value}, 原因: {reason}")]
    ValidationError {
        field: String,
        value: String,
        reason: String,
    },

    #[error("内部错误: {message}")]
    InternalError { message: String },

    #[error("外部依赖错误: {dependency}, 错误: {message}")]
    ExternalDependencyError { dependency: String, message: String },
}

impl WatermarkError {
    /// 创建检测失败错误
    pub fn detection_failed<S: Into<String>>(message: S) -> Self {
        Self::DetectionFailed {
            message: message.into(),
        }
    }

    /// 创建移除失败错误
    pub fn removal_failed<S: Into<String>>(message: S) -> Self {
        Self::RemovalFailed {
            message: message.into(),
        }
    }

    /// 创建添加失败错误
    pub fn addition_failed<S: Into<String>>(message: S) -> Self {
        Self::AdditionFailed {
            message: message.into(),
        }
    }

    /// 创建不支持格式错误
    pub fn unsupported_format<S: Into<String>>(format: S, supported: Vec<String>) -> Self {
        Self::UnsupportedFormat {
            format: format.into(),
            supported,
        }
    }

    /// 创建FFmpeg错误
    pub fn ffmpeg_error<S: Into<String>>(message: S) -> Self {
        Self::FFmpegError {
            message: message.into(),
        }
    }

    /// 创建OpenCV错误
    pub fn opencv_error<S: Into<String>>(message: S) -> Self {
        Self::OpenCVError {
            message: message.into(),
        }
    }

    /// 创建模板不存在错误
    pub fn template_not_found<S: Into<String>>(template_id: S) -> Self {
        Self::TemplateNotFound {
            template_id: template_id.into(),
        }
    }

    /// 创建模板名称已存在错误
    pub fn template_name_exists<S: Into<String>>(name: S) -> Self {
        Self::TemplateNameExists { name: name.into() }
    }

    /// 创建无效配置错误
    pub fn invalid_config<S: Into<String>>(message: S) -> Self {
        Self::InvalidConfig {
            message: message.into(),
        }
    }

    /// 创建文件操作失败错误
    pub fn file_operation_failed<S: Into<String>>(
        operation: S,
        path: S,
        message: S,
    ) -> Self {
        Self::FileOperationFailed {
            operation: operation.into(),
            path: path.into(),
            message: message.into(),
        }
    }

    /// 创建批量任务失败错误
    pub fn batch_task_failed<S: Into<String>>(task_id: S, message: S) -> Self {
        Self::BatchTaskFailed {
            task_id: task_id.into(),
            message: message.into(),
        }
    }

    /// 创建任务取消错误
    pub fn task_cancelled<S: Into<String>>(task_id: S) -> Self {
        Self::TaskCancelled {
            task_id: task_id.into(),
        }
    }

    /// 创建任务超时错误
    pub fn task_timeout<S: Into<String>>(task_id: S, timeout_ms: u64) -> Self {
        Self::TaskTimeout {
            task_id: task_id.into(),
            timeout_ms,
        }
    }

    /// 创建数据库错误
    pub fn database_error<S: Into<String>>(operation: S, message: S) -> Self {
        Self::DatabaseError {
            operation: operation.into(),
            message: message.into(),
        }
    }

    /// 创建网络错误
    pub fn network_error<S: Into<String>>(url: S, message: S) -> Self {
        Self::NetworkError {
            url: url.into(),
            message: message.into(),
        }
    }

    /// 创建权限不足错误
    pub fn permission_denied<S: Into<String>>(operation: S) -> Self {
        Self::PermissionDenied {
            operation: operation.into(),
        }
    }

    /// 创建资源不足错误
    pub fn insufficient_resources<S: Into<String>>(
        resource: S,
        required: S,
        available: S,
    ) -> Self {
        Self::InsufficientResources {
            resource: resource.into(),
            required: required.into(),
            available: available.into(),
        }
    }

    /// 创建配置错误
    pub fn configuration_error<S: Into<String>>(key: S, value: S, message: S) -> Self {
        Self::ConfigurationError {
            key: key.into(),
            value: value.into(),
            message: message.into(),
        }
    }

    /// 创建验证错误
    pub fn validation_error<S: Into<String>>(field: S, value: S, reason: S) -> Self {
        Self::ValidationError {
            field: field.into(),
            value: value.into(),
            reason: reason.into(),
        }
    }

    /// 创建内部错误
    pub fn internal_error<S: Into<String>>(message: S) -> Self {
        Self::InternalError {
            message: message.into(),
        }
    }

    /// 创建外部依赖错误
    pub fn external_dependency_error<S: Into<String>>(dependency: S, message: S) -> Self {
        Self::ExternalDependencyError {
            dependency: dependency.into(),
            message: message.into(),
        }
    }

    /// 获取错误类型
    pub fn error_type(&self) -> &'static str {
        match self {
            Self::DetectionFailed { .. } => "detection_failed",
            Self::RemovalFailed { .. } => "removal_failed",
            Self::AdditionFailed { .. } => "addition_failed",
            Self::UnsupportedFormat { .. } => "unsupported_format",
            Self::FFmpegError { .. } => "ffmpeg_error",
            Self::OpenCVError { .. } => "opencv_error",
            Self::TemplateNotFound { .. } => "template_not_found",
            Self::TemplateNameExists { .. } => "template_name_exists",
            Self::InvalidConfig { .. } => "invalid_config",
            Self::FileOperationFailed { .. } => "file_operation_failed",
            Self::BatchTaskFailed { .. } => "batch_task_failed",
            Self::TaskCancelled { .. } => "task_cancelled",
            Self::TaskTimeout { .. } => "task_timeout",
            Self::DatabaseError { .. } => "database_error",
            Self::NetworkError { .. } => "network_error",
            Self::PermissionDenied { .. } => "permission_denied",
            Self::InsufficientResources { .. } => "insufficient_resources",
            Self::ConfigurationError { .. } => "configuration_error",
            Self::ValidationError { .. } => "validation_error",
            Self::InternalError { .. } => "internal_error",
            Self::ExternalDependencyError { .. } => "external_dependency_error",
        }
    }

    /// 判断是否为可重试错误
    pub fn is_retryable(&self) -> bool {
        matches!(
            self,
            Self::NetworkError { .. }
                | Self::TaskTimeout { .. }
                | Self::InsufficientResources { .. }
                | Self::ExternalDependencyError { .. }
        )
    }

    /// 判断是否为用户错误
    pub fn is_user_error(&self) -> bool {
        matches!(
            self,
            Self::UnsupportedFormat { .. }
                | Self::TemplateNotFound { .. }
                | Self::TemplateNameExists { .. }
                | Self::InvalidConfig { .. }
                | Self::ValidationError { .. }
                | Self::PermissionDenied { .. }
        )
    }

    /// 判断是否为系统错误
    pub fn is_system_error(&self) -> bool {
        matches!(
            self,
            Self::FFmpegError { .. }
                | Self::OpenCVError { .. }
                | Self::FileOperationFailed { .. }
                | Self::DatabaseError { .. }
                | Self::InternalError { .. }
        )
    }

    /// 获取错误的严重程度
    pub fn severity(&self) -> ErrorSeverity {
        match self {
            Self::ValidationError { .. } | Self::InvalidConfig { .. } => ErrorSeverity::Warning,
            Self::TemplateNotFound { .. }
            | Self::TemplateNameExists { .. }
            | Self::UnsupportedFormat { .. }
            | Self::PermissionDenied { .. } => ErrorSeverity::Error,
            Self::DetectionFailed { .. }
            | Self::RemovalFailed { .. }
            | Self::AdditionFailed { .. }
            | Self::BatchTaskFailed { .. }
            | Self::TaskTimeout { .. } => ErrorSeverity::Error,
            Self::FFmpegError { .. }
            | Self::OpenCVError { .. }
            | Self::DatabaseError { .. }
            | Self::FileOperationFailed { .. }
            | Self::NetworkError { .. }
            | Self::InsufficientResources { .. }
            | Self::ExternalDependencyError { .. }
            | Self::InternalError { .. } => ErrorSeverity::Critical,
            Self::TaskCancelled { .. } => ErrorSeverity::Info,
            Self::ConfigurationError { .. } => ErrorSeverity::Warning,
        }
    }
}

/// 错误严重程度
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ErrorSeverity {
    Info,
    Warning,
    Error,
    Critical,
}

impl ErrorSeverity {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Info => "info",
            Self::Warning => "warning",
            Self::Error => "error",
            Self::Critical => "critical",
        }
    }
}

/// 错误上下文信息
#[derive(Debug, Clone)]
pub struct ErrorContext {
    pub operation: String,
    pub material_id: Option<String>,
    pub template_id: Option<String>,
    pub task_id: Option<String>,
    pub file_path: Option<String>,
    pub timestamp: chrono::DateTime<chrono::Utc>,
    pub additional_info: std::collections::HashMap<String, String>,
}

impl ErrorContext {
    pub fn new<S: Into<String>>(operation: S) -> Self {
        Self {
            operation: operation.into(),
            material_id: None,
            template_id: None,
            task_id: None,
            file_path: None,
            timestamp: chrono::Utc::now(),
            additional_info: std::collections::HashMap::new(),
        }
    }

    pub fn with_material_id<S: Into<String>>(mut self, material_id: S) -> Self {
        self.material_id = Some(material_id.into());
        self
    }

    pub fn with_template_id<S: Into<String>>(mut self, template_id: S) -> Self {
        self.template_id = Some(template_id.into());
        self
    }

    pub fn with_task_id<S: Into<String>>(mut self, task_id: S) -> Self {
        self.task_id = Some(task_id.into());
        self
    }

    pub fn with_file_path<S: Into<String>>(mut self, file_path: S) -> Self {
        self.file_path = Some(file_path.into());
        self
    }

    pub fn with_info<K: Into<String>, V: Into<String>>(mut self, key: K, value: V) -> Self {
        self.additional_info.insert(key.into(), value.into());
        self
    }
}

/// 水印错误结果类型
pub type WatermarkResult<T> = Result<T, WatermarkError>;

/// 从标准错误转换为水印错误
impl From<std::io::Error> for WatermarkError {
    fn from(err: std::io::Error) -> Self {
        Self::FileOperationFailed {
            operation: "io_operation".to_string(),
            path: "unknown".to_string(),
            message: err.to_string(),
        }
    }
}

impl From<rusqlite::Error> for WatermarkError {
    fn from(err: rusqlite::Error) -> Self {
        Self::DatabaseError {
            operation: "database_operation".to_string(),
            message: err.to_string(),
        }
    }
}

impl From<serde_json::Error> for WatermarkError {
    fn from(err: serde_json::Error) -> Self {
        Self::ConfigurationError {
            key: "json_config".to_string(),
            value: "unknown".to_string(),
            message: err.to_string(),
        }
    }
}

impl From<anyhow::Error> for WatermarkError {
    fn from(err: anyhow::Error) -> Self {
        Self::InternalError {
            message: err.to_string(),
        }
    }
}
