use thiserror::Error;

pub type Result<T> = std::result::Result<T, AppError>;

#[derive(Error, Debug)]
pub enum AppError {
    #[error("Configuration error: {0}")]
    Configuration(String),

    #[error("Message bus error: {0}")]
    MessageBus(#[from] async_nats::Error),

    #[error("Message bus publish error: {0}")]
    MessageBusPublish(#[from] async_nats::PublishError),

    #[error("Message bus subscribe error: {0}")]
    MessageBusSubscribe(String),

    #[error("Message bus connect error: {0}")]
    MessageBusConnect(String),

    #[error("HTTP request to another service failed: {0}")]
    ServiceRequest(#[from] reqwest::Error),

    #[error("Data parsing error: {0}")]
    DataParsing(#[from] anyhow::Error),

    #[error("Internal error: {0}")]
    Internal(String),
}

// 手动实现针对 async-nats 泛型错误类型的 From 转换
impl From<async_nats::error::Error<async_nats::ConnectErrorKind>> for AppError {
    fn from(err: async_nats::error::Error<async_nats::ConnectErrorKind>) -> Self {
        AppError::MessageBusConnect(err.to_string())
    }
}

impl From<async_nats::SubscribeError> for AppError {
    fn from(err: async_nats::SubscribeError) -> Self {
        AppError::MessageBusSubscribe(err.to_string())
    }
}
