"""Tests for Step 3 functional API routes."""

from datetime import datetime, timezone
from types import SimpleNamespace
from uuid import uuid4

from fastapi import FastAPI
from fastapi.testclient import TestClient
import pytest

from transcription.api.errors import register_error_handlers
from transcription.api.routes import router


def _build_app() -> FastAPI:
    app = FastAPI()
    register_error_handlers(app)
    app.include_router(router)
    return app


@pytest.mark.integration
class TestFunctionalRoutes:
    """Verify jobs/revisions/search/export route behavior."""

    def test_get_jobs_returns_serialized_rows(self, monkeypatch):
        """GET /api/jobs returns normalized job rows."""
        now = datetime.now(timezone.utc)
        job = SimpleNamespace(
            id=uuid4(),
            document_id=uuid4(),
            status=SimpleNamespace(value="queued"),
            created_at=now,
            updated_at=now,
        )
        monkeypatch.setattr("transcription.api.routes.list_jobs", lambda: [job])

        client = TestClient(_build_app())
        response = client.get("/api/jobs")

        assert response.status_code == 200
        payload = response.json()
        assert len(payload) == 1
        assert payload[0]["id"] == str(job.id)
        assert payload[0]["status"] == "queued"

    def test_create_revision_returns_revision_payload(self, monkeypatch):
        """POST /api/jobs/{job_id}/revisions returns created revision fields."""
        revision = SimpleNamespace(
            id=uuid4(),
            job_id=uuid4(),
            revision_number=2,
            text="edited text",
            source="user",
            accepted=False,
            created_at=datetime.now(timezone.utc),
        )
        monkeypatch.setattr("transcription.api.routes.add_revision", lambda **_kwargs: revision)

        client = TestClient(_build_app())
        response = client.post(
            f"/api/jobs/{revision.job_id}/revisions",
            json={"text": "edited text", "source": "user", "accepted": False},
        )

        assert response.status_code == 200
        payload = response.json()
        assert payload["id"] == str(revision.id)
        assert payload["revision_number"] == 2
        assert payload["text"] == "edited text"

    def test_search_returns_results(self, monkeypatch):
        """GET /api/search returns accepted transcript matches."""
        result = SimpleNamespace(
            id=uuid4(),
            job_id=uuid4(),
            revision_number=1,
            text="family archive",
            source="user",
            accepted=True,
            created_at=datetime.now(timezone.utc),
        )
        monkeypatch.setattr("transcription.api.routes.search_accepted_transcripts", lambda query: [result])

        client = TestClient(_build_app())
        response = client.get("/api/search", params={"query": "archive"})

        assert response.status_code == 200
        payload = response.json()
        assert len(payload) == 1
        assert payload[0]["revision_id"] == str(result.id)
        assert payload[0]["accepted"] is True

    def test_export_returns_count_and_records(self, monkeypatch):
        """GET /api/export returns record count and payload list."""
        records = [
            {
                "job_id": str(uuid4()),
                "document_id": str(uuid4()),
                "filename": "letter.jpg",
                "revision_id": str(uuid4()),
                "revision_number": 1,
                "accepted": True,
                "source": "user",
                "text": "exported",
                "created_at": datetime.now(timezone.utc).isoformat(),
            }
        ]
        monkeypatch.setattr("transcription.api.routes.export_transcripts", lambda accepted_only=True: records)

        client = TestClient(_build_app())
        response = client.get("/api/export")

        assert response.status_code == 200
        payload = response.json()
        assert payload["count"] == 1
        assert payload["accepted_only"] is True
        assert payload["records"] == records
