"""SQLAlchemy repository tests against an in-memory sqlite db."""

from __future__ import annotations

from uuid import uuid4

import pytest

from ocr_sprint.db.base import Base, get_engine, session_scope
from ocr_sprint.db.repositories import JobNotFoundError, JobRepository
from ocr_sprint.schemas.document import DocumentStatus, SourceKind


@pytest.fixture
def db_ready() -> None:
    Base.metadata.create_all(bind=get_engine())


def test_create_then_fetch(db_ready: None) -> None:
    jid = uuid4()
    with session_scope() as session:
        JobRepository(session).create(
            job_id=jid,
            filename="x.pdf",
            source_kind=SourceKind.PDF,
            blob_key="2026/01/01/x.pdf",
        )
    with session_scope() as session:
        row = JobRepository(session).get_or_raise(jid)
    assert row.status == DocumentStatus.PENDING.value
    assert row.source_kind == SourceKind.PDF.value
    assert row.blob_key == "2026/01/01/x.pdf"


def test_lifecycle_transitions(db_ready: None) -> None:
    jid = uuid4()
    with session_scope() as session:
        JobRepository(session).create(
            job_id=jid,
            filename="x.pdf",
            source_kind=SourceKind.PDF,
            blob_key="k",
        )
    with session_scope() as session:
        JobRepository(session).mark_processing(jid)
    with session_scope() as session:
        repo = JobRepository(session)
        repo.mark_completed(
            jid,
            status=DocumentStatus.NEEDS_REVIEW,
            confidence=0.88,
            result={"header": {"nomor_sprint": "Sprin/1/2025"}},
            review_flags=["low_ocr_confidence"],
        )
        row = repo.get_or_raise(jid)
    assert row.status == DocumentStatus.NEEDS_REVIEW.value
    assert row.confidence == 0.88
    assert row.result == {"header": {"nomor_sprint": "Sprin/1/2025"}}
    assert row.review_flags == ["low_ocr_confidence"]


def test_mark_failed_truncates_long_error(db_ready: None) -> None:
    jid = uuid4()
    with session_scope() as session:
        JobRepository(session).create(
            job_id=jid, filename="x", source_kind=SourceKind.UNKNOWN, blob_key="k"
        )
    with session_scope() as session:
        JobRepository(session).mark_failed(jid, error="x" * 5000)
        row = JobRepository(session).get_or_raise(jid)
    assert len(row.error or "") == 2048


def test_unknown_job_raises(db_ready: None) -> None:
    with session_scope() as session, pytest.raises(JobNotFoundError):
        JobRepository(session).get_or_raise(uuid4())
