from __future__ import annotations

from datetime import datetime, timezone

from digital_pet_import import load_module

state_mod = load_module("state.py", "digital_pet_state")
PetState = state_mod.PetState
apply_event = state_mod.apply_event


def at(second: int = 0):
    return datetime(2026, 1, 1, 12, 0, second, tzinfo=timezone.utc)


def test_click_summons_hidden_pet_deterministically():
    state = PetState()

    next_state = apply_event("click", state=state, now=at())

    assert next_state.enabled is True
    assert next_state.mode == "idle"
    assert next_state.last_mode == "hidden"
    assert next_state.message == "Station companion online."
    assert next_state.revision == 1


def test_hover_hold_sends_active_pet_to_sleep():
    state = apply_event("summon", state=PetState(), now=at())

    next_state = apply_event("hover_hold", state=state, now=at(1))

    assert next_state.enabled is True
    assert next_state.mode == "sleeping"
    assert next_state.last_mode == "idle"
    assert next_state.message == "Going quiet."


def test_sleeping_click_wakes_then_wake_complete_returns_idle():
    state = apply_event("summon", state=PetState(), now=at())
    state = apply_event("hover_hold", state=state, now=at(1))

    waking = apply_event("click", state=state, now=at(2))
    assert waking.mode == "waking"
    assert waking.message == "Back online."

    idle = apply_event("wake_complete", state=waking, now=at(3))
    assert idle.mode == "idle"
    assert idle.message is None


def test_reaction_and_prompt_complete_return_to_idle():
    state = apply_event("summon", state=PetState(), now=at())
    reacting = apply_event("click", state=state, now=at(1))
    assert reacting.mode == "reacting"

    idle = apply_event("reaction_complete", state=reacting, now=at(2))
    assert idle.mode == "idle"

    idle.prompt_cooldown_until = None
    prompting = apply_event("prompt_tick", state=idle, now=at(3))
    assert prompting.mode == "prompting"

    completed = apply_event("prompt_complete", state=prompting, now=at(4))
    assert completed.mode == "idle"


def test_hidden_and_sleeping_ignore_prompt_and_reacting_completion():
    hidden = PetState()
    after_prompt = apply_event("prompt_tick", state=hidden, now=at())
    after_reaction_complete = apply_event("reaction_complete", state=after_prompt, now=at(1))

    assert after_prompt.mode == "hidden"
    assert after_reaction_complete.mode == "hidden"

    sleeping = apply_event("sleep", state=PetState(enabled=True, mode="idle"), now=at(2))
    still_sleeping = apply_event("prompt_tick", state=sleeping, now=at(3))

    assert still_sleeping.mode == "sleeping"
