#!/usr/bin/env python3
"""
MCRO multi-group summary
========================

Scan a directory of MCRO JSON files and output a CSV listing all documents
(filename) that belong to MORE THAN ONE pdf_group (via tracking.groups).

Output columns:
    filename, pdf_group1, pdf_group2, pdf_group3, font_group1, font_group2, font_group3

Rules:
  - One row per filename (no duplicates).
  - Only include rows where the document has >= 2 distinct pdf_group values.
  - For each document:
      * Collect (pdf_group, font_group) from tracking.groups[*].
      * Deduplicate by pdf_group.
      * Sort by pdf_group alphabetically.
      * Assign up to three:
            pdf_group1/font_group1 -> smallest pdf_group
            pdf_group2/font_group2 -> next
            pdf_group3/font_group3 -> next
      * If fewer than 3, remaining columns are blank.

Usage:
  python3 mcro_multigroup_summary.py \
      --input /path/to/json_dir \
      --out multigroup_summary.csv \
      [--pattern "*.json"] \
      [--recurse]
"""

import argparse
import csv
import json
from pathlib import Path
from typing import Any, Dict, List, Tuple
import sys


def as_list(x):
    if x is None:
        return []
    if isinstance(x, list):
        return x
    return [x]


def main():
    ap = argparse.ArgumentParser(description="Summarize documents that belong to multiple pdf_groups.")
    ap.add_argument("--input", required=True, help="Directory containing JSON files")
    ap.add_argument("--out", required=True, help="Output CSV file path")
    ap.add_argument("--pattern", default="*.json", help='Glob for JSON files (default: "*.json")')
    ap.add_argument("--recurse", action="store_true", help="Recurse into subdirectories")
    args = ap.parse_args()

    json_dir = Path(args.input)
    if not json_dir.is_dir():
        print(f"[error] Input directory does not exist or is not a directory: {json_dir}", file=sys.stderr)
        sys.exit(1)

    if args.recurse:
        files = sorted(json_dir.rglob(args.pattern))
    else:
        files = sorted(json_dir.glob(args.pattern))

    if not files:
        print(f"[warn] No JSON files matched {args.pattern} under {json_dir}", file=sys.stderr)
        sys.exit(0)

    rows: List[Dict[str, Any]] = []

    for jp in files:
        try:
            data = json.loads(jp.read_text(encoding="utf-8"))
        except Exception as e:
            print(f"[warn] Skipping {jp}: failed to parse JSON ({e})", file=sys.stderr)
            continue

        if not isinstance(data, dict):
            print(f"[warn] Skipping {jp}: JSON root is not an object", file=sys.stderr)
            continue

        filename = data.get("filename", "").strip()
        if not filename:
            # If there's no filename in the JSON, it won't match your CSV-based tracking anyway
            continue

        tracking = data.get("tracking") or {}
        groups = as_list(tracking.get("groups"))

        if not groups:
            continue

        # Collect unique pdf_group -> font_group mapping
        group_map: Dict[str, str] = {}
        for g in groups:
            if not isinstance(g, dict):
                continue
            pg = g.get("pdf_group")
            if pg is None:
                continue
            pg_str = str(pg).strip()
            if not pg_str:
                continue
            # get font_group if present
            fg = g.get("font_group")
            fg_str = str(fg).strip() if fg is not None else ""
            # Only store first seen font_group for each pdf_group
            if pg_str not in group_map:
                group_map[pg_str] = fg_str

        # We only care about docs that belong to 2 or more distinct pdf_groups
        if len(group_map) < 2:
            continue

        # Sort by pdf_group alphabetically
        sorted_groups: List[Tuple[str, str]] = sorted(group_map.items(), key=lambda kv: kv[0])

        # Take up to 3
        pdf_groups = [g[0] for g in sorted_groups[:3]]
        font_groups = [g[1] for g in sorted_groups[:3]]

        # Pad to length 3 with empty strings
        while len(pdf_groups) < 3:
            pdf_groups.append("")
        while len(font_groups) < 3:
            font_groups.append("")

        row = {
            "filename": filename,
            "pdf_group1": pdf_groups[0],
            "pdf_group2": pdf_groups[1],
            "pdf_group3": pdf_groups[2],
            "font_group1": font_groups[0],
            "font_group2": font_groups[1],
            "font_group3": font_groups[2],
        }
        rows.append(row)

    out_path = Path(args.out)
    out_path.parent.mkdir(parents=True, exist_ok=True)

    fieldnames = [
        "filename",
        "pdf_group1", "pdf_group2", "pdf_group3",
        "font_group1", "font_group2", "font_group3",
    ]

    with out_path.open("w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(rows)

    print(f"[ok] Wrote {len(rows)} multi-group rows to: {out_path.resolve()}")


if __name__ == "__main__":
    main()
