"""Command line: ppi-studio validate|run|demo."""
from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

from .io import InputError
from .pipeline import PRESETS, Inputs, RunConfig, run_pipeline, validate
from .synthetic import make_synthetic_dataset


def _progress(ev):
    print(f"[{ev['elapsed']:>6.1f}s] {ev['progress']:>4.0%}  {ev['message']}", flush=True)


def main(argv=None):
    ap = argparse.ArgumentParser(prog="ppi-studio", description="Evaluate a PPI dataset before model building.")
    sub = ap.add_subparsers(dest="command", required=True)
    for name in ("validate", "run"):
        p = sub.add_parser(name)
        p.add_argument("--proteins", required=True)
        p.add_argument("--pairs", required=True)
        p.add_argument("--species", help="optional protein_id -> species table")
        if name == "run":
            p.add_argument("--clusters")
            p.add_argument("--embeddings")
            p.add_argument("--embeddings-name")
    for name in ("run", "demo"):
        p = sub.choices[name] if name in sub.choices else sub.add_parser(name)
        p.add_argument("--out", required=True)
        p.add_argument("--preset", choices=sorted(PRESETS), default="quick")
        p.add_argument("--seed", type=int, default=42)
        p.add_argument("--threads", type=int, default=4)
    args = ap.parse_args(argv)

    if args.command == "validate":
        rep = validate(Inputs(args.proteins, args.pairs, args.species))
        print(json.dumps({"ok": rep["ok"], "issues": rep["issues"]}, indent=2))
        return 0 if rep["ok"] else 1
    cfg = RunConfig(preset=args.preset, seed=args.seed, n_jobs=args.threads)
    if args.command == "demo":
        prot, pairs = make_synthetic_dataset(Path(args.out) / "synthetic_input")
        inputs = Inputs(prot, pairs)
    else:
        inputs = Inputs(args.proteins, args.pairs, args.species, args.clusters, args.embeddings)
        cfg.embeddings_name = args.embeddings_name
    try:
        res = run_pipeline(inputs, cfg, args.out, _progress)
    except InputError as e:
        print(json.dumps([i.to_dict() for i in e.issues], indent=2), file=sys.stderr)
        return 2
    print(f"\n{res['summary']['verdict']}: {res['summary']['headline']}")
    for d in res["diagnostics"]:
        print(f"  [{d['status']:>5}] {d['title']}: {d['headline']}")
    print(f"\nReport: {Path(args.out) / 'report.html'}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
