"""Clock/interrupt system — timed events that fire on game turns."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Callable, Any


@dataclass
class ClockEntry:
    """A scheduled interrupt."""
    routine: Callable  # (state) -> bool; True = handled/displayed
    tick: int  # Countdown; fires when reaches 0. -1 = every turn
    enabled: bool = True
    name: str = ""  # For debugging


class Clock:
    """Manages timed game events, equivalent to ZIL's C-TABLE/CLOCKER."""

    def __init__(self) -> None:
        self.entries: list[ClockEntry] = []

    def queue(self, routine: Callable, tick: int, name: str = "") -> ClockEntry:
        """Schedule an interrupt routine to fire after `tick` turns.

        If an entry for the same routine already exists, update its tick.
        """
        for entry in self.entries:
            if entry.routine is routine:
                entry.tick = tick
                entry.enabled = True
                return entry
        entry = ClockEntry(routine=routine, tick=tick, name=name)
        self.entries.append(entry)
        return entry

    def enable(self, entry: ClockEntry) -> None:
        entry.enabled = True

    def disable(self, entry: ClockEntry) -> None:
        entry.enabled = False

    def remove(self, entry: ClockEntry) -> None:
        if entry in self.entries:
            self.entries.remove(entry)

    def tick_all(self, state: Any) -> bool:
        """Advance all clocks by one turn. Returns True if any event fired."""
        any_fired = False
        for entry in list(self.entries):  # copy because handlers may modify
            if not entry.enabled:
                continue
            if entry.tick > 0:
                entry.tick -= 1
            if entry.tick == 0:
                result = entry.routine(state)
                if result:
                    any_fired = True
                entry.enabled = False  # one-shot; re-enable manually
            elif entry.tick < 0:
                # Negative tick = fires every turn
                result = entry.routine(state)
                if result:
                    any_fired = True
        return any_fired
