//! # Common Provider Types
//!
//! Shared data structures and enumerations used across different market data providers
//! in the Foxhunt HFT trading system. This module provides:
//!
//! - **News Events**: Breaking news, earnings, analyst ratings
//! - **Sentiment Analysis**: Market sentiment scores and trends
//! - **Options Activity**: Unusual options flow and block trades
//! - **Error Classification**: Standardized error categorization
//!
//! ## Provider Integration
//!
//! These types serve as a bridge between provider-specific APIs and the unified
//! `ExtendedMarketDataEvent` system, allowing consistent handling of alternative
//! data sources alongside traditional market data.
//!
//! ## Usage
//!
//! ```rust
//! use data::providers::common::{NewsEvent, SentimentEvent, AnalystRatingEvent};
//! use data::types::ExtendedMarketDataEvent;
//!
//! // Convert provider-specific events to extended events
//! let news_event = ExtendedMarketDataEvent::NewsAlert(news_event);
//! let sentiment_event = ExtendedMarketDataEvent::SentimentUpdate(sentiment_event);
//! ```

use ::common::{Price, Quantity, Symbol};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

/// Error category classification for provider-specific errors.
///
/// Standardizes error types across different data providers to enable
/// consistent error handling and recovery strategies in the trading system.
/// Each category has specific implications for reconnection logic and alerting.
///
/// # Error Recovery Strategies
///
/// - **Connection**: Implement exponential backoff reconnection
/// - **Authentication**: Refresh tokens or credentials, alert operations
/// - **RateLimit**: Implement adaptive throttling and request queuing
/// - **DataFormat**: Log for debugging, potentially skip malformed messages
/// - **Internal**: Restart provider connection, escalate to monitoring
/// - **Unknown**: Treat as transient, implement general retry logic
///
/// # Examples
///
/// ```rust
/// use data::providers::common::ProviderErrorCategory;
///
/// match error_category {
///     ProviderErrorCategory::RateLimit => {
///         // Implement exponential backoff
///         tokio::time::sleep(Duration::from_millis(1000)).await;
///     },
///     ProviderErrorCategory::Authentication => {
///         // Refresh credentials and reconnect
///         provider.refresh_auth().await?;
///     },
///     _ => {
///         // General error handling
///     }
/// }
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ProviderErrorCategory {
    /// Network connectivity issues, WebSocket disconnections
    ///
    /// Indicates problems with the underlying network connection to the
    /// data provider. Recovery strategy should include exponential backoff
    /// reconnection attempts and connection health monitoring.
    Connection,

    /// API key invalid, token expired, permission denied
    ///
    /// Authentication or authorization failures that require credential
    /// refresh or manual intervention. These errors should trigger
    /// immediate alerts to operations teams.
    Authentication,

    /// API rate limits exceeded, quota exhausted
    ///
    /// Provider is throttling requests due to rate limit violations.
    /// Recovery should implement adaptive request throttling and
    /// request queuing with appropriate delays.
    RateLimit,

    /// Malformed data, parsing errors, schema mismatches
    ///
    /// Indicates problems with data format or structure that prevent
    /// proper parsing. These should be logged for debugging but may
    /// not require immediate reconnection.
    DataFormat,

    /// Provider-side internal errors, service unavailable
    ///
    /// Errors originating from the data provider's infrastructure.
    /// Recovery strategy should include service status checks and
    /// potential failover to alternative providers.
    Internal,

    /// Unclassified or unexpected errors
    ///
    /// Default category for errors that don't fit other classifications.
    /// Should be treated conservatively with general retry logic.
    Unknown,
}

/// Classification of news event types for filtering and priority routing.
///
/// Categorizes news events by their nature and potential market impact,
/// allowing trading algorithms to apply different processing logic based
/// on event type. Each type has different latency requirements and
/// impact characteristics.
///
/// # Market Impact
///
/// - **Earnings**: High impact, quarterly/annual reporting cycles
/// - **Rating**: Medium to high impact, analyst opinion changes
/// - **Economic**: Market-wide impact, affects multiple sectors
/// - **CorporateAction**: Company-specific, varies by action type
/// - **News**: General news, impact depends on content
///
/// # Usage in Trading
///
/// ```rust
/// use data::providers::common::NewsEventType;
///
/// match event.event_type {
///     NewsEventType::Earnings => {
///         // High priority processing for earnings events
///         priority_queue.push_high(event);
///     },
///     NewsEventType::Rating => {
///         // Analyst rating changes - medium priority
///         priority_queue.push_medium(event);
///     },
///     _ => {
///         // Standard processing
///         standard_queue.push(event);
///     }
/// }
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum NewsEventType {
    /// General news articles and press releases
    ///
    /// Broad category covering company announcements, industry news,
    /// regulatory updates, and other general market information.
    /// Impact varies widely based on content.
    News,

    /// Earnings announcements, financial results, guidance updates
    ///
    /// Quarterly and annual earnings reports, revenue guidance,
    /// earnings per share announcements. These events typically
    /// have high market impact and require immediate processing.
    Earnings,

    /// Analyst upgrades, downgrades, price target changes
    ///
    /// Research analyst opinion changes including rating upgrades/downgrades,
    /// price target adjustments, and initiation of coverage. Can significantly
    /// impact stock price in the short term.
    Rating,

    /// Economic indicators, Federal Reserve announcements, policy changes
    ///
    /// Macroeconomic events that affect broader market conditions,
    /// including GDP data, inflation reports, interest rate decisions,
    /// and monetary policy announcements.
    Economic,

    /// Mergers, acquisitions, dividends, stock splits, spin-offs
    ///
    /// Corporate structure changes that directly affect stock mechanics
    /// and ownership. Includes M&A announcements, dividend declarations,
    /// stock splits, and other corporate reorganizations.
    CorporateAction,
}

