//! 错误处理模块
//!
//! 定义了应用中用到的所有错误类型,支持错误链追踪和上下文信息

use std::sync::Arc;
use thiserror::Error;

/// 应用统一错误类型
///
/// 这个枚举涵盖了应用可能遇到的各种错误情况
/// 使用 thiserror 提供结构化的错误处理和错误链追踪功能
#[derive(Error, Debug)]
pub enum AppError {
    /// WebSocket相关错误
    #[error("WebSocket错误: {message}")]
    WebSocket {
        message: String,
        #[source]
        source: Option<Arc<dyn std::error::Error + Send + Sync>>,
    },

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

    /// IO错误
    #[error("IO错误: {0}")]
    Io(#[from] std::io::Error),

    /// 网络错误
    #[error("网络错误: {message}")]
    Network {
        message: String,
        #[source]
        source: Option<Arc<dyn std::error::Error + Send + Sync>>,
    },

    /// 窗口错误
    #[error("窗口错误: {message}")]
    Window {
        message: String,
        #[source]
        source: Option<Arc<dyn std::error::Error + Send + Sync>>,
    },

    /// 音频错误
    #[error("音频错误: {message}")]
    Audio {
        message: String,
        #[source]
        source: Option<Arc<dyn std::error::Error + Send + Sync>>,
    },

    /// 存储错误
    #[error("存储错误: {message}")]
    Storage {
        message: String,
        #[source]
        source: Option<Arc<dyn std::error::Error + Send + Sync>>,
    },

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

    /// 未找到错误
    #[error("未找到: {0}")]
    NotFound(String),

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

    /// 超时错误
    #[error("操作超时: {0}")]
    Timeout(String),

    /// 取消错误
    #[error("操作已取消: {0}")]
    Canceled(String),

    /// 其他错误
    #[error("错误: {message}")]
    Other {
        message: String,
        #[source]
        source: Option<Arc<dyn std::error::Error + Send + Sync>>,
    },
}

impl AppError {
    /// 创建一个 WebSocket 错误
    pub fn websocket<M: Into<String>>(message: M) -> Self {
        AppError::WebSocket {
            message: message.into(),
            source: None,
        }
    }

    /// 创建一个带原始错误的 WebSocket 错误
    pub fn websocket_with_source<M, E>(message: M, source: E) -> Self
    where
        M: Into<String>,
        E: std::error::Error + Send + Sync + 'static,
    {
        AppError::WebSocket {
            message: message.into(),
            source: Some(Arc::new(source)),
        }
    }

    /// 创建一个网络错误
    pub fn network<M: Into<String>>(message: M) -> Self {
        AppError::Network {
            message: message.into(),
            source: None,
        }
    }

    /// 创建一个带原始错误的网络错误
    pub fn network_with_source<M, E>(message: M, source: E) -> Self
    where
        M: Into<String>,
        E: std::error::Error + Send + Sync + 'static,
    {
        AppError::Network {
            message: message.into(),
            source: Some(Arc::new(source)),
        }
    }

    /// 创建一个窗口错误
    pub fn window<M: Into<String>>(message: M) -> Self {
        AppError::Window {
            message: message.into(),
            source: None,
        }
    }

    /// 创建一个音频错误
    pub fn audio<M: Into<String>>(message: M) -> Self {
        AppError::Audio {
            message: message.into(),
            source: None,
        }
    }

    /// 创建一个存储错误
    pub fn storage<M: Into<String>>(message: M) -> Self {
        AppError::Storage {
            message: message.into(),
            source: None,
        }
    }

    /// 创建一个验证错误
    pub fn validation<M: Into<String>>(message: M) -> Self {
        AppError::Validation(message.into())
    }

    /// 创建一个未找到错误
    pub fn not_found<M: Into<String>>(message: M) -> Self {
        AppError::NotFound(message.into())
    }

    /// 创建一个状态错误
    pub fn invalid_state<M: Into<String>>(message: M) -> Self {
        AppError::InvalidState(message.into())
    }

    /// 创建一个超时错误
    pub fn timeout<M: Into<String>>(message: M) -> Self {
        AppError::Timeout(message.into())
    }

    /// 创建一个取消错误
    pub fn canceled<M: Into<String>>(message: M) -> Self {
        AppError::Canceled(message.into())
    }

    /// 创建一个通用错误
    pub fn other<M: Into<String>>(message: M) -> Self {
        AppError::Other {
            message: message.into(),
            source: None,
        }
    }

    /// 给错误添加额外的上下文信息
    pub fn context<M: Into<String>>(self, message: M) -> Self {
        let msg = format!("{}: {}", message.into(), &self);
        match self {
            AppError::WebSocket { .. } => AppError::websocket(msg),
            AppError::Network { .. } => AppError::network(msg),
            AppError::Window { .. } => AppError::window(msg),
            AppError::Audio { .. } => AppError::audio(msg),
            AppError::Storage { .. } => AppError::storage(msg),
            _ => AppError::other(msg),
        }
    }
}

/// 把 AppError 转换成字符串
/// 主要用于 Tauri 命令返回值
impl From<AppError> for String {
    fn from(error: AppError) -> Self {
        error.to_string()
    }
}

/// 从字符串创建 AppError
/// 为了兼容旧代码保留这个转换
impl From<String> for AppError {
    fn from(message: String) -> Self {
        AppError::other(message)
    }
}

/// 从字符串切片创建 AppError
/// 为了兼容旧代码保留这个转换
impl From<&str> for AppError {
    fn from(message: &str) -> Self {
        AppError::other(message.to_string())
    }
}


