//! Tests for game mode system (Attrition vs Essence War).

use cardgame::cards::CardDatabase;
use cardgame::core::config::game;
use cardgame::core::state::{GameMode, GameResult, WinReason};
use cardgame::engine::GameEngine;
use cardgame::types::CardId;

/// Default commander for tests (The High Artificer).
const DEFAULT_COMMANDER: CardId = CardId(5000);

fn load_test_db() -> CardDatabase {
    CardDatabase::load_with_commanders(
        cardgame::data_dir().join("cards/core_set"),
        cardgame::data_dir().join("commanders"),
    )
    .expect("Failed to load card database with commanders")
}

fn get_test_deck() -> Vec<CardId> {
    // Simple test deck with low-cost creatures
    vec![
        CardId(2000), CardId(2000), // Spore Crawler x2
        CardId(2001), CardId(2001), // Feral Striker x2
        CardId(2002), CardId(2002), // Venomfang x2
        CardId(2003), CardId(2003), // Swarm Runner x2
        CardId(2004), CardId(2004), // Hive Warrior x2
        CardId(2005), CardId(2005), // Brood Guardian x2
        CardId(2006), CardId(2006), // Evolution Master x2
        CardId(2007), CardId(2007), // Apex Predator x2
        CardId(2008), CardId(2008), // Swarm Surge x2
        CardId(2009), CardId(2009), // Feeding Frenzy x2
        CardId(4000), CardId(4000), // Hedge Wizard x2
        CardId(4001), CardId(4001), // Street Rat x2
        CardId(4002), CardId(4002), // Wandering Merchant x2
        CardId(4003), CardId(4003), // Caravan Guard x2
        CardId(4004), CardId(4004), // Free-Walker Scout x2
    ]
}

#[test]
fn test_game_mode_default_is_essence_war() {
    let card_db = load_test_db();
    let mut engine = GameEngine::new(&card_db);
    let deck = get_test_deck();

    engine.start_game_raw(deck.clone(), deck.clone(), DEFAULT_COMMANDER, DEFAULT_COMMANDER, 12345, GameMode::default()).unwrap();

    assert_eq!(engine.state.game_mode, GameMode::EssenceWar);
}

#[test]
fn test_start_game_with_mode_sets_mode() {
    let card_db = load_test_db();
    let mut engine = GameEngine::new(&card_db);
    let deck = get_test_deck();

    engine.start_game_raw(deck.clone(), deck.clone(), DEFAULT_COMMANDER, DEFAULT_COMMANDER, 12345, GameMode::EssenceWar).unwrap();

    assert_eq!(engine.state.game_mode, GameMode::EssenceWar);
}

#[test]
fn test_essence_war_vp_threshold_is_50() {
    assert_eq!(game::VICTORY_POINTS_THRESHOLD, 50);
}

#[test]
fn test_essence_war_vp_victory_at_threshold() {
    let card_db = load_test_db();
    let mut engine = GameEngine::new(&card_db);
    let deck = get_test_deck();

    engine.start_game_raw(deck.clone(), deck.clone(), DEFAULT_COMMANDER, DEFAULT_COMMANDER, 12345, GameMode::EssenceWar).unwrap();

    // Simulate player 1 dealing exactly 50 face damage
    engine.state.players[0].total_damage_dealt = 50;
    engine.check_essence_extraction_victory();

    assert!(engine.is_game_over());
    match engine.state.result {
        Some(GameResult::Win { winner, reason }) => {
            assert_eq!(winner.index(), 0); // Player 1 wins
            assert_eq!(reason, WinReason::EssenceExtractionReached);
        }
        _ => panic!("Expected VP victory for player 1"),
    }
}

