//! Bridge error types

use std::fmt;

/// Bridge error
#[derive(Debug)]
pub struct BridgeError {
    pub message: String,
    pub code: Option<String>,
    pub status_code: Option<u16>,
}

impl BridgeError {
    pub fn new(message: impl Into<String>) -> Self {
        Self {
            message: message.into(),
            code: None,
            status_code: None,
        }
    }

    pub fn with_code(mut self, code: impl Into<String>) -> Self {
        self.code = Some(code.into());
        self
    }

    pub fn with_status(mut self, status: u16) -> Self {
        self.status_code = Some(status);
        self
    }

    pub fn is_confirmations_pending(&self) -> bool {
        self.code.as_deref() == Some("CONFIRMATIONS_PENDING")
    }
}

impl fmt::Display for BridgeError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.message)
    }
}

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

impl From<reqwest::Error> for BridgeError {
    fn from(err: reqwest::Error) -> Self {
        Self::new(err.to_string())
    }
}

impl From<serde_json::Error> for BridgeError {
    fn from(err: serde_json::Error) -> Self {
        Self::new(err.to_string())
    }
}

/// Result type alias
pub type Result<T> = std::result::Result<T, BridgeError>;
