//! Models module for pickleball player ratings using the Glicko2 rating system.
//!
//! # Glicko2 Rating System Overview
//!
//! The Glicko2 system provides a more sophisticated rating mechanism than simple Elo,
//! incorporating three parameters per player per format (singles/doubles):
//!
//! - **Rating (r)**: The player's skill estimate (1500 = average, typically ranges 400-2000+)
//! - **RD (Rating Deviation)**: Confidence level in the rating (lower RD = more confident)
//!   - Starts at ~350 (high uncertainty for new players)
//!   - Decreases with more matches played
//!   - Increases over time without play (conversely, inactive players become uncertain)
//!   - ~30 or below indicates a highly established rating
//! - **Volatility (σ)**: Unpredictability of player performance (0.06 = starting value)
//!   - Measures how inconsistently a player performs
//!   - Stable players have lower volatility; erratic players have higher
//!   - Affects how much a rating changes per match

/// Represents a player profile with Glicko2 ratings for both singles and doubles play.
///
/// Players maintain separate rating systems for singles and doubles because skill
/// in each format can differ significantly (e.g., strong net play in doubles ≠ consistent baseline in singles).
///
/// # Fields
///
/// * `id` - Unique database identifier
/// * `name` - Player's name (unique identifier)
/// * `email` - Optional email for notifications
/// * `singles_rating` - Glicko2 rating for singles matches (default: 1500.0)
/// * `singles_rd` - Rating Deviation for singles (default: 350.0; lower = more confident)
/// * `singles_volatility` - Volatility for singles (default: 0.06; higher = more erratic)
/// * `doubles_rating` - Glicko2 rating for doubles matches (default: 1500.0)
/// * `doubles_rd` - Rating Deviation for doubles (default: 350.0)
/// * `doubles_volatility` - Volatility for doubles (default: 0.06)
///
/// # Example
///
/// ```ignore
/// let player = Player {
///     id: 1,
///     name: "Alice".to_string(),
///     email: Some("alice@example.com".to_string()),
///     singles_rating: 1650.0,      // Somewhat above average
///     singles_rd: 80.0,             // Fairly confident (has played many matches)
///     singles_volatility: 0.055,    // Consistent performer
///     doubles_rating: 1500.0,       // New to doubles
///     doubles_rd: 350.0,            // High uncertainty
///     doubles_volatility: 0.06,
/// };
/// ```
#[derive(Debug, Clone)]
pub struct Player {
    /// Unique database identifier
    pub id: i64,
    /// Player's display name (unique)
    pub name: String,
    /// Optional email address
    pub email: Option<String>,
    
    // === Singles Glicko2 Parameters ===
    /// Skill estimate in singles format (1500 = average)
    pub singles_rating: f64,
    /// Confidence in singles rating (lower = more certain; ~30 = highly established)
    pub singles_rd: f64,
    /// Consistency in singles play (0.06 = starting; higher = more variable performance)
    pub singles_volatility: f64,
    
    // === Doubles Glicko2 Parameters ===
    /// Skill estimate in doubles format (1500 = average)
    pub doubles_rating: f64,
    /// Confidence in doubles rating (lower = more certain; ~30 = highly established)
    pub doubles_rd: f64,
    /// Consistency in doubles play (0.06 = starting; higher = more variable performance)
    pub doubles_volatility: f64,
}
