"""MIT. Key-free scoring; ten-transaction batches are resampling units."""
import json


def predictions(arguments, ids):
    rows = arguments.get("transactions", [])
    if not isinstance(rows, list):
        return {}, False
    output = {}
    valid = len(rows) == len(ids)
    for row in rows:
        if not isinstance(row, dict) or not isinstance(row.get("id"), str) or not isinstance(row.get("account_id"), str):
            valid = False
            continue
        if row["id"] in output or row["id"] not in ids:
            valid = False
        output[row["id"]] = row["account_id"]
    return output, valid and set(output) == set(ids)


def score(item, arguments, config):
    gold = item["gold"]
    pred, valid = predictions(arguments, gold)
    first = arguments.get("_oneshot", {})
    one, _ = predictions(first if isinstance(first, dict) else {}, gold)
    n = len(gold)
    accuracy = lambda p: sum(p.get(k) == v for k, v in gold.items()) / n
    classes = set(gold.values()) | {pred[k] for k in gold if k in pred}
    f1s = []
    for c in classes:
        tp = sum(v == c and pred.get(k) == c for k, v in gold.items())
        fp = sum(v != c and pred.get(k) == c for k, v in gold.items())
        fn = sum(v == c and pred.get(k) != c for k, v in gold.items())
        f1s.append(2 * tp / (2 * tp + fp + fn) if 2 * tp + fp + fn else 0)
    inputs = json.loads(item["text"])
    charts = {b: {a["id"] for a in chart} | {"needs_review"} for b, chart in inputs["businesses"].items()}
    invented = sum(t["id"] in pred and pred[t["id"]] not in charts[t["business"]] for t in inputs["transactions"])
    counts = {"tp": sum(v == "needs_review" and pred.get(k) == "needs_review" for k, v in gold.items()), "fp": sum(v != "needs_review" and pred.get(k) == "needs_review" for k, v in gold.items()), "fn": sum(v == "needs_review" and pred.get(k) != "needs_review" for k, v in gold.items())}
    tools = arguments.get("_tool_valid", [False, False, False])
    return {"score": accuracy(pred), "secondary": {
        "oneshot_accuracy": {"score": accuracy(one)},
        "batch_macro_f1": {"score": sum(f1s) / len(f1s)},
        "invented_account_rate": {"score": invented / n},
        "needs_review_precision": counts,
        "needs_review_recall": dict(counts),
        "tool_call_validity": {"score": sum(v is True for v in tools[:2]) / 3 + int(valid and tools[-1] is True) / 3 if isinstance(tools, list) and len(tools) == 3 else 0},
    }}