/// News event data structure containing breaking news and market-moving information.
///
/// Represents real-time news events from providers like Benzinga that can impact
/// trading decisions. Contains both the news content and metadata for automated
/// processing and sentiment analysis.
///
/// # Field Categories
///
/// - **Identification**: `story_id`, `source`, `url`
/// - **Content**: `headline`, `content`, `summary`
/// - **Classification**: `category`, `tags`, `event_type`
/// - **Impact Assessment**: `impact_score`, `importance`, `sentiment_score`
/// - **Timing**: `timestamp`, `published_at`
/// - **Symbols**: `symbol`, `symbols` (affected securities)
///
/// # Processing Pipeline
///
/// ```text
/// News Event → Sentiment Analysis → Symbol Extraction → Impact Scoring → Trading Signal
/// ```
///
/// # Examples
///
/// ```rust
/// use data::providers::common::{NewsEvent, NewsEventType};
/// use common::Symbol;
///
/// let news = NewsEvent {
///     symbol: Some(Symbol::from("AAPL")),
///     symbols: vec![Symbol::from("AAPL")],
///     story_id: "BZ123456".to_string(),
///     headline: "Apple Reports Strong Q3 Earnings".to_string(),
///     event_type: NewsEventType::Earnings,
///     impact_score: Some(0.85), // High impact
///     // ... other fields
/// };
///
/// // Check if this is a high-impact earnings event
/// if news.event_type == NewsEventType::Earnings &&
///    news.impact_score.unwrap_or(0.0) > 0.8 {
///     // Process as priority event
/// }
/// ```
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NewsEvent {
    /// Primary symbol affected by this news (if applicable)
    ///
    /// The main security ticker that this news event relates to.
    /// May be `None` for market-wide or sector-wide news.
    pub symbol: Option<Symbol>,

    /// All symbols mentioned or affected by this news
    ///
    /// Complete list of securities that may be impacted by this news event.
    /// Includes the primary symbol plus any additional mentioned tickers.
    pub symbols: Vec<Symbol>,

    /// Unique identifier for this news story
    ///
    /// Provider-specific ID used for deduplication and reference.
    /// Format varies by provider (e.g., Benzinga: "BZ123456").
    pub story_id: String,

    /// News headline or title
    ///
    /// Brief summary of the news event, typically optimized for
    /// algorithmic parsing and sentiment analysis.
    pub headline: String,

    /// Full news article content
    ///
    /// Complete text of the news article. May be truncated for
    /// performance reasons in high-frequency scenarios.
    pub content: String,

    /// Executive summary or abstract
    ///
    /// Condensed version of the news content highlighting key points.
    /// Useful for quick algorithmic processing without parsing full content.
    pub summary: String,

    /// News category classification
    ///
    /// Provider-specific category string (e.g., "Earnings", "M&A", "Analyst").
    /// Used for filtering and routing to appropriate processing pipelines.
    pub category: String,

    /// Associated tags and keywords
    ///
    /// List of relevant tags that help categorize and filter the news.
    /// Examples: ["earnings", "beat", "revenue", "guidance"].
    pub tags: Vec<String>,

    /// Algorithmic impact score (0.0 to 1.0)
    ///
    /// Machine-generated assessment of potential market impact.
    /// Higher scores indicate greater expected price movement.
    /// `None` if impact scoring is not available.
    pub impact_score: Option<f64>,

    /// News importance rating (0.0 to 1.0)
    ///
    /// Editorial or algorithmic assessment of news significance.
    /// Different from impact_score - measures newsworthiness rather
    /// than expected price impact.
    pub importance: f64,

    /// Article author or reporter
    ///
    /// Journalist or analyst who authored the news piece.
    /// Can be used for author-based filtering or credibility weighting.
    pub author: String,

    /// Event processing timestamp (when received by our system)
    ///
    /// When this news event was received and processed by the
    /// Foxhunt system. Used for latency analysis and sequencing.
    pub timestamp: DateTime<Utc>,

    /// Original publication timestamp
    ///
    /// When the news was originally published by the news source.
    /// May differ from `timestamp` due to processing delays.
    pub published_at: DateTime<Utc>,

    /// News source identifier
    ///
    /// Name of the news organization or wire service that published
    /// this story (e.g., "Reuters", "PR Newswire", "Benzinga").
    pub source: String,

    /// Link to the full article
    ///
    /// URL where the complete news article can be accessed.
    /// Useful for manual review and audit trails.
    pub url: String,

    /// Overall sentiment score (-1.0 to 1.0)
    ///
    /// Algorithmic sentiment analysis of the news content.
    /// Positive values indicate bullish sentiment, negative values
    /// indicate bearish sentiment. `None` if sentiment analysis unavailable.
    pub sentiment_score: Option<f64>,

    /// Legacy sentiment field (deprecated)
    ///
    /// Maintained for backwards compatibility. New code should use
    /// `sentiment_score` instead. May be removed in future versions.
    #[deprecated(since = "1.0.0", note = "Use sentiment_score instead")]
    pub sentiment: Option<f64>,

    /// Classification of the news event type
    ///
    /// Structured categorization for automated processing and filtering.
    /// Determines processing priority and routing logic.
    pub event_type: NewsEventType,
}

