//! Error types for the LiveSpeech SDK

use crate::types::ErrorCode;
use thiserror::Error;

/// Main error type for the LiveSpeech SDK
#[derive(Debug, Error)]
pub enum LiveSpeechError {
    /// Configuration error
    #[error("Configuration error: {0}")]
    Config(#[from] crate::types::ConfigError),

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

    /// WebSocket error
    #[error("WebSocket error: {0}")]
    WebSocket(#[from] tokio_tungstenite::tungstenite::Error),

    /// JSON serialization/deserialization error
    #[error("JSON error: {0}")]
    Json(#[from] serde_json::Error),

    /// URL parsing error
    #[error("URL error: {0}")]
    Url(#[from] url::ParseError),

    /// Not connected error
    #[error("Not connected")]
    NotConnected,

    /// Session not started error
    #[error("No active session")]
    NoActiveSession,

    /// Session already active error
    #[error("Session already active")]
    SessionAlreadyActive,

    /// Already streaming audio
    #[error("Already streaming")]
    AlreadyStreaming,

    /// Not streaming audio
    #[error("Not streaming")]
    NotStreaming,

    /// Session error from server
    #[error("Session error: {0}")]
    SessionError(String),

    /// Invalid parameter
    #[error("Invalid parameter: {0}")]
    InvalidParameter(String),

    /// Connection timeout
    #[error("Connection timeout")]
    ConnectionTimeout,

    /// Authentication failed
    #[error("Authentication failed: {0}")]
    AuthenticationFailed(String),

    /// Server error
    #[error("Server error ({code}): {message}")]
    ServerError { code: ErrorCode, message: String },

    /// Channel send error
    #[error("Channel send error")]
    ChannelSend,

    /// Channel receive error
    #[error("Channel receive error")]
    ChannelReceive,

    /// Reconnection failed
    #[error("Reconnection failed after {attempts} attempts")]
    ReconnectionFailed { attempts: u32 },
}

/// Result type alias for LiveSpeech operations
pub type Result<T> = std::result::Result<T, LiveSpeechError>;
