//! Steam-User Example - Token Dumper
//!
//! Dumps access tokens for apps using an anonymous login.
//! This is a Rust port of the JavaScript tokendumper.js example.
//!
//! # Usage
//! ```bash
//! cargo run --example token_dumper
//! ```

use std::time::Duration;

use steam_client::{AppsEvent, LogOnDetails, SteamClient, SteamEvent};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize logging
    tracing_subscriber::fmt().with_max_level(tracing::Level::INFO).init();

    let mut client = SteamClient::new(Default::default());

    println!("🔑 Token Dumper - Fetching app access tokens\n");

    // Log on anonymously
    println!("🔓 Logging in anonymously...");
    let response = client.log_on(LogOnDetails { anonymous: true, ..Default::default() }).await?;

    println!("✅ Logged in as {}\n", response.steam_id.steam3());

    // Wait for connection to stabilize
    tokio::time::sleep(Duration::from_millis(500)).await;

    // Build list of app IDs to check (sample range)
    // Note: The JS example uses 0..1000000, but that would take forever
    // Let's use a smaller sample of popular apps
    let app_ids: Vec<u32> = vec![
        10,      // Counter-Strike
        20,      // Team Fortress Classic
        30,      // Day of Defeat
        40,      // Deathmatch Classic
        50,      // Half-Life: Opposing Force
        60,      // Ricochet
        70,      // Half-Life
        80,      // Condition Zero
        100,     // Condition Zero DS
        130,     // Half-Life: Blue Shift
        220,     // Half-Life 2
        240,     // CS:S
        280,     // HL2:DM
        300,     // Day of Defeat: Source
        320,     // HL2: Lost Coast
        340,     // HL2: Episode 1
        380,     // HL2: Episode 2
        400,     // Portal
        420,     // HL2: Episode Two
        440,     // Team Fortress 2
        500,     // Left 4 Dead
        550,     // Left 4 Dead 2
        570,     // Dota 2
        620,     // Portal 2
        730,     // CS:GO
        1245620, // Elden Ring
    ];

    println!("📋 Requesting access tokens for {} apps...\n", app_ids.len());

    // Request product access tokens
    client.get_product_access_tokens(app_ids.clone()).await?;

    // Wait for response events
    let start = std::time::Instant::now();
    while start.elapsed() < Duration::from_secs(10) {
        match client.poll_event_timeout(Duration::from_secs(1)).await {
            Ok(Some(SteamEvent::Apps(AppsEvent::AccessTokensResponse { app_tokens, app_denied, package_denied, .. }))) => {
                println!("📊 Results: {} tokens granted, {} denied\n", app_tokens.len(), app_denied.len());

                // Print tokens
                if !app_tokens.is_empty() {
                    println!("✅ Apps with access tokens:");
                    for (app_id, token) in &app_tokens {
                        if *token != 0 {
                            println!("   App {}: {}", app_id, token);
                        }
                    }
                }

                // Print denied
                if !app_denied.is_empty() && app_denied.len() <= 20 {
                    println!("\n❌ Apps denied:");
                    for app_id in &app_denied {
                        println!("   App {}", app_id);
                    }
                } else if app_denied.len() > 20 {
                    println!("\n❌ {} apps denied (too many to list)", app_denied.len());
                }

                if !package_denied.is_empty() {
                    println!("\n❌ {} packages denied", package_denied.len());
                }
                break;
            }
            Ok(Some(_)) => {}
            Ok(None) => {}
            Err(e) => {
                println!("❌ Error: {:?}", e);
                break;
            }
        }
    }

    println!();

    // Log off
    client.log_off().await?;
    println!("👋 Done!");

    Ok(())
}
