#!/usr/bin/env python
"""Interactive console testing reference for Mantimon TCG core engine.

Usage:
    cd backend && uv run python -i references/console_testing.py

This script sets up a complete game state with cards, players, and demonstrates
how to use the effects system interactively.

After running, you'll have access to:
    - game: A GameState with two players and active Pokemon
    - pikachu, charmander: CardInstance objects (active Pokemon)
    - pikachu_def, charmander_def: CardDefinition objects
    - rng: A SeededRandom for deterministic testing
    - All imports ready to use

Quick Examples:
    >>> resolve_effect("deal_damage", make_ctx({"amount": 30}))
    >>> charmander.damage
    30
    >>> resolve_effect("apply_status", make_ctx({"status": "poisoned"}))
    >>> charmander.status_conditions
    [<StatusCondition.POISONED: 'poisoned'>]
"""

# =============================================================================
# PATH SETUP (ensures imports work when running from backend/)
# =============================================================================

import sys
from pathlib import Path

# Add backend to path if needed (references/ is directly under backend/)
backend_dir = Path(__file__).resolve().parent.parent
if str(backend_dir) not in sys.path:
    sys.path.insert(0, str(backend_dir))

# =============================================================================
# IMPORTS
# =============================================================================

# Register all built-in effect handlers
import app.core.effects.handlers  # noqa: F401
from app.core.config import (
    RulesConfig,
)
from app.core.effects.base import EffectContext
from app.core.effects.registry import list_effects
from app.core.enums import (
    CardType,
    EnergyType,
    PokemonStage,
    TrainerType,
    TurnPhase,
)
from app.core.models.card import (
    Attack,
    CardDefinition,
    CardInstance,
    WeaknessResistance,
)
from app.core.models.game_state import GameState, PlayerState
from app.core.rng import SeededRandom

# =============================================================================
# SAMPLE CARD DEFINITIONS
# =============================================================================

pikachu_def = CardDefinition(
    id="pikachu-001",
    name="Pikachu",
    card_type=CardType.POKEMON,
    stage=PokemonStage.BASIC,
    hp=60,
    pokemon_type=EnergyType.LIGHTNING,
    attacks=[
        Attack(name="Gnaw", damage=10),
        Attack(
            name="Thunder Shock",
            cost=[EnergyType.LIGHTNING],
            damage=20,
            effect_id="may_paralyze",
            effect_description="Flip a coin. If heads, the Defending Pokemon is now Paralyzed.",
        ),
    ],
    weakness=WeaknessResistance(energy_type=EnergyType.FIGHTING),
    retreat_cost=1,
)

charmander_def = CardDefinition(
    id="charmander-001",
    name="Charmander",
    card_type=CardType.POKEMON,
    stage=PokemonStage.BASIC,
    hp=70,
    pokemon_type=EnergyType.FIRE,
    attacks=[
        Attack(name="Scratch", damage=10),
        Attack(
            name="Ember",
            cost=[EnergyType.FIRE],
            damage=30,
            effect_id="discard_energy",
            effect_params={"count": 1},
        ),
    ],
    weakness=WeaknessResistance(energy_type=EnergyType.WATER),
    retreat_cost=1,
)

bulbasaur_def = CardDefinition(
    id="bulbasaur-001",
    name="Bulbasaur",
    card_type=CardType.POKEMON,
    stage=PokemonStage.BASIC,
    hp=70,
    pokemon_type=EnergyType.GRASS,
    attacks=[
        Attack(name="Vine Whip", cost=[EnergyType.GRASS], damage=20),
    ],
    weakness=WeaknessResistance(energy_type=EnergyType.FIRE),
    resistance=WeaknessResistance(energy_type=EnergyType.WATER),
    retreat_cost=1,
)

# Sample trainer card
potion_def = CardDefinition(
    id="potion-001",
    name="Potion",
    card_type=CardType.TRAINER,
    trainer_type=TrainerType.ITEM,
    effect_id="heal",
    effect_params={"amount": 30},
    effect_description="Heal 30 damage from one of your Pokemon.",
)

# Sample energy card
fire_energy_def = CardDefinition(
    id="fire-energy-001",
    name="Fire Energy",
    card_type=CardType.ENERGY,
    energy_type=EnergyType.FIRE,
    energy_provides=[EnergyType.FIRE],
)

# =============================================================================
# GAME STATE SETUP
# =============================================================================

# Create the game state
game = GameState(
    game_id="test-game-001",
    rules=RulesConfig(),
    card_registry={
        "pikachu-001": pikachu_def,
        "charmander-001": charmander_def,
        "bulbasaur-001": bulbasaur_def,
        "potion-001": potion_def,
        "fire-energy-001": fire_energy_def,
    },
    players={
        "player1": PlayerState(player_id="player1"),
        "player2": PlayerState(player_id="player2"),
    },
    turn_order=["player1", "player2"],
    current_player_id="player1",
    turn_number=1,
    phase=TurnPhase.MAIN,
)

# Create card instances
pikachu = CardInstance(instance_id="pika-1", definition_id="pikachu-001")
charmander = CardInstance(instance_id="char-1", definition_id="charmander-001")
bulbasaur = CardInstance(instance_id="bulba-1", definition_id="bulbasaur-001")

