from datetime import date
from pathlib import Path

from cyclone.parsers.parse_837 import parse
from cyclone.parsers.payer import PayerConfig


FIXTURE = Path(__file__).parent / "fixtures" / "minimal_837p.txt"


def test_parse_minimal_fixture_returns_one_claim():
    text = FIXTURE.read_text()
    result = parse(text, PayerConfig.co_medicaid())
    assert len(result.claims) == 1
    claim = result.claims[0]
    assert claim.claim_id == "CLM001"
    assert claim.billing_provider.npi == "1993999998"
    assert claim.subscriber.last_name == "Doe"
    assert claim.subscriber.first_name == "John"
    assert claim.subscriber.member_id == "ABC123"
    assert claim.payer.id == "SKCO0"
    assert claim.claim.frequency_code == "1"
    assert claim.claim.place_of_service == "12"
    assert claim.claim.prior_auth == "PA123"
    assert claim.diagnoses[0].code == "Z00"
    assert claim.diagnoses[0].qualifier == "ABK"
    assert len(claim.service_lines) == 1
    sl = claim.service_lines[0]
    assert sl.procedure.code == "99213"
    assert sl.procedure.qualifier == "HC"
    assert sl.charge == 100.00


def test_parse_envelope_captured():
    result = parse(FIXTURE.read_text(), PayerConfig.co_medicaid())
    assert result.envelope is not None
    assert result.envelope.control_number == "991102977"
    assert result.envelope.transaction_date == date(2026, 6, 11)
    assert result.envelope.sender_id == "11525703"


def test_parse_summary_counts():
    result = parse(FIXTURE.read_text(), PayerConfig.co_medicaid())
    assert result.summary.total_claims == 1
    assert result.summary.passed == 1
    assert result.summary.failed == 0


def test_parse_continues_on_malformed_subscriber():
    """A bad subscriber record must not abort the whole batch."""
    text = FIXTURE.read_text().replace("MI*ABC123", "MI*")  # truncate member id segment
    result = parse(text, PayerConfig.co_medicaid())
    # Should still find the claim, but with errors
    assert len(result.claims) == 1
    assert result.claims[0].validation.passed is False
    assert result.summary.failed == 1


def test_parse_preserves_raw_segments():
    result = parse(FIXTURE.read_text(), PayerConfig.co_medicaid())
    claim = result.claims[0]
    assert any(s[0] == "CLM" for s in claim.raw_segments)
    assert any(s[0] == "SV1" for s in claim.raw_segments)


def test_parse_uses_generic_config_when_requested():
    result = parse(FIXTURE.read_text(), PayerConfig.generic_837p())
    assert len(result.claims) == 1
    # No patient-loop rule on generic config
    assert result.claims[0].validation.passed is True
