"""Write a :class:`ParseResult` to disk as one JSON file per claim + summary.json."""

from __future__ import annotations

import json
import re
from pathlib import Path

from cyclone.parsers.models import ParseResult

_UNSAFE = re.compile(r"[^A-Za-z0-9._-]")


def _sanitize(s: str) -> str:
    return _UNSAFE.sub("-", s).strip("-") or "claim"


def _filename(control_number: str, transaction_date_iso: str, claim_id: str, used: set[str]) -> str:
    base = f"claim-{_sanitize(control_number)}-{_sanitize(transaction_date_iso.replace('-', ''))}-{_sanitize(claim_id)}.json"
    if base not in used:
        return base
    # Disambiguate: append -2, -3, ...
    stem = base[:-5]
    n = 2
    while True:
        cand = f"{stem}-{n}.json"
        if cand not in used:
            return cand
        n += 1


def write_outputs(result: ParseResult, output_dir: Path) -> list[Path]:
    """Write one JSON file per claim and a ``summary.json``.

    Returns the list of written claim-file paths, in input order.
    """
    output_dir = Path(output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    txn_date = result.envelope.transaction_date.isoformat() if result.envelope else "unknown"
    control = result.envelope.control_number if result.envelope else "unknown"

    used: set[str] = set()
    paths: list[Path] = []
    for claim in result.claims:
        name = _filename(control, txn_date, claim.claim_id, used)
        used.add(name)
        path = output_dir / name
        path.write_text(claim.model_dump_json(indent=2))
        paths.append(path)

    summary_path = output_dir / "summary.json"
    summary_path.write_text(result.summary.model_dump_json(indent=2))
    return paths
