#!/usr/bin/env python3
"""
MCRO cluster date overview (CLI)
================================

Scan MCRO JSON files and, for each cluster_id, compute:

  - first_case_date   : earliest case_filing_date across all cases in the cluster
  - first_filing_date : earliest document filing_date in that cluster
  - last_filing_date  : latest  document filing_date in that cluster

ASSUMED STRUCTURE
-----------------

Each JSON (top level):

  filing_date   : "YYYY-MM-DD" (string)
  case : {
      "cluster_id"       : "...",
      "cluster_name"     : "...",   (ignored here)
      "case_id"          : "...",
      "case_filing_date" : "YYYY-MM-DD"  # case initiation date
      ...
  }

The script is robust if some fields are missing; those entries are just
ignored for that particular metric.

OUTPUT
------

Printed to stdout:

  cluster_id,first_case_date,first_filing_date,last_filing_date

Sorted by cluster_id (string sort).

USAGE
=====

  python3 mcro_cluster_date_overview.py \
      --input /path/to/json/documents \
      [--pattern "*.json"] \
      [--recurse]
"""

import argparse
import json
from pathlib import Path
from typing import Dict, Any
import sys


def safer_min(old: str | None, new: str | None) -> str | None:
    """
    Return the lexicographically smaller non-empty date string (YYYY-MM-DD),
    or whichever is non-empty if the other is None/empty.
    """
    if not new:
        return old
    if not old:
        return new
    return new if new < old else old


def safer_max(old: str | None, new: str | None) -> str | None:
    """
    Return the lexicographically larger non-empty date string (YYYY-MM-DD),
    or whichever is non-empty if the other is None/empty.
    """
    if not new:
        return old
    if not old:
        return new
    return new if new > old else old


def main():
    ap = argparse.ArgumentParser(description="Print per-cluster date overview for MCRO JSON files.")
    ap.add_argument(
        "--input",
        required=True,
        help="Directory containing MCRO JSON files.",
    )
    ap.add_argument(
        "--pattern",
        default="*.json",
        help='Glob pattern for JSON files (default: "*.json")',
    )
    ap.add_argument(
        "--recurse",
        action="store_true",
        help="Recurse into subdirectories under --input.",
    )
    args = ap.parse_args()

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

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

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

    # cluster_id -> aggregated dates
    cluster_dates: Dict[str, Dict[str, Any]] = {}

    n_parsed = 0
    n_failed = 0

    for fp in files:
        try:
            text = fp.read_text(encoding="utf-8")
            data = json.loads(text)
        except Exception as e:
            print(f"[warn] Failed to read/parse JSON: {fp} ({e})", file=sys.stderr)
            n_failed += 1
            continue

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

        case = data.get("case") or {}
        cluster_id = (case.get("cluster_id") or "").strip()
        if not cluster_id:
            # No cluster; ignore for cluster-based stats
            continue

        # Case initiation date (per case)
        case_filing_date = (case.get("case_filing_date") or "").strip()

        # Document filing date (per doc)
        filing_date = (data.get("filing_date") or "").strip()

        if cluster_id not in cluster_dates:
            cluster_dates[cluster_id] = {
                "first_case_date": None,
                "first_filing_date": None,
                "last_filing_date": None,
            }

        agg = cluster_dates[cluster_id]

        agg["first_case_date"] = safer_min(agg["first_case_date"], case_filing_date)
        agg["first_filing_date"] = safer_min(agg["first_filing_date"], filing_date)
        agg["last_filing_date"] = safer_max(agg["last_filing_date"], filing_date)

        n_parsed += 1

    # Print header
    print("cluster_id,first_case_date,first_filing_date,last_filing_date")

    # Sort by cluster_id for stable output
    for cluster_id in sorted(cluster_dates.keys()):
        dates = cluster_dates[cluster_id]
        first_case = dates["first_case_date"] or ""
        first_fil = dates["first_filing_date"] or ""
        last_fil = dates["last_filing_date"] or ""
        print(f"{cluster_id},{first_case},{first_fil},{last_fil}")

    print(f"\n[ok] Processed {n_parsed} JSONs with cluster_id (failed: {n_failed}).", file=sys.stderr)


if __name__ == "__main__":
    main()