/// Market sentiment analysis event containing aggregated sentiment metrics.
///
/// Represents sentiment analysis data from providers like Benzinga that aggregate
/// sentiment from various sources including news articles, social media, and
/// analyst reports. Used for incorporating market mood into trading decisions.
///
/// # Sentiment Interpretation
///
/// - **sentiment_score > 0.6**: Strong bullish sentiment
/// - **sentiment_score 0.4-0.6**: Moderate bullish sentiment  
/// - **sentiment_score 0.4-0.6**: Neutral sentiment
/// - **sentiment_score 0.2-0.4**: Moderate bearish sentiment
/// - **sentiment_score < 0.2**: Strong bearish sentiment
///
/// # Confidence Assessment
///
/// The `confidence` field indicates the reliability of the sentiment analysis:
/// - **confidence > 0.8**: High confidence, large sample size
/// - **confidence 0.5-0.8**: Moderate confidence
/// - **confidence < 0.5**: Low confidence, small sample or conflicting signals
///
/// # Usage in Trading
///
/// ```rust
/// use data::providers::common::SentimentEvent;
///
/// fn assess_sentiment_signal(sentiment: &SentimentEvent) -> Option<f64> {
///     if sentiment.confidence > 0.7 && sentiment.sample_size > 100 {
///         // High confidence signal
///         Some(sentiment.sentiment_score * sentiment.confidence)
///     } else {
///         // Low confidence, ignore signal
///         None
///     }
/// }
/// ```
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SentimentEvent {
    /// Symbol this sentiment analysis applies to
    ///
    /// The specific security ticker for which sentiment has been analyzed.
    pub symbol: Symbol,

    /// Overall sentiment score (0.0 = very bearish, 1.0 = very bullish)
    ///
    /// Normalized sentiment metric where:
    /// - 0.0-0.3: Bearish sentiment
    /// - 0.3-0.7: Neutral sentiment
    /// - 0.7-1.0: Bullish sentiment
    pub sentiment_score: f64,

    /// Ratio of bullish mentions (0.0 to 1.0)
    ///
    /// Percentage of analyzed content that expressed bullish sentiment.
    /// `bullish_ratio + bearish_ratio` may not equal 1.0 due to neutral content.
    pub bullish_ratio: f64,

    /// Ratio of bearish mentions (0.0 to 1.0)
    ///
    /// Percentage of analyzed content that expressed bearish sentiment.
    /// Complement to `bullish_ratio` but may not sum to 1.0.
    pub bearish_ratio: f64,

    /// Number of data points used in sentiment calculation
    ///
    /// Size of the sample used for sentiment analysis. Larger sample
    /// sizes generally indicate more reliable sentiment scores.
    pub sample_size: u32,

    /// Data sources used for sentiment analysis
    ///
    /// List of sources that contributed to this sentiment calculation
    /// (e.g., ["twitter", "reddit", "news", "analyst_reports"]).
    pub sources: Vec<String>,

    /// Confidence level in the sentiment analysis (0.0 to 1.0)
    ///
    /// Statistical confidence in the sentiment score based on:
    /// - Sample size
    /// - Source diversity
    /// - Consistency across sources
    /// - Time-based stability
    pub confidence: f64,

    /// Time period this sentiment analysis covers
    ///
    /// Indicates whether this is real-time sentiment or aggregated
    /// over a specific time window (hourly, daily, etc.).
    pub period: SentimentPeriod,

    /// When this sentiment analysis was generated
    ///
    /// Timestamp when the sentiment calculation was completed.
    /// Important for time-series analysis and sentiment trends.
    pub timestamp: DateTime<Utc>,

    /// Provider that generated this sentiment analysis
    ///
    /// Name of the sentiment analysis provider (e.g., "Benzinga", "StockTwits").
    pub source: String,
}

