"""Autonomous wandering. Needs a QApplication, so run with
QT_QPA_PLATFORM=offscreen (same as test_controller.py)."""

import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from PySide6.QtWidgets import QApplication

from bolt_pet import config
from bolt_pet.state import PetState
from bolt_pet.ui.pet_window import PetWindow


@pytest.fixture(scope="module")
def qt_app():
    app = QApplication.instance() or QApplication([])
    yield app


@pytest.fixture
def pet(qt_app):
    window = PetWindow()
    window.set_wander_enabled(True)
    yield window
    window.close()


def _walk_until_done(pet, max_ticks=2000):
    for _ in range(max_ticks):
        pet._wander_tick()
        if pet._wander_target is None:
            return True
    return False


def test_wanders_when_idle_and_reaches_its_target(pet, monkeypatch):
    # Snapping is tested separately; here it would tug the pet off its target
    # the moment it arrives near an edge.
    monkeypatch.setattr(config, "PET_EDGE_SNAP", False)
    pet.wander_now()
    pet._wander_tick()
    target = pet._wander_target
    if target is None:
        pytest.skip("no usable screen geometry for a stroll on this host")
    assert _walk_until_done(pet), "pet never reached its wander target"
    assert pet.pos() == target


def test_stays_put_while_talking(pet):
    pet.set_state(PetState.TALKING)
    start = pet.pos()
    pet.wander_now()
    for _ in range(50):
        pet._wander_tick()
    assert pet.pos() == start
    assert pet._wander_target is None


def test_stays_put_while_bubble_is_up(pet):
    pet.say("hello there", duration_ms=60000)
    start = pet.pos()
    pet.wander_now()
    for _ in range(50):
        pet._wander_tick()
    assert pet.pos() == start


def test_disabling_wander_stops_movement(pet):
    pet.set_wander_enabled(False)
    start = pet.pos()
    pet.wander_now()
    for _ in range(50):
        pet._wander_tick()
    assert pet.pos() == start


def test_stroll_stays_on_screen(pet):
    geo = pet._screen_geometry()
    if geo is None:
        pytest.skip("no usable screen geometry on this host")
    for _ in range(10):
        pet.wander_now()
        pet._wander_tick()
        assert _walk_until_done(pet)
        assert geo.contains(pet.geometry())
