"""Game state — all mutable globals, score, turn counter, puzzle flags."""

from __future__ import annotations

from typing import Any, Callable, TYPE_CHECKING

if TYPE_CHECKING:
    from h2g2.engine.game_object import GameObject, Room
    from h2g2.engine.world import World
    from h2g2.engine.output import Output
    from h2g2.engine.clock import Clock


class GameState:
    """Central mutable state for the game."""

    def __init__(self, world: "World", output: "Output", clock: "Clock") -> None:
        self.world = world
        self.output = output
        self.clock = clock

        # Core
        self.here: Room | None = None
        self.protagonist: GameObject | None = None
        self.winner: GameObject | None = None  # current actor
        self.score: int = 0
        self.moves: int = 0
        self.lit: bool = False
        self.running: bool = True

        # Identity system (multi-character)
        self.identity_flag: GameObject | None = None  # ARTHUR, FORD, etc.

        # Parser state
        self.prsa: str | None = None  # current verb
        self.prso: GameObject | None = None  # direct object
        self.prsi: GameObject | None = None  # indirect object
        self.p_it_object: GameObject | None = None  # last referenced object
        self.dont_flag: bool = False
        self.in_front_flag: bool = False

        # Last action (for AGAIN)
        self.l_prsa: str | None = None
        self.l_prso: GameObject | None = None
        self.l_prsi: GameObject | None = None

        # Engine-level condition flags
        self.lying_down: bool = False
        self.verbosity: int = 1  # 0=superbrief, 1=brief, 2=verbose
        self.dreaming: bool = False

        # Generic game state flags (content-specific)
        self.flags: dict[str, Any] = {}

        # Hook system for inventory extras
        self.inventory_extras: list[Callable] = []

        # Death system
        self._dream_restore_callback: Callable | None = None

    def update_lit(self) -> None:
        """Recalculate whether the current location is lit."""
        if self.here is None:
            self.lit = False
            return
        from h2g2.engine.game_object import Flag
        # Room has ONBIT = lit
        if self.here.fset_q(Flag.ONBIT):
            self.lit = True
            return
        # Check if player carries a light source
        if self.protagonist:
            for obj in self.protagonist.children:
                if obj.fset_q(Flag.LIGHTBIT) and obj.fset_q(Flag.ONBIT):
                    self.lit = True
                    return
        self.lit = False

    def jigs_up(self, message: str) -> None:
        """Handle player death."""
        self.output.tell(message + "\n")
        if self.dreaming:
            # Dream death: restore state and return to DARK room
            self.output.tell("\nEverything becomes...\n\n")
            # Content modules register dream-restore callbacks
            if self._dream_restore_callback:
                self._dream_restore_callback(self)
            dark = self.world.rooms.get("DARK")
            if dark:
                self.here = dark
                # Will be handled by dark room's M-ENTER
        else:
            self.output.tell("\n    ****  You have died  ****\n\n")
            self.finish()

    def finish(self) -> None:
        """End the game with score display and restart prompt."""
        self.output.tell(
            f"Your score is {self.score} of a possible 400, "
            f"in {self.moves} turns.\n"
        )
        self.running = False