/// Time period classification for sentiment analysis aggregation.
///
/// Defines the time window over which sentiment data has been aggregated.
/// Different periods serve different use cases in trading strategies:
///
/// - **Real-time**: Immediate sentiment for breaking news response
/// - **Minute-level**: Short-term sentiment shifts for scalping strategies  
/// - **Hourly**: Intraday sentiment trends for day trading
/// - **Daily**: Medium-term sentiment for swing trading
/// - **Weekly**: Long-term sentiment for position strategies
///
/// # Trading Applications
///
/// ```rust
/// use data::providers::common::{SentimentEvent, SentimentPeriod};
///
/// fn route_sentiment_event(event: &SentimentEvent) {
///     match event.period {
///         SentimentPeriod::RealTime => {
///             // Route to high-frequency trading algorithms
///             hft_processor.process(event);
///         },
///         SentimentPeriod::Daily => {
///             // Route to swing trading strategies
///             swing_processor.process(event);
///         },
///         _ => {
///             // Route to appropriate time-based processor
///         }
///     }
/// }
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum SentimentPeriod {
    /// Real-time sentiment analysis (streaming)
    ///
    /// Immediate sentiment calculated from live data feeds.
    /// Minimal aggregation, highest frequency updates.
    RealTime,

    /// 1-minute aggregated sentiment
    ///
    /// Sentiment aggregated over 1-minute windows.
    /// Suitable for high-frequency trading strategies.
    Minute1,

    /// 5-minute aggregated sentiment
    ///
    /// Sentiment aggregated over 5-minute windows.
    /// Balances responsiveness with noise reduction.
    Minute5,

    /// 15-minute aggregated sentiment
    ///
    /// Sentiment aggregated over 15-minute windows.
    /// Good for short-term trend identification.
    Minute15,

    /// 1-hour aggregated sentiment
    ///
    /// Sentiment aggregated over 1-hour windows.
    /// Smooths out short-term noise while maintaining responsiveness.
    Hour1,

    /// Hourly sentiment (alias for Hour1)
    ///
    /// Alternative naming for 1-hour aggregation.
    /// Maintained for backwards compatibility.
    Hourly,

    /// 1-day aggregated sentiment
    ///
    /// Sentiment aggregated over daily windows.
    /// Suitable for swing trading and position strategies.
    Day1,

    /// Daily sentiment (alias for Day1)
    ///
    /// Alternative naming for daily aggregation.
    /// Maintained for backwards compatibility.
    Daily,

    /// Weekly aggregated sentiment
    ///
    /// Sentiment aggregated over weekly windows.
    /// Long-term sentiment trends for position trading.
    Weekly,
}

/// Analyst rating change event from sell-side research firms.
///
/// Represents analyst upgrades, downgrades, price target changes, and coverage
/// initiations from research analysts. These events can significantly impact
/// stock prices and are closely watched by institutional and retail investors.
///
/// # Rating Actions
///
/// - **Upgrade**: Analyst raises rating (e.g., Hold → Buy)
/// - **Downgrade**: Analyst lowers rating (e.g., Buy → Hold)  
/// - **Initiate**: Analyst begins coverage with initial rating
/// - **Maintain**: Analyst reaffirms existing rating (often with price target change)
///
/// # Price Target Impact
///
/// Price target changes can be more impactful than rating changes:
/// - Large price target increases often drive immediate buying
/// - Price target cuts can trigger selling even without rating downgrades
/// - Multiple analysts changing targets in same direction amplifies impact
///
/// # Usage in Trading
///
/// ```rust
/// use data::providers::common::{AnalystRatingEvent, RatingAction};
///
/// fn assess_rating_impact(rating: &AnalystRatingEvent) -> f64 {
///     let base_impact = match rating.action {
///         RatingAction::Upgrade => 0.05,   // +5% expected impact
///         RatingAction::Downgrade => -0.05, // -5% expected impact
///         RatingAction::Initiate => 0.02,   // +2% expected impact
///         _ => 0.0,
///     };
///     
///     // Adjust for price target changes
///     if let (Some(current), Some(previous)) = (rating.price_target, rating.previous_price_target) {
///         let pt_change = (current - previous) / previous;
///         base_impact + pt_change * 0.3 // Price target changes have 30% weight
///     } else {
///         base_impact
///     }
/// }
/// ```
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalystRatingEvent {
    /// Symbol being rated by the analyst
    ///
    /// The security ticker that this rating change applies to.
    pub symbol: Symbol,

    /// Type of rating action taken
    ///
    /// Classification of what the analyst did (upgrade, downgrade, initiate, etc.).
    /// Determines the expected market reaction and processing priority.
    pub action: RatingAction,

    /// Current rating string
    ///
    /// The new rating assigned by the analyst. Format varies by firm
    /// (e.g., "Buy", "Outperform", "Strong Buy", "1" (numeric scale)).
    pub rating: String,

    /// Current rating after this change (normalized)
    ///
    /// Standardized version of the current rating for easier comparison
    /// across different firms' rating systems.
    pub current_rating: String,

    /// Previous rating before this change (normalized)
    ///
    /// Standardized version of the previous rating, allowing calculation
    /// of rating change magnitude and direction.
    pub previous_rating: String,

    /// New price target set by the analyst
    ///
    /// Target price the analyst expects the stock to reach over their
    /// forecast horizon (typically 12 months). `None` if no price target provided.
    pub price_target: Option<Price>,

    /// Previous price target before this change
    ///
    /// Allows calculation of price target change percentage and magnitude.
    /// `None` if this is the first price target or previous target unavailable.
    pub previous_price_target: Option<Price>,

    /// Analyst commentary or research note summary
    ///
    /// Optional text explanation of the rating change rationale.
    /// May contain key points from the research report.
    pub comment: Option<String>,

    /// Date when the rating was published
    ///
    /// Original publication date of the analyst report or rating change.
    /// May differ from `timestamp` due to processing delays.
    pub rating_date: DateTime<Utc>,

    /// Name of the analyst who issued the rating
    ///
    /// Individual analyst name for tracking analyst performance and
    /// implementing analyst-specific weightings.
    pub analyst: String,

    /// Research firm or investment bank name
    ///
    /// Name of the institution employing the analyst (e.g., "Goldman Sachs",
    /// "Morgan Stanley"). Used for firm-based credibility weighting.
    pub firm: String,

    /// When this rating event was processed by our system
    ///
    /// Timestamp when the rating change was received and processed
    /// by the Foxhunt system. Used for latency analysis.
    pub timestamp: DateTime<Utc>,
}

