"""Tests for Step 3 library services (revisions, search, export)."""

from sqlmodel import select
import pytest

from transcription.models import Document, Job, JobStatus, Transcript, TranscriptRevision
from transcription.services.library import accept_revision, add_revision, export_transcripts, list_revisions, search_accepted_transcripts


def _create_job(session) -> Job:
    document = Document(filename="letter.jpg", file_path="uploads/letter.jpg")
    session.add(document)
    session.commit()
    session.refresh(document)

    job = Job(document_id=document.id, status=JobStatus.TRANSCRIBED)
    session.add(job)
    session.commit()
    session.refresh(job)
    return job


@pytest.mark.integration
class TestRevisionHistoryBehavior:
    """Verify revision append/accept behavior."""

    def test_add_revision_appends_incrementing_revision_numbers(self, session):
        """add_revision creates immutable incrementing revisions per job."""
        job = _create_job(session)

        r1 = add_revision(job_id=job.id, text="first", session=session)
        r2 = add_revision(job_id=job.id, text="second", session=session)

        revisions = list_revisions(job_id=job.id, session=session)

        assert r1.revision_number == 1
        assert r2.revision_number == 2
        assert [revision.revision_number for revision in revisions] == [1, 2]

    def test_accept_revision_marks_selected_revision_and_sets_job_completed(self, session):
        """accept_revision marks one revision accepted and transitions job to completed."""
        job = _create_job(session)
        r1 = add_revision(job_id=job.id, text="v1", session=session)
        r2 = add_revision(job_id=job.id, text="v2", session=session)

        accepted = accept_revision(revision_id=r2.id, session=session)
        session.refresh(job)

        all_revisions = list(session.exec(select(TranscriptRevision).where(TranscriptRevision.job_id == job.id)).all())
        accepted_flags = {revision.id: revision.accepted for revision in all_revisions}
        transcript = session.exec(select(Transcript).where(Transcript.job_id == job.id)).first()

        assert accepted.id == r2.id
        assert accepted_flags[r1.id] is False
        assert accepted_flags[r2.id] is True
        assert job.status == JobStatus.COMPLETED
        assert transcript is not None
        assert transcript.text == "v2"


@pytest.mark.integration
class TestSearchAndExportBehavior:
    """Verify accepted-only search and export semantics."""

    def test_search_returns_only_accepted_revisions(self, session):
        """search_accepted_transcripts filters out non-accepted revisions."""
        job = _create_job(session)
        draft = add_revision(job_id=job.id, text="family archive draft", session=session)
        accepted = add_revision(job_id=job.id, text="family archive final", accepted=True, session=session)

        results = search_accepted_transcripts(query="archive", session=session)

        assert results
        result_ids = {result.id for result in results}
        assert accepted.id in result_ids
        assert draft.id not in result_ids

    def test_export_returns_serializable_records_for_accepted_revisions(self, session):
        """export_transcripts returns expected fields for accepted-only export."""
        job = _create_job(session)
        accepted = add_revision(job_id=job.id, text="export me", accepted=True, session=session)

        records = export_transcripts(accepted_only=True, session=session)

        assert len(records) == 1
        record = records[0]
        assert record["job_id"] == str(job.id)
        assert record["revision_id"] == str(accepted.id)
        assert record["accepted"] is True
        assert record["text"] == "export me"
