"""Tests for audit/review module — Task 44."""

from __future__ import annotations

from uuid import uuid4

from services.intelligence_pipeline_v3.audit.models import (
    AuditRecord,
    CorrectionEvent,
    CorrectionType,
    ReviewFilter,
    ReviewStatus,
)
from services.intelligence_pipeline_v3.audit.store import AuditStore


class TestAuditRecord:
    """Task 44.1-44.2: Evidence display and specialist output tracking."""

    def test_create_record(self):
        record = AuditRecord.create(
            document_id="doc-001",
            run_id=uuid4(),
            evidence_spans=[{"text": "Apple reported Q4 revenue", "start": 0, "end": 25}],
            specialist_outputs={"sentiment": {"positive": 0.8}},
            routing_reasons=["HIGH_CONFIDENCE"],
            route_decision="fast_path",
        )
        assert record.document_id == "doc-001"
        assert record.review_status == ReviewStatus.PENDING
        assert len(record.evidence_spans) == 1

    def test_add_correction(self):
        record = AuditRecord.create(
            document_id="doc-001", run_id=uuid4()
        )
        correction = CorrectionEvent.create(
            record_id=record.record_id,
            field_name="sentiment",
            correction_type=CorrectionType.INCORRECT,
            original_value="positive",
            corrected_value="negative",
            reviewer_id="reviewer-1",
        )
        record.add_correction(correction)
        assert record.review_status == ReviewStatus.CORRECTED
        assert len(record.corrections) == 1

    def test_corrections_are_immutable(self):
        correction = CorrectionEvent.create(
            record_id=uuid4(),
            field_name="ticker",
            correction_type=CorrectionType.CORRECT,
            original_value="AAPL",
            reviewer_id="reviewer-1",
        )
        # Frozen dataclass — cannot modify
        assert correction.event_id is not None
        assert correction.timestamp is not None

    def test_mark_reviewed(self):
        record = AuditRecord.create(document_id="doc-001", run_id=uuid4())
        record.mark_reviewed()
        assert record.review_status == ReviewStatus.REVIEWED

    def test_mark_confirmed(self):
        record = AuditRecord.create(document_id="doc-001", run_id=uuid4())
        record.mark_confirmed()
        assert record.review_status == ReviewStatus.CONFIRMED


class TestReviewFilter:
    """Task 44.4: Filters for low confidence, unsupported claims, adjudicated."""

    def test_filter_adjudicated(self):
        f = ReviewFilter(is_adjudicated=True)
        record_adj = AuditRecord.create(
            document_id="doc-001",
            run_id=uuid4(),
            adjudicator_decision={"resolved": True},
        )
        record_fast = AuditRecord.create(
            document_id="doc-002", run_id=uuid4()
        )
        assert f.matches(record_adj)
        assert not f.matches(record_fast)

    def test_filter_by_review_status(self):
        f = ReviewFilter(review_status=ReviewStatus.CORRECTED)
        record = AuditRecord.create(document_id="doc-001", run_id=uuid4())
        assert not f.matches(record)
        record.review_status = ReviewStatus.CORRECTED
        assert f.matches(record)

    def test_filter_unsupported_claims(self):
        f = ReviewFilter(has_unsupported_claims=True)
        record = AuditRecord.create(document_id="doc-001", run_id=uuid4())
        assert not f.matches(record)
        # Add unsupported correction
        record.add_correction(
            CorrectionEvent.create(
                record_id=record.record_id,
                field_name="fact",
                correction_type=CorrectionType.UNSUPPORTED,
                original_value="revenue beat",
                reviewer_id="r1",
            )
        )
        assert f.matches(record)


class TestAuditStore:
    """Task 44: Storage and retrieval."""

    def test_store_and_retrieve(self):
        store = AuditStore()
        record = AuditRecord.create(document_id="doc-001", run_id=uuid4())
        store.store(record)
        assert store.get(record.record_id) is record
        assert store.count() == 1

    def test_get_by_document(self):
        store = AuditStore()
        run1 = uuid4()
        run2 = uuid4()
        store.store(AuditRecord.create(document_id="doc-001", run_id=run1))
        store.store(AuditRecord.create(document_id="doc-001", run_id=run2))
        store.store(AuditRecord.create(document_id="doc-002", run_id=uuid4()))
        assert len(store.get_by_document("doc-001")) == 2

    def test_add_correction_to_record(self):
        store = AuditStore()
        record = AuditRecord.create(document_id="doc-001", run_id=uuid4())
        store.store(record)
        correction = CorrectionEvent.create(
            record_id=record.record_id,
            field_name="ticker",
            correction_type=CorrectionType.VALUE_OVERRIDE,
            original_value="GOOG",
            corrected_value="GOOGL",
            reviewer_id="r1",
        )
        assert store.add_correction(record.record_id, correction)
        assert store.correction_count() == 1

    def test_filter(self):
        store = AuditStore()
        r1 = AuditRecord.create(
            document_id="doc-001",
            run_id=uuid4(),
            adjudicator_decision={"x": 1},
        )
        r2 = AuditRecord.create(document_id="doc-002", run_id=uuid4())
        store.store(r1)
        store.store(r2)
        results = store.filter(ReviewFilter(is_adjudicated=True))
        assert len(results) == 1
        assert results[0].document_id == "doc-001"