/// Type of action taken by an analyst on a stock rating.
///
/// Classifies the nature of analyst rating changes for automated processing
/// and impact assessment. Each action type has different implications for
/// expected price movement and market reaction.
///
/// # Market Impact Rankings (typical)
///
/// 1. **Upgrade**: Highest positive impact
/// 2. **Initiate**: Moderate positive impact (new coverage)
/// 3. **Maintain**: Low impact (reaffirmation)
/// 4. **Downgrade**: High negative impact
/// 5. **Suspend**: Moderate negative impact (uncertainty)
/// 6. **Discontinue**: Low impact (loss of coverage)
///
/// # Processing Priorities
///
/// - **Upgrade/Downgrade**: Immediate processing, high priority alerts
/// - **Initiate**: Medium priority, good for discovery of new opportunities
/// - **Maintain**: Low priority unless significant price target change
/// - **Suspend/Discontinue**: Medium priority, may indicate issues
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum RatingAction {
    /// Analyst raised the rating (e.g., Hold → Buy)
    ///
    /// Positive rating change indicating improved outlook.
    /// Typically drives immediate buying pressure and positive price movement.
    Upgrade,

    /// Analyst lowered the rating (e.g., Buy → Hold)
    ///
    /// Negative rating change indicating deteriorated outlook.
    /// Often triggers selling pressure and negative price movement.
    Downgrade,

    /// Analyst initiated coverage with new rating
    ///
    /// First-time coverage of a stock by this analyst/firm.
    /// Can increase visibility and trading volume for the security.
    Initiate,

    /// Analyst reaffirmed existing rating
    ///
    /// No rating change but often accompanied by updated price targets
    /// or commentary. Lower impact than upgrades/downgrades.
    Maintain,

    /// Analyst temporarily suspended rating
    ///
    /// Rating removed due to pending corporate actions, lack of information,
    /// or other temporary factors. Creates uncertainty.
    Suspend,

    /// Analyst permanently discontinued coverage
    ///
    /// Analyst no longer following the stock. May indicate reduced
    /// institutional interest or resource reallocation.
    Discontinue,
}

impl std::fmt::Display for RatingAction {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            RatingAction::Upgrade => write!(f, "Upgrade"),
            RatingAction::Downgrade => write!(f, "Downgrade"),
            RatingAction::Initiate => write!(f, "Initiate"),
            RatingAction::Maintain => write!(f, "Maintain"),
            RatingAction::Suspend => write!(f, "Suspend"),
            RatingAction::Discontinue => write!(f, "Discontinue"),
        }
    }
}

