"""SP7 — endpoint test for GET /api/claims/{id}/line-reconciliation.

Spec §5.1.

Architecture note: 837 service lines live in ``Claim.raw_json``, not a
separate ORM table, so the test seeds them via the raw_json blob.
"""
from datetime import date, datetime, timezone
from decimal import Decimal
import json
import uuid

import pytest
from fastapi.testclient import TestClient
from sqlalchemy import select

from cyclone import db
from cyclone.api import app
from cyclone.parsers.models_835 import ClaimPayment, ServicePayment
from cyclone.reconcile import run
from cyclone.store import _persist_835_remit, _remittance_835_row


@pytest.fixture
def client():
    return TestClient(app)


def _seed(client):
    """Insert one claim + matching remit + 4 service lines (3 matched, 1 unmatched 837).
    Returns the claim id."""
    bid = str(uuid.uuid4())
    claim_id = "CLM-API-1"
    svc_lines_json = []
    # 4 837 service lines: 99213, 99214, 99215, 90837 (last one is 837-only — no SVC)
    for i, code in enumerate(["99213", "99214", "99215", "90837"], start=1):
        svc_lines_json.append({
            "line_number": i,
            "procedure": {"qualifier": "HC", "code": code, "modifiers": []},
            "charge": "100.00",
            "unit_type": "UN",
            "units": "1",
            "place_of_service": "11",
            "service_date": f"2026-06-0{i}",
            "provider_reference": None,
        })

    with db.SessionLocal()() as s:
        s.add(db.Batch(
            id=bid, kind="835", input_filename="x.835",
            parsed_at=datetime.now(timezone.utc),
            totals_json={"total_claims": 1, "total_paid": "240"},
            validation_json={"passed": True, "warnings": [], "errors": []},
            raw_result_json={"_": "stub"},
        ))
        s.add(db.Claim(
            id=claim_id,
            patient_control_number="PCN-API",
            charge_amount=Decimal("300.00"),
            provider_npi="1234567890",
            payer_id="SKCO0",
            service_date_from=date(2026, 6, 1),
            service_date_to=date(2026, 6, 4),
            state="submitted",
            batch_id=bid,
            raw_json={"service_lines": svc_lines_json},
        ))
        # Remit pays the first 3 lines (line 4 is 837-only)
        cp = ClaimPayment(
            payer_claim_control_number="PCN-API",
            status_code="1",
            total_charge=Decimal("300.00"),
            total_paid=Decimal("240.00"),
            service_payments=[
                ServicePayment(
                    line_number=i, procedure_qualifier="HC",
                    procedure_code=code, charge=Decimal("100.00"),
                    payment=Decimal("80.00"),
                    units=Decimal("1"),
                    service_date=date(2026, 6, i),
                )
                for i, code in enumerate(["99213", "99214", "99215"], start=1)
            ],
        )
        remit = _remittance_835_row(cp, bid)
        s.add(remit)
        s.flush()
        _persist_835_remit(s, cp, remit.id)
        s.commit()

        # Run reconcile so matched_remittance_id gets set + LineReconciliation rows persist
        run(s, bid)
        s.commit()

    return claim_id


def test_endpoint_returns_documented_shape(client):
    claim_id = _seed(client)
    r = client.get(f"/api/claims/{claim_id}/line-reconciliation")
    assert r.status_code == 200, r.text
    body = r.json()
    assert body["claim_id"] == claim_id
    assert body["summary"]["total_lines"] == 4
    assert body["summary"]["matched_lines"] == 3
    statuses = sorted(row["status"] for row in body["lines"])
    assert statuses == ["matched", "matched", "matched", "unmatched_837_only"]


def test_endpoint_404_for_unknown_claim(client):
    r = client.get("/api/claims/UNKNOWN/line-reconciliation")
    assert r.status_code == 404
