//! 错误处理模块

use serde::Serialize;
use thiserror::Error;

/// 应用级错误类型
#[derive(Debug, Error)]
pub enum AppError {
    /// IO 错误
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

    /// 数据库错误
    #[error("Database error: {0}")]
    Database(#[from] rusqlite::Error),

    /// 序列化错误
    #[error("Serialization error: {0}")]
    Serialization(#[from] serde_json::Error),

    /// TLS 错误
    #[error("TLS error: {0}")]
    Tls(String),

    /// WebSocket 错误
    #[error("WebSocket error: {0}")]
    WebSocket(String),

    /// 网络错误
    #[error("Network error: {0}")]
    Network(String),

    /// 文件传输错误
    #[error("File transfer error: {0}")]
    FileTransfer(String),

    /// 设备未找到
    #[error("Device not found: {0}")]
    DeviceNotFound(String),

    /// 连接错误
    #[error("Connection error: {0}")]
    Connection(String),

    /// 配置错误
    #[error("Configuration error: {0}")]
    Config(String),

    /// 通用错误
    #[error("{0}")]
    General(String),
}

/// Tauri 命令返回的错误包装
/// 实现 Serialize 以便在前端使用
#[derive(Debug, Serialize)]
pub struct CommandError {
    /// 错误代码
    pub code: String,
    /// 错误消息
    pub message: String,
}

impl From<AppError> for CommandError {
    fn from(err: AppError) -> Self {
        let (code, message) = match &err {
            AppError::Io(_) => ("IO_ERROR", err.to_string()),
            AppError::Database(_) => ("DB_ERROR", err.to_string()),
            AppError::Serialization(_) => ("SERIALIZATION_ERROR", err.to_string()),
            AppError::Tls(_) => ("TLS_ERROR", err.to_string()),
            AppError::WebSocket(_) => ("WS_ERROR", err.to_string()),
            AppError::Network(_) => ("NETWORK_ERROR", err.to_string()),
            AppError::FileTransfer(_) => ("FILE_TRANSFER_ERROR", err.to_string()),
            AppError::DeviceNotFound(_) => ("DEVICE_NOT_FOUND", err.to_string()),
            AppError::Connection(_) => ("CONNECTION_ERROR", err.to_string()),
            AppError::Config(_) => ("CONFIG_ERROR", err.to_string()),
            AppError::General(_) => ("GENERAL_ERROR", err.to_string()),
        };
        Self {
            code: code.to_string(),
            message,
        }
    }
}

impl From<std::io::Error> for CommandError {
    fn from(err: std::io::Error) -> Self {
        AppError::Io(err).into()
    }
}

impl From<rusqlite::Error> for CommandError {
    fn from(err: rusqlite::Error) -> Self {
        AppError::Database(err).into()
    }
}

impl From<serde_json::Error> for CommandError {
    fn from(err: serde_json::Error) -> Self {
        AppError::Serialization(err).into()
    }
}

/// Tauri 命令返回类型
pub type CommandResult<T> = Result<T, CommandError>;