/// Unusual options activity event indicating potential informed trading.
///
/// Represents detection of abnormal options trading patterns that may signal
/// informed trading ahead of corporate events, earnings, or other catalysts.
/// These events are valuable for identifying potential price movements before
/// they occur in the underlying stock.
///
/// # Types of Unusual Activity
///
/// - **Block Trades**: Large single transactions indicating institutional activity
/// - **Sweeps**: Aggressive orders that sweep through multiple price levels
/// - **Volume Spikes**: Unusually high volume compared to historical averages
/// - **High Open Interest**: Large number of contracts relative to normal activity
///
/// # Trading Applications
///
/// ```rust
/// use data::providers::common::{UnusualOptionsEvent, UnusualOptionsType, OptionsSentiment};
///
/// fn assess_options_signal(event: &UnusualOptionsEvent) -> Option<f64> {
///     // High confidence signals
///     if event.confidence > 0.8 {
///         match (event.unusual_type, event.sentiment) {
///             (UnusualOptionsType::Block, OptionsSentiment::Bullish) => Some(0.75),
///             (UnusualOptionsType::Sweep, OptionsSentiment::Bearish) => Some(-0.60),
///             _ => Some(0.25), // Lower weight for other combinations
///         }
///     } else {
///         None // Low confidence, ignore signal
///     }
/// }
/// ```
///
/// # Risk Considerations
///
/// - Options activity can be hedging rather than directional betting
/// - High implied volatility may indicate uncertainty rather than conviction
/// - Time decay affects options differently than stocks
/// - Consider underlying stock liquidity when interpreting signals
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnusualOptionsEvent {
    /// Underlying stock symbol
    ///
    /// The stock ticker for which unusual options activity was detected.
    pub symbol: Symbol,

    /// Specific options contract details
    ///
    /// Complete specification of the options contract including strike price,
    /// expiration date, and option type (call/put).
    pub contract: OptionsContract,

    /// Type of unusual activity detected
    ///
    /// Classification of what made this options activity unusual
    /// (block trade, sweep, volume spike, etc.).
    pub unusual_type: UnusualOptionsType,

    /// Alternative classification for activity type
    ///
    /// Secondary classification that may provide additional context.
    /// Often duplicates `unusual_type` but may offer different perspective.
    pub activity_type: UnusualOptionsType,

    /// Total volume of options contracts traded
    ///
    /// Number of options contracts involved in the unusual activity.
    /// Compare to average daily volume to assess significance.
    pub volume: Quantity,

    /// Current open interest for this contract
    ///
    /// Total number of outstanding contracts. High volume relative
    /// to open interest suggests new position opening.
    pub open_interest: Quantity,

    /// Total premium paid for the options
    ///
    /// Dollar amount spent on the options trade. Higher premiums
    /// suggest greater conviction or larger position sizes.
    pub premium: Option<Price>,

    /// Implied volatility of the options contract
    ///
    /// Market's expectation of future volatility implied by option prices.
    /// Sudden IV spikes may indicate upcoming news or events.
    pub implied_volatility: Option<f64>,

    /// Directional sentiment inferred from the activity
    ///
    /// Whether the unusual activity suggests bullish, bearish, or
    /// neutral expectations for the underlying stock.
    pub sentiment: OptionsSentiment,

    /// Confidence level in the unusual activity detection (0.0 to 1.0)
    ///
    /// Algorithmic confidence that this activity is truly unusual
    /// and not random market noise. Higher values indicate stronger signals.
    pub confidence: f64,

    /// Human-readable description of the unusual activity
    ///
    /// Textual explanation of what made this activity unusual,
    /// suitable for alerts and reporting.
    pub description: String,

    /// When this unusual activity was detected
    ///
    /// Timestamp when the unusual options activity was identified
    /// and processed by the detection system.
    pub timestamp: DateTime<Utc>,
}

/// Options contract specification with complete contract details.
///
/// Defines all parameters necessary to uniquely identify an options contract.
/// Used within unusual options events to specify exactly which contract
/// exhibited unusual activity.
///
/// # Contract Identification
///
/// Options contracts are uniquely identified by:
/// - Underlying symbol
/// - Expiration date
/// - Strike price  
/// - Option type (call/put)
///
/// # Examples
///
/// ```rust
/// use data::providers::common::{OptionsContract, OptionsType};
/// use common::{Symbol, Price};
/// use chrono::{Utc, Duration};
///
/// // AAPL $150 Call expiring in 30 days
/// let contract = OptionsContract {
///     symbol: Symbol::from("AAPL"),
///     expiry: Utc::now() + Duration::days(30),
///     expiration: Utc::now() + Duration::days(30),
///     strike: Price::from(150.0),
///     option_type: OptionsType::Call,
///     multiplier: 100, // Standard equity option multiplier
/// };
/// ```
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OptionsContract {
    /// Underlying stock symbol
    ///
    /// The stock ticker that this options contract is based on.
    pub symbol: Symbol,

    /// Contract expiration date (primary field)
    ///
    /// Date when the options contract expires and becomes worthless if unexercised.
    /// This is the canonical expiration field.
    pub expiry: DateTime<Utc>,

    /// Contract expiration date (alias for backwards compatibility)
    ///
    /// Duplicate of `expiry` field maintained for backwards compatibility.
    /// New code should use `expiry` instead.
    #[deprecated(since = "1.0.0", note = "Use expiry instead")]
    pub expiration: DateTime<Utc>,

    /// Strike price of the options contract
    ///
    /// The price at which the option can be exercised to buy (call) or sell (put)
    /// the underlying stock.
    pub strike: Price,

    /// Type of option (call or put)
    ///
    /// - Call: Right to buy the underlying at the strike price
    /// - Put: Right to sell the underlying at the strike price
    pub option_type: OptionsType,

    /// Contract multiplier (typically 100 for equity options)
    ///
    /// Number of shares controlled by one options contract.
    /// Standard equity options control 100 shares per contract.
    pub multiplier: u32,
}

