"""Offline normalized-cost demo. No credentials, vendor API calls or invoices."""
from collections import defaultdict
from decimal import Decimal, InvalidOperation
import json


def reconcile(rows, paper):
    if not paper:
        raise ValueError("paper is required")
    seen, totals, review, excluded = {}, defaultdict(Decimal), [], []
    for row in rows:
        # IDs must come from a stable source row, not an import's row number.
        key = tuple(row.get(k) for k in ("provider", "account", "line_id"))
        if not all(isinstance(v, str) and v for v in key):
            raise ValueError("stable provider/account/line_id required")
        if key in seen:
            if seen[key] != row:
                raise ValueError("conflicting source row; reconcile revisions first")
            continue
        seen[key] = dict(row)
        if row.get("kind") != "actual_cost":
            excluded.append({"source": key, "reason": "not an actual cost row"})
            continue
        try:
            amount = Decimal(str(row["amount"]))
        except (KeyError, InvalidOperation):
            raise ValueError("invalid amount") from None
        currency = row.get("currency", "")
        if not amount.is_finite() or len(currency) != 3 or not currency.isascii() or not currency.isupper() or not currency.isalpha():
            raise ValueError("finite amount and uppercase currency code required")
        if not row.get("paper") or not row.get("attribution_ref"):
            review.append({"source": key, "reason": "paper attribution missing"})
            continue
        if row["paper"] != paper:
            continue
        totals[(row["provider"], currency)] += amount
        if not row.get("document_ref"):
            review.append({"source": key, "reason": "billing document missing"})
    return {
        "paper": paper,
        "attributed_costs": [
            {"provider": provider, "currency": currency, "amount": str(amount)}
            for (provider, currency), amount in sorted(totals.items())
        ],
        "needs_review": review,
        "excluded": excluded,
        "status": "draft_for_review_not_reimbursement_approval",
    }


DEMO = [
    dict(provider="platform-a", account="lab", line_id="cost-01", kind="actual_cost", amount="40.00", currency="USD", paper="paper-17", attribution_ref="run-baseline", document_ref="receipt-a.pdf"),
    dict(provider="platform-b", account="author", line_id="cost-02", kind="actual_cost", amount="27.50", currency="USD", paper="paper-17", attribution_ref="run-ablation", document_ref=""),
    dict(provider="platform-b", account="author", line_id="credit-03", kind="actual_cost", amount="-2.50", currency="USD", paper="paper-17", attribution_ref="credit-for-cost-02", document_ref="credit-note.pdf"),
    dict(provider="platform-a", account="lab", line_id="shared-04", kind="actual_cost", amount="12.00", currency="USD", paper="", attribution_ref="", document_ref="receipt-a.pdf"),
    dict(provider="platform-c", account="author", line_id="estimate-05", kind="token_estimate", amount="9.00", currency="USD"),
]

if __name__ == "__main__":
    print(json.dumps(reconcile(DEMO + [DEMO[0]], "paper-17"), indent=2))
