//! Database query module
//!
//! Centralizes repeated database queries to avoid duplication
//! and provide a consistent interface for data access.

use sqlx::SqlitePool;
use anyhow::Result;

/// Get a player by ID
pub async fn get_player_by_id(pool: &SqlitePool, player_id: i64) -> Result<Option<(i64, String, Option<String>, f64)>> {
    let result = sqlx::query_as::<_, (i64, String, Option<String>, f64)>(
        "SELECT id, name, email, rating FROM players WHERE id = ?"
    )
    .bind(player_id)
    .fetch_optional(pool)
    .await?;
    
    Ok(result)
}

/// Get all players
pub async fn get_all_players(pool: &SqlitePool) -> Result<Vec<(i64, String, f64)>> {
    let players = sqlx::query_as::<_, (i64, String, f64)>(
        "SELECT id, name, rating FROM players ORDER BY rating DESC"
    )
    .fetch_all(pool)
    .await?;
    
    Ok(players)
}

/// Get leaderboard with ratings
pub async fn get_leaderboard(pool: &SqlitePool) -> Result<Vec<(i64, String, f64)>> {
    let leaderboard = sqlx::query_as::<_, (i64, String, f64)>(
        r#"SELECT 
            p.id, 
            p.name, 
            p.rating
        FROM players p
        WHERE p.id IN (SELECT DISTINCT player_id FROM match_participants)
        ORDER BY p.rating DESC"#
    )
    .fetch_all(pool)
    .await?;
    
    Ok(leaderboard)
}

/// Get all matches for a player
pub async fn get_player_matches(pool: &SqlitePool, player_id: i64) -> Result<Vec<(i64, String, i32, i32, String)>> {
    let matches = sqlx::query_as::<_, (i64, String, i32, i32, String)>(
        r#"SELECT 
            m.id,
            m.match_type,
            m.team1_score,
            m.team2_score,
            m.timestamp
        FROM matches m
        JOIN match_participants mp ON m.id = mp.match_id
        WHERE mp.player_id = ?
        ORDER BY m.timestamp DESC
        LIMIT 100"#
    )
    .bind(player_id)
    .fetch_all(pool)
    .await?;
    
    Ok(matches)
}

/// Get all matches from today
pub async fn get_daily_matches(pool: &SqlitePool, date: &str) -> Result<Vec<(i64, String, i32, i32, String)>> {
    let matches = sqlx::query_as::<_, (i64, String, i32, i32, String)>(
        r#"SELECT 
            id,
            match_type,
            team1_score,
            team2_score,
            timestamp
        FROM matches
        WHERE DATE(timestamp) = ?
        ORDER BY timestamp DESC"#
    )
    .bind(date)
    .fetch_all(pool)
    .await?;
    
    Ok(matches)
}

/// Get total match count
pub async fn get_match_count(pool: &SqlitePool) -> Result<i64> {
    let count = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM matches")
        .fetch_one(pool)
        .await?;
    
    Ok(count)
}

/// Get player count
pub async fn get_player_count(pool: &SqlitePool) -> Result<i64> {
    let count = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM players")
        .fetch_one(pool)
        .await?;
    
    Ok(count)
}

/// Get session count
pub async fn get_session_count(pool: &SqlitePool) -> Result<i64> {
    let count = sqlx::query_scalar::<_, i64>("SELECT COUNT(*) FROM sessions")
        .fetch_one(pool)
        .await?;
    
    Ok(count)
}

#[cfg(test)]
mod tests {
    // Database tests would go here
}