# Set up the board
game.players["player1"].active.add(pikachu)
game.players["player2"].active.add(charmander)
game.players["player2"].bench.add(bulbasaur)

# Add some cards to decks
for i in range(5):
    game.players["player1"].deck.add(
        CardInstance(instance_id=f"p1-deck-{i}", definition_id="bulbasaur-001")
    )
    game.players["player2"].deck.add(
        CardInstance(instance_id=f"p2-deck-{i}", definition_id="bulbasaur-001")
    )

# Create RNG
rng = SeededRandom(seed=42)


# =============================================================================
# HELPER FUNCTIONS
# =============================================================================


def make_ctx(params: dict, **kwargs) -> EffectContext:
    """Create an EffectContext with sensible defaults.

    Args:
        params: Effect parameters (e.g., {"amount": 30})
        **kwargs: Override defaults (source_player_id, source_card_id, target_card_id, etc.)

    Returns:
        EffectContext ready to pass to resolve_effect()

    Example:
        >>> ctx = make_ctx({"amount": 20})
        >>> resolve_effect("deal_damage", ctx)
    """
    defaults = {
        "game": game,
        "source_player_id": "player1",
        "rng": rng,
        "params": params,
    }
    defaults.update(kwargs)
    return EffectContext(**defaults)


def reset_game():
    """Reset the game state to initial conditions."""
    global pikachu, charmander, bulbasaur, rng

    # Reset damage and status
    pikachu.damage = 0
    pikachu.status_conditions = []
    pikachu.hp_modifier = 0
    pikachu.damage_modifier = 0
    pikachu.retreat_cost_modifier = 0
    pikachu.attached_energy = []

    charmander.damage = 0
    charmander.status_conditions = []
    charmander.hp_modifier = 0
    charmander.damage_modifier = 0
    charmander.retreat_cost_modifier = 0
    charmander.attached_energy = []

    bulbasaur.damage = 0
    bulbasaur.status_conditions = []

    # Reset RNG
    rng = SeededRandom(seed=42)

    print("Game state reset!")


def show_board():
    """Print the current board state."""
    print("\n" + "=" * 50)
    print("PLAYER 1 (current)")
    p1 = game.players["player1"]
    if p1.active:
        poke = p1.get_active_pokemon()
        poke_def = game.card_registry.get(poke.definition_id)
        hp = poke_def.hp + poke.hp_modifier if poke_def else "?"
        print(f"  Active: {poke_def.name if poke_def else poke.definition_id}")
        print(f"          HP: {hp - poke.damage}/{hp}  Damage: {poke.damage}")
        print(f"          Status: {[s.value for s in poke.status_conditions]}")
        print(f"          Energy: {poke.attached_energy}")
    print(f"  Bench: {len(p1.bench)} Pokemon")
    print(f"  Hand: {len(p1.hand)} cards, Deck: {len(p1.deck)} cards")

    print("\nPLAYER 2 (opponent)")
    p2 = game.players["player2"]
    if p2.active:
        poke = p2.get_active_pokemon()
        poke_def = game.card_registry.get(poke.definition_id)
        hp = poke_def.hp + poke.hp_modifier if poke_def else "?"
        print(f"  Active: {poke_def.name if poke_def else poke.definition_id}")
        print(f"          HP: {hp - poke.damage}/{hp}  Damage: {poke.damage}")
        print(f"          Status: {[s.value for s in poke.status_conditions]}")
        print(f"          Energy: {poke.attached_energy}")
    print(f"  Bench: {len(p2.bench)} Pokemon")
    print(f"  Hand: {len(p2.hand)} cards, Deck: {len(p2.deck)} cards")
    print("=" * 50 + "\n")


# =============================================================================
# DEMONSTRATION
# =============================================================================

if __name__ == "__main__":
    print(__doc__)
    print("\n" + "=" * 60)
    print("AVAILABLE EFFECT HANDLERS")
    print("=" * 60)
    for name in sorted(list_effects()):
        print(f"  - {name}")

    print("\n" + "=" * 60)
    print("QUICK REFERENCE")
    print("=" * 60)
    print("""
    # Deal raw damage (no weakness/resistance)
    resolve_effect("deal_damage", make_ctx({"amount": 30}))

    # Deal attack damage (with weakness/resistance)
    resolve_effect("attack_damage", make_ctx({"amount": 30}, source_card_id="pika-1"))

    # Apply status condition
    resolve_effect("apply_status", make_ctx({"status": "poisoned"}))

    # Heal damage
    resolve_effect("heal", make_ctx({"amount": 20}))

    # Draw cards
    resolve_effect("draw_cards", make_ctx({"count": 3}))

    # Coin flip damage
    resolve_effect("coin_flip_damage", make_ctx({"damage_per_heads": 20, "flip_count": 3}))

    # Bench damage
    resolve_effect("bench_damage", make_ctx({"amount": 10}))

    # Show board state
    show_board()

    # Reset everything
    reset_game()
    """)

    print("=" * 60)
    print("INITIAL BOARD STATE")
    print("=" * 60)
    show_board()

    print("Ready for interactive testing!")
    print("Try: resolve_effect('deal_damage', make_ctx({'amount': 30}))")
