"""Tests for /api/recent/{project}."""

from __future__ import annotations

import json
import os
import time
from pathlib import Path

import pytest
from fastapi.testclient import TestClient

import recoil.api.adapters.recent as recent_mod
from recoil.api.main import app


@pytest.fixture
def client() -> TestClient:
    return TestClient(app)


@pytest.fixture
def fake_projects(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
    monkeypatch.setattr("recoil.api.adapters.recent.projects_root", lambda: tmp_path)
    recent_mod._RECENT_CACHE.clear()
    return tmp_path


def _touch(p: Path, mtime: float | None = None) -> None:
    p.parent.mkdir(parents=True, exist_ok=True)
    p.write_bytes(b"\x00")
    if mtime is not None:
        os.utime(p, (mtime, mtime))


def test_nested_layout_derives_episode_beat_take(fake_projects: Path) -> None:
    out = fake_projects / "tartarus" / "output" / "previs" / "ep_001"
    _touch(out / "shot_001_take7.png", mtime=time.time())
    resp = recent_mod.list_recent("tartarus")
    assert resp["total"] == 1
    row = resp["files"][0]
    assert row["episode_id"] == "EP001"
    assert row["beat_id"] == "EP001_SH01"
    assert row["take_id"] == "EP001_SH01_T007"
    assert row["type"] == "image"


def test_flat_layout_yields_null_episode(fake_projects: Path) -> None:
    out = fake_projects / "driver-beware" / "output" / "CRASH_JUMP_02"
    _touch(out / "take_3.mp4", mtime=time.time())
    resp = recent_mod.list_recent("driver-beware")
    assert resp["total"] == 1
    row = resp["files"][0]
    assert row["episode_id"] is None
    assert row["beat_id"] == "CRASH_JUMP_02"
    assert row["take_id"] == "CRASH_JUMP_02_T003"
    assert row["type"] == "video"


def test_mtime_sort_descending(fake_projects: Path) -> None:
    out = fake_projects / "tartarus" / "output" / "previs" / "ep_001"
    _touch(out / "shot_001_take1.png", mtime=1000.0)
    _touch(out / "shot_002_take1.png", mtime=2000.0)
    resp = recent_mod.list_recent("tartarus")
    names = [f["name"] for f in resp["files"]]
    assert names == ["shot_002_take1.png", "shot_001_take1.png"]


def test_skip_dirs_filtered(fake_projects: Path) -> None:
    base = fake_projects / "tartarus" / "output"
    _touch(base / "_archive" / "old.png", mtime=time.time())
    _touch(base / "_meta" / "ignored.png", mtime=time.time())
    _touch(base / "boundary_frames" / "frame.png", mtime=time.time())
    _touch(base / "previs" / "ep_001" / "shot_001_take1.png", mtime=time.time())
    resp = recent_mod.list_recent("tartarus")
    assert resp["total"] == 1


def test_pagination(fake_projects: Path) -> None:
    out = fake_projects / "tartarus" / "output" / "previs" / "ep_001"
    for i in range(1, 6):
        _touch(out / f"shot_001_take{i}.png", mtime=float(i))
    resp = recent_mod.list_recent("tartarus", limit=2, offset=1)
    assert resp["total"] == 5
    assert len(resp["files"]) == 2


def test_sidecar_overlay(fake_projects: Path) -> None:
    out = fake_projects / "tartarus" / "output" / "previs" / "ep_001"
    _touch(out / "shot_001_take1.png", mtime=time.time())
    meta = fake_projects / "tartarus" / "output" / "_meta"
    meta.mkdir(parents=True, exist_ok=True)
    (meta / "shot_001_take1.json").write_text(
        json.dumps(
            {
                "target_path": "output/previs/ep_001/shot_001_take1.png",
                "status": "primary",
                "status_color": "green",
                "model": "gemini-3.1-flash-image-preview",
                "cost": 0.04,
                "take_id": "EP001_SH01_T001",
            }
        ),
        encoding="utf-8",
    )
    recent_mod._RECENT_CACHE.clear()
    resp = recent_mod.list_recent("tartarus")
    row = resp["files"][0]
    assert row["status"] == "primary"
    assert row["model"] == "gemini-3.1-flash-image-preview"
    assert row["take_id"] == "EP001_SH01_T001"


def test_route_returns_200(client: TestClient, fake_projects: Path) -> None:
    out = fake_projects / "tartarus" / "output" / "previs" / "ep_001"
    _touch(out / "shot_001_take1.png", mtime=time.time())
    r = client.get("/api/recent/tartarus")
    assert r.status_code == 200
    body = r.json()
    assert body["schemaVersion"] == 2
    assert body["total"] == 1


def test_config_route_returns_200(client: TestClient) -> None:
    r = client.get("/api/config")
    assert r.status_code == 200
    body = r.json()
    assert body["schemaVersion"] == 1
    assert "ttydHost" in body