#[test]
fn test_essence_war_vp_victory_above_threshold() {
    let card_db = load_test_db();
    let mut engine = GameEngine::new(&card_db);
    let deck = get_test_deck();

    engine.start_game_raw(deck.clone(), deck.clone(), DEFAULT_COMMANDER, DEFAULT_COMMANDER, 12345, GameMode::EssenceWar).unwrap();

    // Simulate player 2 dealing more than 50 face damage
    engine.state.players[1].total_damage_dealt = 55;
    engine.check_essence_extraction_victory();

    assert!(engine.is_game_over());
    match engine.state.result {
        Some(GameResult::Win { winner, reason }) => {
            assert_eq!(winner.index(), 1); // Player 2 wins
            assert_eq!(reason, WinReason::EssenceExtractionReached);
        }
        _ => panic!("Expected VP victory for player 2"),
    }
}

#[test]
fn test_essence_war_no_victory_below_threshold() {
    let card_db = load_test_db();
    let mut engine = GameEngine::new(&card_db);
    let deck = get_test_deck();

    engine.start_game_raw(deck.clone(), deck.clone(), DEFAULT_COMMANDER, DEFAULT_COMMANDER, 12345, GameMode::EssenceWar).unwrap();

    // Set damage just below threshold
    engine.state.players[0].total_damage_dealt = 49;
    engine.state.players[1].total_damage_dealt = 49;
    engine.check_essence_extraction_victory();

    assert!(!engine.is_game_over());
}

#[test]
fn test_attrition_ignores_essence_extraction() {
    let card_db = load_test_db();
    let mut engine = GameEngine::new(&card_db);
    let deck = get_test_deck();

    // Use explicit Attrition mode (not default - default is EssenceWar)
    engine.start_game_raw(deck.clone(), deck.clone(), DEFAULT_COMMANDER, DEFAULT_COMMANDER, 12345, GameMode::Attrition).unwrap();

    // Even with 100 damage dealt, game doesn't end via essence extraction in Attrition mode
    engine.state.players[0].total_damage_dealt = 100;
    engine.check_essence_extraction_victory();

    assert!(!engine.is_game_over());
}

#[test]
fn test_life_victory_takes_precedence_in_essence_war() {
    let card_db = load_test_db();
    let mut engine = GameEngine::new(&card_db);
    let deck = get_test_deck();

    engine.start_game_raw(deck.clone(), deck.clone(), DEFAULT_COMMANDER, DEFAULT_COMMANDER, 12345, GameMode::EssenceWar).unwrap();

    // Reduce player 2's life to 0
    engine.state.players[1].life = 0;
    engine.check_life_victory();

    assert!(engine.is_game_over());
    match engine.state.result {
        Some(GameResult::Win { winner, reason }) => {
            assert_eq!(winner.index(), 0); // Player 1 wins
            assert_eq!(reason, WinReason::LifeReachedZero);
        }
        _ => panic!("Expected life-based victory"),
    }
}

#[test]
fn test_vp_check_doesnt_override_existing_result() {
    let card_db = load_test_db();
    let mut engine = GameEngine::new(&card_db);
    let deck = get_test_deck();

    engine.start_game_raw(deck.clone(), deck.clone(), DEFAULT_COMMANDER, DEFAULT_COMMANDER, 12345, GameMode::EssenceWar).unwrap();

    // Player 2 has life victory first
    engine.state.players[1].life = 0;
    engine.check_life_victory();

    // Now player 2 also has VP (shouldn't override)
    engine.state.players[1].total_damage_dealt = 50;
    engine.check_essence_extraction_victory();

    // Life victory should still be the reason
    match engine.state.result {
        Some(GameResult::Win { reason, .. }) => {
            assert_eq!(reason, WinReason::LifeReachedZero);
        }
        _ => panic!("Expected life-based victory"),
    }
}

#[test]
fn test_game_mode_preserved_across_turns() {
    let card_db = load_test_db();
    let mut engine = GameEngine::new(&card_db);
    let deck = get_test_deck();

    engine.start_game_raw(deck.clone(), deck.clone(), DEFAULT_COMMANDER, DEFAULT_COMMANDER, 12345, GameMode::EssenceWar).unwrap();

    // End turn a few times
    for _ in 0..3 {
        engine.state.active_player_state_mut().action_points = 0;
        let _ = engine.apply_action(cardgame::actions::Action::EndTurn);
    }

    // Mode should still be Essence War
    assert_eq!(engine.state.game_mode, GameMode::EssenceWar);
}
