"""Tests for the 835 ERA Pydantic models."""
import json
from datetime import date
from decimal import Decimal

from cyclone.parsers.models import Address, BatchSummary, Envelope
from cyclone.parsers.models_835 import (
    ClaimAdjustment,
    ClaimPayment,
    FinancialInfo,
    ParseResult835,
    Payer835,
    Payee835,
    ReassociationTrace,
    ServicePayment,
    claim_status_label,
)


def _build_result() -> ParseResult835:
    return ParseResult835(
        envelope=Envelope(
            sender_id="COMEDASSISTPROG",
            receiver_id="TPID001",
            control_number="991102984",
            transaction_date=date(2026, 6, 17),
            implementation_guide="005010X221A1",
        ),
        financial_info=FinancialInfo(
            handling_code="C",
            paid_amount=Decimal("85.00"),
            credit_debit_flag="C",
            payment_method="ACH",
            payer_tax_id="81-1725341",
            payment_date=date(2026, 6, 17),
        ),
        trace=ReassociationTrace(
            trace_type_code="1",
            trace_number="991102984",
            originating_company_id="TPID001",
            payer_id="81-1725341",
        ),
        payer=Payer835(
            name="CO_TXIX",
            id="7912900843",
            contact_url="hcpf.colorado.gov",
            address=Address(line1="PO BOX 11000", city="DENVER", state="CO", zip="802110000"),
        ),
        payee=Payee835(
            name="TOC, Inc.",
            npi="1881068062",
            address=Address(line1="1100 East Main St", line2="Suite A", city="Montrose", state="CO", zip="814014063"),
        ),
        claims=[
            ClaimPayment(
                payer_claim_control_number="CLM001",
                status_code="1",
                status_label="Processed as Primary",
                total_charge=Decimal("100.00"),
                total_paid=Decimal("85.00"),
                patient_responsibility=Decimal("15.00"),
                claim_filing_indicator="MC",
                original_claim_id="CLM001",
                facility_type="12",
                frequency_code="1",
                per_diem_covered_days=None,
                ref_benefit_plan=None,
                service_payments=[
                    ServicePayment(
                        line_number=1,
                        procedure_qualifier="HC",
                        procedure_code="S5130",
                        modifiers=["U2"],
                        charge=Decimal("60.00"),
                        payment=Decimal("50.00"),
                        units=Decimal("7.73"),
                        unit_type="UN",
                        service_date=date(2026, 6, 2),
                        adjustments=[
                            ClaimAdjustment(group_code="CO", reason_code="45", amount=Decimal("10.00"), quantity=None),
                        ],
                        ref_benefit_plan=None,
                    ),
                ],
                raw_segments=[["CLP", "CLM001", "1", "100.00", "85.00"]],
            )
        ],
        summary=BatchSummary(
            input_file="f",
            control_number="991102984",
            transaction_date=date(2026, 6, 17),
            total_claims=1,
            passed=1,
            failed=0,
        ),
    )


def test_financial_info_decimal_paid_amount():
    f = FinancialInfo(handling_code="C", paid_amount=Decimal("85.00"), credit_debit_flag="C")
    assert f.paid_amount == Decimal("85.00")
    assert f.payer_tax_id is None
    assert f.payment_date is None


def test_reassociation_trace_required():
    t = ReassociationTrace(trace_type_code="1", trace_number="X", originating_company_id="Y")
    assert t.payer_id is None


def test_payer835_optional_fields():
    p = Payer835(name="X")
    assert p.id is None
    assert p.address is None
    assert p.contact_url is None


def test_payee835_required_npi():
    p = Payee835(name="TOC", npi="1881068062")
    assert p.npi == "1881068062"


def test_claim_adjustment_quantity_optional():
    a = ClaimAdjustment(group_code="CO", reason_code="45", amount=Decimal("10.00"))
    assert a.quantity is None


def test_service_payment_modifiers_default_empty():
    sp = ServicePayment(
        line_number=1,
        procedure_qualifier="HC",
        procedure_code="99213",
        charge=Decimal("100.00"),
        payment=Decimal("85.00"),
    )
    assert sp.modifiers == []
    assert sp.adjustments == []


def test_claim_payment_status_label_decoded():
    c = ClaimPayment(
        payer_claim_control_number="X",
        status_code="1",
        total_charge=Decimal("100"),
        total_paid=Decimal("85"),
    )
    assert c.status_label == "Processed as Primary"
    assert claim_status_label("4") == "Denied"
    assert claim_status_label("25") == "Predetermination Pricing Only"
    assert claim_status_label("99") is None  # unknown → None


def test_parse_result835_date_serializes_to_iso():
    r = _build_result()
    blob = r.model_dump()
    assert blob["envelope"]["transaction_date"] == "2026-06-17"
    assert blob["financial_info"]["payment_date"] == "2026-06-17"
    assert blob["claims"][0]["service_payments"][0]["service_date"] == "2026-06-02"


def test_parse_result835_full_round_trip():
    r = _build_result()
    blob = json.loads(r.model_dump_json())
    assert blob["envelope"]["control_number"] == "991102984"
    assert blob["payer"]["name"] == "CO_TXIX"
    assert blob["payee"]["npi"] == "1881068062"
    assert blob["claims"][0]["payer_claim_control_number"] == "CLM001"
    # Round-trip back to a model
    r2 = ParseResult835.model_validate(blob)
    assert r2.claims[0].total_paid == Decimal("85.00")
    assert r2.payer.contact_url == "hcpf.colorado.gov"
