"""Tests for MouseModel and ai_mouse.generate()."""
from __future__ import annotations

import pytest


def test_mouse_model_init_default() -> None:
    from ai_mouse.mouse import MouseModel
    m = MouseModel()
    assert m._seq_len > 0
    assert m._session is not None
    m.close()


def test_mouse_model_generate_returns_correct_shape() -> None:
    from ai_mouse.mouse import MouseModel
    m = MouseModel()
    pts = m.generate((100, 200), (900, 400))
    assert len(pts) == 66  # 64 moves + 2 clicks
    for x, y, t in pts:
        assert isinstance(x, int)
        assert isinstance(y, int)
        assert isinstance(t, int)


def test_mouse_model_click_false_omits_clicks() -> None:
    from ai_mouse.mouse import MouseModel
    m = MouseModel()
    pts = m.generate((100, 200), (900, 400), click=False)
    assert len(pts) == 64


def test_mouse_model_seed_reproducibility() -> None:
    from ai_mouse.mouse import MouseModel
    m = MouseModel()
    a = m.generate((100, 200), (900, 400), seed=42)
    b = m.generate((100, 200), (900, 400), seed=42)
    assert a == b


def test_mouse_model_invalid_path_raises_model_load_error() -> None:
    from ai_mouse.mouse import MouseModel
    from ai_mouse.errors import ModelLoadError
    with pytest.raises(ModelLoadError):
        MouseModel(model_path="/nonexistent/path/here")


def test_mouse_model_timestamps_monotonic() -> None:
    from ai_mouse.mouse import MouseModel
    m = MouseModel()
    pts = m.generate((100, 200), (900, 400))
    times = [p[2] for p in pts]
    for i in range(1, len(times)):
        assert times[i] >= times[i - 1]


def test_mouse_model_starts_and_ends_near_endpoints() -> None:
    from ai_mouse.mouse import MouseModel
    start = (100, 200)
    end = (900, 400)
    m = MouseModel()
    pts = m.generate(start, end)
    assert abs(pts[0][0] - start[0]) < 30
    assert abs(pts[0][1] - start[1]) < 30
    last_move = pts[-3]  # last 2 are click events
    assert abs(last_move[0] - end[0]) < 30
    assert abs(last_move[1] - end[1]) < 30


def test_mouse_model_n_points_parameter() -> None:
    from ai_mouse.mouse import MouseModel
    m = MouseModel()
    pts = m.generate((100, 200), (900, 400), n_points=32)
    # 32 moves + 2 clicks
    assert len(pts) == 34


def test_mouse_model_click_events_have_matching_coords() -> None:
    from ai_mouse.mouse import MouseModel
    m = MouseModel()
    pts = m.generate((100, 200), (900, 400))
    down, up = pts[-2], pts[-1]
    assert down[0] == up[0]
    assert down[1] == up[1]
    assert up[2] > down[2]
    # Within click_dist bounds 20..500
    assert 20 <= up[2] - down[2] <= 500
