"""Tests for scroll generator."""
from __future__ import annotations

import json
from pathlib import Path

import torch
import pytest

from ai_mouse._scroll_legacy import generate_scroll
from tools.scroll.models import ScrollCVAE


@pytest.fixture
def scroll_model_dir(tmp_path):
    model = ScrollCVAE(seq_len=32)
    torch.save(model.state_dict(), tmp_path / "scroll_model.pt")
    config = {"seq_len": 32, "epochs": 100}
    (tmp_path / "scroll_config.json").write_text(json.dumps(config))
    return tmp_path


class TestGenerateScroll:
    def test_returns_list_of_dicts(self, scroll_model_dir):
        result = generate_scroll(1000, 3000, mode="target", model_dir=str(scroll_model_dir))
        assert isinstance(result, list)
        assert len(result) > 0
        assert all("deltaY" in e and "t" in e and "deltaMode" in e for e in result)

    def test_timestamps_monotonic(self, scroll_model_dir):
        result = generate_scroll(1000, 3000, mode="target", model_dir=str(scroll_model_dir))
        times = [e["t"] for e in result]
        for i in range(1, len(times)):
            assert times[i] >= times[i - 1]

    def test_total_scroll_approximately_matches_distance(self, scroll_model_dir):
        result = generate_scroll(1000, 3000, mode="target", model_dir=str(scroll_model_dir))
        total = sum(e["deltaY"] for e in result)
        # Should be within 30% of target distance (2000px)
        assert abs(total - 2000) < 2000 * 0.4

    def test_deltaY_are_integers(self, scroll_model_dir):
        result = generate_scroll(1000, 3000, mode="target", model_dir=str(scroll_model_dir))
        assert all(isinstance(e["deltaY"], int) for e in result)

    def test_direction_up(self, scroll_model_dir):
        result = generate_scroll(3000, 1000, mode="target", model_dir=str(scroll_model_dir))
        total = sum(e["deltaY"] for e in result)
        # Negative total for scrolling up
        assert total < 0
