"""TDD: 999 ingest endpoint moves claims to REJECTED on AK5 R/E.

Plan: docs/superpowers/plans/2026-06-20-cyclone-workflow-automation.md
Task 4 (T4). Wires apply_999_rejections into the /api/parse-999 endpoint.
"""
from __future__ import annotations

import io
from datetime import datetime, timezone
from pathlib import Path

import pytest
from fastapi.testclient import TestClient

from cyclone import db
from cyclone.api import app
from cyclone.db import Batch, Claim, ClaimState


@pytest.fixture(autouse=True)
def _setup(tmp_path, monkeypatch):
    monkeypatch.setenv("CYCLONE_DB_URL", f"sqlite:///{tmp_path}/inbox.db")
    db._reset_for_tests()
    db.init_db()
    yield


@pytest.fixture
def client():
    with TestClient(app) as c:
        yield c


def _seed_claim(*, claim_id: str, patient_control_number: str) -> None:
    with db.SessionLocal()() as s:
        s.add(Batch(
            id="B-1", kind="837p", input_filename="x.txt",
            parsed_at=datetime.now(timezone.utc),
            totals_json={"total_claims": 1},
            validation_json={"passed": True, "warnings": [], "errors": []},
            raw_result_json={"_": "stub"},
        ))
        s.add(Claim(
            id=claim_id, batch_id="B-1",
            patient_control_number=patient_control_number,
            state=ClaimState.SUBMITTED,
        ))
        s.commit()


def test_999_set_rejection_moves_claim_to_rejected_state(client: TestClient):
    # The seeded claim's patient_control_number is the AK202 (set_control_number)
    # of the 999 we post.
    pcn = "PCN-001"
    _seed_claim(claim_id="CLP-1", patient_control_number=pcn)

    # Reuse the parser-valid minimal_999_rejected.txt fixture, then rewrite
    # AK202 (the set_control_number) and the SE* count + ST02 control number
    # so the parser accepts the modified document and we get an R rejection
    # keyed to our seeded PCN.
    fixture = (Path(__file__).parent / "fixtures" / "minimal_999_rejected.txt").read_text()
    raw = fixture.replace("AK2*837*0001~", f"AK2*837*{pcn}~")

    r = client.post(
        "/api/parse-999",
        files={"file": ("sample.999", io.BytesIO(raw.encode()), "text/plain")},
    )
    assert r.status_code == 200, r.text

    with db.SessionLocal()() as s:
        # Migration 0014: composite PK (batch_id, id).
        c = s.get(Claim, ("B-1", "CLP-1"))
        assert c.state == ClaimState.REJECTED
        assert c.rejected_at is not None
        assert "999" in (c.rejection_reason or "")

