//! Tests migrated from inline #[cfg(test)] module in src/core/engine/effect_context.rs

use cardgame::effects::EffectTarget;
use cardgame::engine::{ResolvedTargets, TargetResolver};
use cardgame::keywords::Keywords;
use cardgame::state::{Creature, GameState};
use cardgame::types::{CardId, CreatureInstanceId, PlayerId, Slot};

fn create_test_creature(owner: PlayerId, slot: Slot) -> Creature {
    Creature {
        instance_id: CreatureInstanceId(1),
        card_id: CardId(1000),
        owner,
        slot,
        attack: 2,
        current_health: 3,
        max_health: 3,
        base_attack: 2,
        base_health: 3,
        keywords: Keywords::none(),
        status: Default::default(),
        turn_played: 1,
        frenzy_stacks: 0,
        token_data: None,
    }
}

#[test]
fn test_resolve_single_creature() {
    let mut state = GameState::default();
    state.players[0]
        .creatures
        .push(create_test_creature(PlayerId::PLAYER_ONE, Slot(0)));

    let target = EffectTarget::Creature {
        owner: PlayerId::PLAYER_ONE,
        slot: Slot(0),
    };
    let result = TargetResolver::resolve(&target, None, &state);

    match result {
        ResolvedTargets::Single { owner, slot } => {
            assert_eq!(owner, PlayerId::PLAYER_ONE);
            assert_eq!(slot, Slot(0));
        }
        _ => panic!("Expected Single target"),
    }
}

#[test]
fn test_resolve_nonexistent_creature() {
    let state = GameState::default();
    let target = EffectTarget::Creature {
        owner: PlayerId::PLAYER_ONE,
        slot: Slot(0),
    };
    let result = TargetResolver::resolve(&target, None, &state);

    assert!(matches!(result, ResolvedTargets::None));
}

#[test]
fn test_resolve_player() {
    let state = GameState::default();
    let target = EffectTarget::Player(PlayerId::PLAYER_TWO);
    let result = TargetResolver::resolve(&target, None, &state);

    match result {
        ResolvedTargets::Player(player) => assert_eq!(player, PlayerId::PLAYER_TWO),
        _ => panic!("Expected Player target"),
    }
}

#[test]
fn test_resolve_all_creatures() {
    let mut state = GameState::default();
    state.players[0]
        .creatures
        .push(create_test_creature(PlayerId::PLAYER_ONE, Slot(0)));
    state.players[0]
        .creatures
        .push(create_test_creature(PlayerId::PLAYER_ONE, Slot(1)));
    state.players[1]
        .creatures
        .push(create_test_creature(PlayerId::PLAYER_TWO, Slot(0)));

    let target = EffectTarget::AllCreatures;
    let result = TargetResolver::resolve(&target, None, &state);

    match result {
        ResolvedTargets::Multiple(creatures) => {
            assert_eq!(creatures.len(), 3);
        }
        _ => panic!("Expected Multiple targets"),
    }
}

#[test]
fn test_resolve_ally_creatures() {
    let mut state = GameState::default();
    state.players[0]
        .creatures
        .push(create_test_creature(PlayerId::PLAYER_ONE, Slot(0)));
    state.players[0]
        .creatures
        .push(create_test_creature(PlayerId::PLAYER_ONE, Slot(1)));
    state.players[1]
        .creatures
        .push(create_test_creature(PlayerId::PLAYER_TWO, Slot(0)));

    let target = EffectTarget::AllAllyCreatures(PlayerId::PLAYER_ONE);
    let result = TargetResolver::resolve(&target, None, &state);

    match result {
        ResolvedTargets::Multiple(creatures) => {
            assert_eq!(creatures.len(), 2);
            assert!(creatures
                .iter()
                .all(|(owner, _)| *owner == PlayerId::PLAYER_ONE));
        }
        _ => panic!("Expected Multiple targets"),
    }
}

#[test]
fn test_resolve_enemy_creatures() {
    let mut state = GameState::default();
    state.players[0]
        .creatures
        .push(create_test_creature(PlayerId::PLAYER_ONE, Slot(0)));
    state.players[1]
        .creatures
        .push(create_test_creature(PlayerId::PLAYER_TWO, Slot(0)));
    state.players[1]
        .creatures
        .push(create_test_creature(PlayerId::PLAYER_TWO, Slot(1)));

    let target = EffectTarget::AllEnemyCreatures(PlayerId::PLAYER_ONE);
    let result = TargetResolver::resolve(&target, None, &state);

    match result {
        ResolvedTargets::Multiple(creatures) => {
            assert_eq!(creatures.len(), 2);
            assert!(creatures
                .iter()
                .all(|(owner, _)| *owner == PlayerId::PLAYER_TWO));
        }
        _ => panic!("Expected Multiple targets"),
    }
}
