"""CLI helpers for TEI validation workflows."""

from __future__ import annotations

import json
import sys

from hiveos_trace import terminal_style as _term


def _load_tei_input(*, file_path: str):
    path = str(file_path or "").strip()
    if path:
        with open(path, "r", encoding="utf-8") as handle:
            return json.load(handle)
    return json.load(sys.stdin)


def _summarize_item(item, raw_event):
    event = raw_event if isinstance(raw_event, dict) else {}
    return {
        "index": int(item.get("index") or 0),
        "ok": bool(item.get("ok")),
        "event_id": str(event.get("event_id") or ""),
        "run_id": str(event.get("run_id") or ""),
        "event_type": str(event.get("event_type") or ""),
        "errors": list(item.get("errors") or []),
    }


def handle_trace_tei_validate(args, *, validate_tei_event, validate_tei_batch):
    strict = bool(args.strict_version)
    try:
        payload = _load_tei_input(file_path=args.file)
    except Exception as exc:
        raise SystemExit(f"invalid input json: {exc}")

    if isinstance(payload, list):
        validated = validate_tei_batch(payload, strict_version=strict)
        items = []
        raw_events = payload
        for item in list(validated.get("items") or []):
            idx = int(item.get("index") or 0)
            raw = raw_events[idx] if 0 <= idx < len(raw_events) else {}
            items.append(_summarize_item(item, raw))
        result = {
            "ok": bool(validated.get("ok")),
            "mode": "batch",
            "strict_version": strict,
            "total": int(validated.get("total") or 0),
            "valid": int(validated.get("valid") or 0),
            "invalid": int(validated.get("invalid") or 0),
            "items": items,
        }
    else:
        validated = validate_tei_event(payload, strict_version=strict)
        event = payload if isinstance(payload, dict) else {}
        result = {
            "ok": bool(validated.get("ok")),
            "mode": "single",
            "strict_version": strict,
            "total": 1,
            "valid": 1 if bool(validated.get("ok")) else 0,
            "invalid": 0 if bool(validated.get("ok")) else 1,
            "items": [
                {
                    "index": 0,
                    "ok": bool(validated.get("ok")),
                    "event_id": str(event.get("event_id") or ""),
                    "run_id": str(event.get("run_id") or ""),
                    "event_type": str(event.get("event_type") or ""),
                    "errors": list(validated.get("errors") or []),
                }
            ],
        }

    if args.json:
        print(json.dumps(result, separators=(",", ":")))
        return 0 if result["ok"] else 1

    print(_term.section("tei_validate"))
    print(
        f"  {_term.key('mode')}={result['mode']} {_term.key('strict_version')}={result['strict_version']} "
        f"{_term.key('total')}={result['total']} {_term.key('valid')}={result['valid']} {_term.key('invalid')}={result['invalid']}"
    )
    print(_term.section("items"))
    for item in result["items"]:
        if item["ok"]:
            print(
                f"  {_term.ok('ok')} index={item['index']} run_id={item['run_id'] or '-'} "
                f"event_id={item['event_id'] or '-'} event_type={item['event_type'] or '-'}"
            )
        else:
            print(
                f"  {_term.err('invalid')} index={item['index']} run_id={item['run_id'] or '-'} "
                f"event_id={item['event_id'] or '-'} event_type={item['event_type'] or '-'}"
            )
            for err in item["errors"]:
                for wrapped in _term.wrap_text(str(err), initial_indent="    - ", subsequent_indent="      "):
                    print(wrapped)
    return 0 if result["ok"] else 1


def handle_trace_tei_ingest(
    args,
    *,
    ingest_tei_event,
    ingest_tei_events,
):
    try:
        payload = _load_tei_input(file_path=args.file)
    except Exception as exc:
        raise SystemExit(f"invalid input json: {exc}")

    strict = bool(args.strict_version)
    agent_id = str(args.agent_id or "observer.tei").strip() or "observer.tei"

    if isinstance(payload, list):
        result = ingest_tei_events(payload, agent_id=agent_id, strict_version=strict)
    else:
        result = ingest_tei_event(payload, agent_id=agent_id, strict_version=strict)

    ok = bool(result.get("ok"))
    if args.json:
        print(json.dumps(result, separators=(",", ":")))
        return 0 if ok else 1

    print(_term.section("tei_ingest"))
    if isinstance(payload, list):
        print(
            f"  {_term.key('ok')}={ok} {_term.key('total')}={int(result.get('total') or 0)} "
            f"{_term.key('ingested')}={int(result.get('ingested') or 0)} {_term.key('failed')}={int(result.get('failed') or 0)} "
            f"{_term.key('strict_version')}={bool(result.get('strict_version'))}"
        )
        print(_term.section("items"))
        for item in list(result.get("items") or []):
            idx = int(item.get("index") or 0)
            if bool(item.get("ok")):
                print(
                    f"  {_term.ok('ok')} index={idx} run_id={str(item.get('run_id') or '-')} "
                    f"event_id={str(item.get('event_id') or '-')} event_type={str(item.get('event_type') or '-')}"
                )
            else:
                print(f"  {_term.err('invalid')} index={idx} reason={str(item.get('reason') or 'validation_failed')}")
                for err in list(item.get("errors") or []):
                    for wrapped in _term.wrap_text(str(err), initial_indent="    - ", subsequent_indent="      "):
                        print(wrapped)
        return 0 if ok else 1

    # single object
    if ok:
        print(
            f"  {_term.key('ok')}=true run_id={str(result.get('run_id') or '-')} "
            f"event_id={str(result.get('event_id') or '-')} event_type={str(result.get('event_type') or '-')}"
        )
        return 0
    print(f"  {_term.key('ok')}=false {_term.key('reason')}={str(result.get('reason') or 'ingest_failed')}")
    for err in list(result.get("errors") or []):
        for wrapped in _term.wrap_text(str(err), initial_indent="  - ", subsequent_indent="    "):
            print(wrapped)
    hint = str(result.get("hint") or "").strip()
    if hint:
        for line in _term.wrap_kv(_term.key("hint"), hint, indent="  "):
            print(line)
    return 1