/// Type of options contract (call or put).
///
/// Defines the rights granted by an options contract:
///
/// - **Call Options**: Right to buy the underlying asset at the strike price
/// - **Put Options**: Right to sell the underlying asset at the strike price
///
/// # Market Sentiment Implications
///
/// - **Call Buying**: Generally bullish (expecting price increase)
/// - **Put Buying**: Generally bearish (expecting price decrease)
/// - **Call Selling**: Neutral to bearish (collecting premium)
/// - **Put Selling**: Neutral to bullish (collecting premium)
///
/// # Examples
///
/// ```rust
/// use data::providers::common::OptionsType;
///
/// // Assess directional bias from options type
/// match option_type {
///     OptionsType::Call => {
///         // Buyer expects stock to rise above strike + premium
///         println!("Bullish bias detected");
///     },
///     OptionsType::Put => {
///         // Buyer expects stock to fall below strike - premium
///         println!("Bearish bias detected");
///     }
/// }
/// ```
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum OptionsType {
    /// Call option - right to buy the underlying asset
    ///
    /// Grants the holder the right (but not obligation) to purchase
    /// the underlying stock at the strike price before expiration.
    /// Profitable when stock price > strike + premium paid.
    Call,

    /// Put option - right to sell the underlying asset
    ///
    /// Grants the holder the right (but not obligation) to sell
    /// the underlying stock at the strike price before expiration.
    /// Profitable when stock price < strike - premium paid.
    Put,
}

/// Sentiment classification derived from options trading activity.
///
/// Algorithmic assessment of the directional bias implied by unusual
/// options activity. Takes into account option type, trading patterns,
/// and market context to infer trader sentiment.
///
/// # Sentiment Determination Factors
///
/// - **Option Type**: Calls generally bullish, puts generally bearish
/// - **Buy vs Sell**: Aggressive buying more significant than selling
/// - **Strike Price**: In-the-money vs out-of-the-money implications
/// - **Time to Expiration**: Near-term options suggest immediate expectations
/// - **Volume Profile**: Large blocks suggest institutional conviction
///
/// # Usage in Signal Generation
///
/// ```rust
/// use data::providers::common::{OptionsSentiment, UnusualOptionsEvent};
///
/// fn weight_options_signal(event: &UnusualOptionsEvent) -> f64 {
///     let base_weight = match event.sentiment {
///         OptionsSentiment::Bullish => 1.0,
///         OptionsSentiment::Bearish => -1.0,
///         OptionsSentiment::Neutral => 0.0,
///     };
///     
///     // Adjust based on confidence and premium
///     base_weight * event.confidence *
///         event.premium.map(|p| p.min(1000000.0) / 1000000.0).unwrap_or(0.5)
/// }
/// ```
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum OptionsSentiment {
    /// Positive sentiment - expecting stock price to rise
    ///
    /// Unusual activity suggests traders expect the underlying
    /// stock to increase in value. Typically associated with:
    /// - Heavy call buying
    /// - Put selling
    /// - Low strike calls or high strike puts
    Bullish,

    /// Negative sentiment - expecting stock price to fall
    ///
    /// Unusual activity suggests traders expect the underlying
    /// stock to decrease in value. Typically associated with:
    /// - Heavy put buying
    /// - Call selling
    /// - High strike puts or low strike calls
    Bearish,

    /// Neutral sentiment - no clear directional bias
    ///
    /// Unusual activity doesn't indicate clear directional expectations.
    /// May suggest:
    /// - Volatility plays (straddles/strangles)
    /// - Hedging activity
    /// - Arbitrage strategies
    /// - Unclear or mixed signals
    Neutral,
}

/// Classification of unusual options activity patterns.
///
/// Categorizes the specific type of unusual trading behavior detected
/// in options markets. Each type has different implications for market
/// sentiment and potential price movements in the underlying stock.
///
/// # Activity Type Significance
///
/// **High Impact:**
/// - `Block`: Large institutional trades, often informed
/// - `Sweep`: Aggressive market orders suggesting urgency
///
/// **Medium Impact:**
/// - `VolumeSpike`: Sudden interest, check for news catalysts
/// - `VolatilitySpike`: Expectation of significant price movement
///
/// **Lower Impact:**
/// - `HighVolume`/`HighOpenInterest`: Sustained interest over time
/// - `Split`: Large order broken into pieces, less urgent
///
/// # Detection Thresholds
///
/// Each type has specific detection criteria:
/// - Volume thresholds relative to historical averages
/// - Open interest comparisons
/// - Price and volatility change requirements
/// - Time-based clustering analysis
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum UnusualOptionsType {
    /// Large block trade executed as single transaction
    ///
    /// Large institutional-sized trade executed at once, typically indicating
    /// informed trading by sophisticated market participants. High significance.
    Block,

    /// Aggressive order sweeping through multiple price levels
    ///
    /// Market order that aggressively takes liquidity across multiple bid/ask
    /// levels, suggesting urgency and strong conviction. Very high significance.
    Sweep,

    /// Large order split into smaller pieces
    ///
    /// Detection of coordinated smaller trades that appear to be part of
    /// a larger strategy. Lower urgency than blocks but still significant.
    Split,

    /// Volume significantly above historical average
    ///
    /// Trading volume for this contract is unusually high compared to
    /// recent historical patterns. Medium significance.
    HighVolume,

    /// Open interest unusually high for this contract
    ///
    /// Number of outstanding contracts is abnormally high, suggesting
    /// sustained institutional interest. Medium significance.
    HighOpenInterest,

    /// Alternative classification for block trades
    ///
    /// Alias for `Block` to handle different provider naming conventions.
    /// Represents the same type of large institutional trade.
    BlockTrade,

    /// Sudden spike in trading volume
    ///
    /// Rapid increase in volume over a short time period, often associated
    /// with breaking news or imminent announcements. High significance.
    VolumeSpike,

    /// Rapid increase in open interest
    ///
    /// Quick buildup of new positions in this contract, suggesting
    /// institutional accumulation. Medium to high significance.
    OpenInterestSpike,

    /// Implied volatility increase indicating expected price movement
    ///
    /// Market pricing in higher expected volatility, often preceding
    /// earnings or major announcements. High significance for timing.
    VolatilitySpike,
}

