use chrono::{DateTime, Utc};
use thiserror::Error;

/// Market data repository errors
///
/// Comprehensive error types for market data operations including
/// database errors, validation failures, and data retrieval issues.
#[derive(Error, Debug)]
pub enum MarketDataError {
    /// Database operation error
    #[error("Database error: {0}")]
    Database(#[from] sqlx::Error),

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

    /// Invalid trading symbol provided
    #[error("Invalid symbol: {symbol}")]
    InvalidSymbol {
        /// The invalid symbol that was provided
        symbol: String,
    },

    /// Price data not found for the specified symbol
    #[error("Price not found for symbol: {symbol}")]
    PriceNotFound {
        /// The symbol for which price data was not found
        symbol: String,
    },

    /// Order book data not found for the specified symbol
    #[error("Order book not found for symbol: {symbol}")]
    OrderBookNotFound {
        /// The symbol for which order book data was not found
        symbol: String,
    },

    /// Technical indicator not found
    #[error("Indicator not found: {indicator_type} for symbol: {symbol}")]
    IndicatorNotFound {
        /// The type of indicator that was not found
        indicator_type: String,
        /// The symbol for which the indicator was not found
        symbol: String,
    },

    /// Invalid time range specified for data queries
    #[error("Invalid time range: from {from} to {to}")]
    InvalidTimeRange {
        /// Start time of the invalid range
        from: DateTime<Utc>,
        /// End time of the invalid range
        to: DateTime<Utc>,
    },

    /// Configuration-related error
    #[error("Configuration error: {0}")]
    Configuration(String),

    /// Database connection pool error
    #[error("Connection pool error: {0}")]
    ConnectionPool(String),

    /// Data validation error
    #[error("Data validation error: {0}")]
    Validation(String),
}

/// Result type alias for market data operations
///
/// Convenience type alias that uses `MarketDataError` as the error type.
///
/// This is used throughout the market data module for consistent error handling.
pub type MarketDataResult<T> = Result<T, MarketDataError>;
