"""Integration tests for end-to-end upload and worker pipeline behavior."""

from pathlib import Path

import pytest
from sqlmodel import desc
from sqlmodel import select

from transcription.config import Settings
from transcription.models import Job
from transcription.models import JobStatus
from transcription.models import Transcript
from transcription.providers.base import TranscriptionResult
from transcription.services.store import create_upload_job
from transcription.worker import process_next_queued_job


@pytest.mark.integration
class TestPipelineSuccessFlow:
    """Verify end-to-end success lifecycle behavior."""

    @pytest.mark.asyncio
    async def test_upload_then_worker_persists_transcribed_terminal_state(
        self,
        async_session,
        tmp_path: Path,
        monkeypatch,
    ):
        """Upload followed by worker processing persists transcript and transcribed status."""
        settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path)
        upload_result = await create_upload_job(
            filename="pipeline.jpg",
            file_bytes=b"pipeline-bytes",
            session=async_session,
            settings=settings,
        )

        async def _fake_transcribe(_path: str) -> TranscriptionResult:
            return TranscriptionResult(
                text="Pipeline transcript",
                provider="openrouter",
                prompt_name="transcribe_document.md",
                model="test-model",
            )

        monkeypatch.setattr("transcription.services.workflows.transcribe_document_image", _fake_transcribe)

        processed = await process_next_queued_job(session=async_session)
        job = await async_session.get(Job, upload_result.job_id)
        transcript = (
            await async_session.exec(
                select(Transcript)
                .where(Transcript.job_id == upload_result.job_id)
                .order_by(desc(Transcript.revision))
                .limit(1)
            )
        ).first()

        assert processed is True
        assert job is not None
        assert job.status == JobStatus.TRANSCRIBED
        assert transcript is not None
        assert transcript.text == "Pipeline transcript"
        assert transcript.error_detail is None


@pytest.mark.integration
class TestPipelineFailureFlow:
    """Verify end-to-end failure lifecycle behavior."""

    @pytest.mark.asyncio
    async def test_upload_then_worker_persists_failed_terminal_state(
        self,
        async_session,
        tmp_path: Path,
        monkeypatch,
    ):
        """Upload followed by worker processing persists error detail and failed status."""
        settings = Settings(openrouter_api_key="test-key", upload_dir=tmp_path)
        upload_result = await create_upload_job(
            filename="pipeline.jpg",
            file_bytes=b"pipeline-bytes",
            session=async_session,
            settings=settings,
        )

        async def _fake_transcribe(_path: str) -> TranscriptionResult:
            raise RuntimeError("pipeline provider failure")

        monkeypatch.setattr("transcription.services.workflows.transcribe_document_image", _fake_transcribe)

        processed = await process_next_queued_job(session=async_session)
        job = await async_session.get(Job, upload_result.job_id)
        transcript = (
            await async_session.exec(
                select(Transcript)
                .where(Transcript.job_id == upload_result.job_id)
                .order_by(desc(Transcript.revision))
                .limit(1)
            )
        ).first()

        assert processed is True
        assert job is not None
        assert job.status == JobStatus.FAILED
        assert transcript is not None
        assert transcript.text is None
        assert "pipeline provider failure" in transcript.error_detail
        assert "[internal_unexpected_error]" in transcript.error_detail
        assert "error_id=" in transcript.error_detail
