"""Tests for the jobs page routes and action handlers."""

import pytest
import pytest_asyncio
from sqlmodel import select

from transcription.db import session_scope
from transcription.db.models import Document, Job, JobSourceStatus, JobStatus


# --- Helper Fixtures ---


@pytest_asyncio.fixture
async def seed_document_with_unlinked_job():
    """Seed a document and a queued job for testing route actions."""
    async with session_scope() as session:
        document = Document(name="Test Archival Letter", document_type="letter")
        session.add(document)
        await session.flush()

        job = Job(
            document_id=document.id,
            status=JobStatus.QUEUED,
            provider="openai",
            model="gpt-4o",
        )
        session.add(job)
        await session.commit()
        return str(document.id), str(job.id)


# --- Integration Tests for Jobs Route Handlers ---


@pytest.mark.integration
class TestJobsPageRendering:
    """Verify jobs list, creation, detail, and lifecycle action routes."""

    def test_jobs_page_renders_empty_state(self, app_client):
        _, client = app_client

        response = client.get("/ui/jobs")

        assert response.status_code == 200
        assert "Transcription Pipeline Jobs" in response.text
        assert "No active or historical processing jobs found." in response.text

    @pytest.mark.asyncio
    async def test_jobs_page_lists_seeded_jobs(self, app_client, seed_job):
        _, client = app_client
        job_id = await seed_job(filename="seeded-document-page.png")

        response = client.get("/ui/jobs")

        assert response.status_code == 200
        assert str(job_id) in response.text
        assert "seeded-document-page.png" in response.text

    @pytest.mark.asyncio
    async def test_job_create_page_shows_empty_document_warning_when_no_docs(self, app_client):
        _, client = app_client

        response = client.get("/ui/jobs/new")

        assert response.status_code == 200
        assert "Create Processing Job" in response.text
        assert "No documents available. Create a Document before creating a Job." in response.text

    @pytest.mark.asyncio
    async def test_job_create_page_preselects_document_from_query_param(self, app_client):
        _, client = app_client

        async with session_scope() as session:
            doc = Document(name="Preselected Journal Entry", document_type="journal")
            session.add(doc)
            await session.commit()
            doc_id = str(doc.id)

        response = client.get(f"/ui/jobs/new?document_id={doc_id}")

        assert response.status_code == 200
        assert "Create Processing Job" in response.text
        assert "Preselected Journal Entry" in response.text

    @pytest.mark.asyncio
    async def test_job_detail_page_renders_logistics_and_links(
        self, app_client, seed_document_with_unlinked_job
    ):
        _, client = app_client
        _, job_id = seed_document_with_unlinked_job

        response = client.get(f"/ui/jobs/{job_id}")

        assert response.status_code == 200
        assert f"Job Record: {job_id}" in response.text
        assert "Execution Logistics".upper() in response.text.upper()
        assert "openai" in response.text
        assert "gpt-4o" in response.text
        assert "View Linked Document" in response.text
        assert "View Linked Sources" in response.text

    @pytest.mark.asyncio
    async def test_job_cancel_page_renders_confirmation(
        self, app_client, seed_document_with_unlinked_job
    ):
        _, client = app_client
        _, job_id = seed_document_with_unlinked_job

        response = client.get(f"/ui/jobs/{job_id}/cancel")

        assert response.status_code == 200
        assert "Cancel Processing Job" in response.text
        assert "Cancel stops processing" in response.text
        assert "Cancel job" in response.text

    @pytest.mark.asyncio
    async def test_job_resubmit_page_renders_counts(
        self, app_client, seed_job
    ):
        _, client = app_client
        job_id = await seed_job(
            filename="failed-resubmit.png",
            status=JobStatus.FAILED,
            transcription_text=None,
            error_detail="Timeout",
        )

        response = client.get(f"/ui/jobs/{job_id}/resubmit")

        assert response.status_code == 200
        assert "Resubmit Job" in response.text
        assert "Non-Transcribed Sources:" in response.text
        assert "Resubmit now" in response.text

    @pytest.mark.asyncio
    async def test_job_delete_page_blocks_deletion_when_processing(self, app_client):
        _, client = app_client

        async with session_scope() as session:
            doc = Document(name="Processing Doc", document_type="letter")
            session.add(doc)
            await session.flush()
            job = Job(document_id=doc.id, status=JobStatus.PROCESSING)
            session.add(job)
            await session.commit()
            job_id = str(job.id)

        response = client.get(f"/ui/jobs/{job_id}/delete")

        assert response.status_code == 200
        assert "Delete Processing Job" in response.text
        assert "Delete is blocked while the job is processing." in response.text

    @pytest.mark.asyncio
    async def test_job_delete_page_allows_deletion_for_queued_or_completed_job(
        self, app_client, seed_document_with_unlinked_job
    ):
        _, client = app_client
        _, job_id = seed_document_with_unlinked_job

        response = client.get(f"/ui/jobs/{job_id}/delete")

        assert response.status_code == 200
        assert "Delete Processing Job" in response.text
        assert "Delete job permanently" in response.text
        assert "Delete is blocked" not in response.text