/// Order book price level change for Level 2 market data updates.
///
/// Represents a change to a specific price level in the order book,
/// including additions, updates, or deletions of orders at that price.
/// Used for maintaining real-time order book state in high-frequency
/// trading systems.
///
/// # Order Book Mechanics
///
/// - **Add**: New orders added to a price level
/// - **Update**: Existing price level quantity modified (usually reduced due to fills)
/// - **Delete**: Price level completely removed (all orders filled or cancelled)
///
/// # Usage in Order Book Reconstruction
///
/// ```rust
/// use data::providers::common::{PriceLevelChange, PriceLevelChangeType, OrderBookSide};
/// use std::collections::BTreeMap;
/// use common::Price;
///
/// fn apply_level_change(order_book: &mut BTreeMap<Price, f64>, change: &PriceLevelChange) {
///     match change.change_type {
///         PriceLevelChangeType::Add | PriceLevelChangeType::Update => {
///             order_book.insert(change.price, change.quantity.into());
///         },
///         PriceLevelChangeType::Delete => {
///             order_book.remove(&change.price);
///         }
///     }
/// }
/// ```
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PriceLevelChange {
    /// Price level being modified
    ///
    /// The specific price at which the order book change occurred.
    pub price: Price,

    /// New quantity at this price level
    ///
    /// - For Add/Update: The new total quantity at this price
    /// - For Delete: Typically 0 (price level removed)
    pub quantity: Quantity,

    /// Type of change applied to this price level
    ///
    /// Indicates whether this is an addition, update, or deletion
    /// of orders at the specified price level.
    pub change_type: PriceLevelChangeType,

    /// Which side of the order book (bid or ask)
    ///
    /// Specifies whether this change affects the buy side (bids)
    /// or sell side (asks) of the order book.
    pub side: OrderBookSide,
}

/// Type of change applied to an order book price level.
///
/// Classifies the nature of order book modifications for proper
/// reconstruction and analysis of market depth changes.
///
/// # Change Semantics
///
/// - **Add**: New price level created with initial quantity
/// - **Update**: Existing price level quantity modified (partial fill)
/// - **Delete**: Price level removed entirely (all orders filled/cancelled)
///
/// # HFT Considerations
///
/// In high-frequency trading, the sequence and timing of these changes
/// can provide insights into:
/// - Large order execution patterns
/// - Iceberg order detection
/// - Market maker behavior
/// - Liquidity provider strategies
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum PriceLevelChangeType {
    /// New price level added to the order book
    ///
    /// Indicates that orders were placed at a price level that
    /// previously had no quantity. Creates new market depth.
    Add,

    /// Existing price level quantity modified
    ///
    /// Partial execution or cancellation at an existing price level.
    /// The price level remains but with different total quantity.
    Update,

    /// Price level completely removed from order book
    ///
    /// All orders at this price level have been filled or cancelled.
    /// The price level no longer exists in the order book.
    Delete,
}

/// Side of the order book affected by a price level change.
///
/// Distinguishes between the buy side (bids) and sell side (asks)
/// of the order book for proper routing of level changes.
///
/// # Order Book Structure
///
/// ```text
/// Ask Side (Sell Orders)
/// ----------------------
/// $100.03  |  500 shares
/// $100.02  |  750 shares  ← Best Ask
/// $100.01  | 1000 shares
/// ========================
/// $100.00  | 1200 shares  ← Best Bid
/// $ 99.99  |  800 shares
/// $ 99.98  |  600 shares
/// ----------------------
/// Bid Side (Buy Orders)
/// ```
///
/// # Trading Implications
///
/// - **Bid Changes**: Affect buying pressure and support levels
/// - **Ask Changes**: Affect selling pressure and resistance levels
/// - **Best Bid/Ask**: Most important levels for spread calculation
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum OrderBookSide {
    /// Buy side of the order book
    ///
    /// Orders from traders willing to buy the security.
    /// Higher bid prices indicate stronger buying pressure.
    Bid,

    /// Sell side of the order book
    ///
    /// Orders from traders willing to sell the security.
    /// Lower ask prices indicate stronger selling pressure.
    Ask,
}
