"""E2E tests for institutional claim validation pipeline."""

from __future__ import annotations

from claim_validator.models.institutional import (
    InstitutionalClaimData,
    InstitutionalServiceLine,
    OccurrenceCode,
    ValueCode,
)
from claim_validator.validators.institutional.admission import AdmissionValidator
from claim_validator.validators.institutional.bill_type import BillTypeValidator
from claim_validator.validators.institutional.completeness import (
    InstitutionalCompletenessValidator,
)
from claim_validator.validators.institutional.revenue_code import RevenueCodeValidator


def _valid_institutional_claim() -> InstitutionalClaimData:
    """Create a fully valid institutional claim for testing."""
    return InstitutionalClaimData(
        billing_provider_npi="1234567893",
        attending_physician_npi="9876543210",
        bill_type_code="111",
        admission_date="2026-01-10",
        discharge_date="2026-01-15",
        admission_type_code="1",
        admission_source_code="7",
        patient_status_code="01",
        subscriber_id="MEM123",
        payer_id="60054",
        service_lines=[
            InstitutionalServiceLine(revenue_code="0120", rate=500.00, units=5.0),
            InstitutionalServiceLine(revenue_code="0250", hcpcs_code="J1234", rate=150.00),
        ],
        total_charge_amount=2650.00,
    )


class TestInstitutionalFullValidation:
    """E2E: Run all institutional validators on a complete claim."""

    def test_valid_claim_passes_all_validators(self) -> None:
        """A complete, valid institutional claim has zero findings."""
        claim = _valid_institutional_claim()
        validators = [
            BillTypeValidator(),
            RevenueCodeValidator(),
            AdmissionValidator(),
            InstitutionalCompletenessValidator(),
        ]
        all_findings = []
        for v in validators:
            output = v.validate(claim)
            all_findings.extend(output.findings)

        assert len(all_findings) == 0, (
            f"Expected zero findings, got: {[f.code for f in all_findings]}"
        )

    def test_invalid_claim_catches_multiple_issues(self) -> None:
        """An empty claim should trigger all completeness validators."""
        claim = InstitutionalClaimData()
        v = InstitutionalCompletenessValidator()
        output = v.validate(claim)
        codes = {f.code for f in output.findings}
        assert "INST_MISSING_ATTENDING_NPI" in codes
        assert "INST_MISSING_BILL_TYPE" in codes
        assert "INST_MISSING_SERVICE_LINES" in codes
        assert "INST_MISSING_BILLING_NPI" in codes
        assert "INST_MISSING_SUBSCRIBER_ID" in codes

    def test_bad_bill_type_caught(self) -> None:
        claim = InstitutionalClaimData(bill_type_code="999")
        output = BillTypeValidator().validate(claim)
        assert any(f.code == "INST_INVALID_BILL_TYPE" for f in output.findings)

    def test_bad_revenue_code_caught(self) -> None:
        claim = InstitutionalClaimData(
            service_lines=[InstitutionalServiceLine(revenue_code="9999")]
        )
        output = RevenueCodeValidator().validate(claim)
        assert any(f.code == "INST_INVALID_REVENUE_CODE" for f in output.findings)

    def test_admission_after_discharge_caught(self) -> None:
        claim = InstitutionalClaimData(
            admission_date="2026-01-20",
            discharge_date="2026-01-10",
        )
        output = AdmissionValidator().validate(claim)
        assert any(f.code == "INST_ADMISSION_DATE_ORDER" for f in output.findings)

    def test_professional_claim_skips_institutional_validators(self) -> None:
        """Professional claim (ClaimData) should pass through institutional validators."""
        from tests.conftest import build_claim_unchecked

        claim = build_claim_unchecked(billing_provider_npi="1234567893")
        for v in [BillTypeValidator(), AdmissionValidator()]:
            output = v.validate(claim)
            assert len(output.findings) == 0

    def test_institutional_model_is_frozen(self) -> None:
        """All models should be immutable."""
        import pydantic
        import pytest

        claim = _valid_institutional_claim()
        with pytest.raises(pydantic.ValidationError):
            claim.bill_type_code = "222"  # type: ignore[misc]
