"""run_kurator.py — CLI-Einstiegspunkt für den notebooklm-kurator-Skill.

Drei Varianten (Spec §1 Wave-D MVP-Scope):

    python .skills/notebooklm-kurator/run_kurator.py --variant standard
    python .skills/notebooklm-kurator/run_kurator.py --variant resync \
        --notebook <UUID>
    python .skills/notebooklm-kurator/run_kurator.py \
        --variant dedup-check --notebook <UUID>

Der Einstiegspunkt ist bewusst dünn — die schwere Logik (semantische
Notebook-Wahl, Inbox-Klassifikation, Rückfragen-Liste) liegt im
aufrufenden LLM-Agent, der die Helper-Funktionen Schritt für Schritt
ansteuert. Dieses Skript dient hauptsächlich als Diagnose-/Smoke-Tool
und als Aufhänger für die Eval-Behavior-Tests.

Pflicht-Parameter über CLI oder Env:
    --state-root  oder  KURATOR_STATE_ROOT      (Pfad zu state/, backups/)
    --register    oder  KURATOR_REGISTER_PATH   (Pfad zur Register-Markdown)
    --inbox       oder  KURATOR_INBOX_ROOT      (Pfad zur Inbox-Wurzel)
    --notebook                                  (für resync/dedup-check)

Alle notebooklm-CLI-Aufrufe laufen über die Helper, die ihrerseits
PYTHONIOENCODING=utf-8 im Subprocess-Env setzen
(MOCK-API-CONTRACT.md §8 globale Pflicht).
"""
from __future__ import annotations

import argparse
import json
import os
import sys
from pathlib import Path


_SKILL_DIR = Path(__file__).resolve().parent
_HELPERS_DIR = _SKILL_DIR / "helpers"
if str(_HELPERS_DIR) not in sys.path:
    sys.path.insert(0, str(_HELPERS_DIR))


def _resolve_path(arg_value: str | None, env_name: str, default: str | None) -> Path | None:
    """Liest einen Pfad aus CLI-Arg, dann Env-Var, dann Default."""
    if arg_value:
        return Path(arg_value).resolve()
    env_value = os.environ.get(env_name)
    if env_value:
        return Path(env_value).resolve()
    if default:
        return Path(default).resolve()
    return None


def _cmd_standard(args: argparse.Namespace) -> int:
    """Standard-Variante: Inbox iterieren, klassifizieren, einsortieren.

    In Wave D dünn als Diagnose-Stub umgesetzt — der LLM-Agent ruft die
    Helper-Funktionen einzeln auf (siehe SKILL.md Ablauf).
    """
    from inbox_scan import scan_inbox  # noqa: WPS433

    inbox = _resolve_path(args.inbox, "KURATOR_INBOX_ROOT", None)
    if inbox is None:
        print(
            "FEHLER: --inbox oder KURATOR_INBOX_ROOT setzen.",
            file=sys.stderr,
        )
        return 2

    entries = scan_inbox(inbox)
    summary = {
        "variant": "standard",
        "inbox_root": str(inbox),
        "entries_found": len(entries),
        "entries": [
            {
                "path": str(e["path"]),
                "char_count": e["char_count"],
                "url_count": len(e["urls"]),
                "existing_status": e["existing_status"],
            }
            for e in entries
        ],
    }
    print(json.dumps(summary, ensure_ascii=False, indent=2))
    return 0


def _cmd_resync(args: argparse.Namespace) -> int:
    """Resync-Variante: Drift-Heilung gegen NotebookLM-Wahrheit."""
    from resync import resync_notebook  # noqa: WPS433

    if not args.notebook:
        print("FEHLER: --notebook <UUID> ist Pflicht für --variant resync.", file=sys.stderr)
        return 2

    state_root = _resolve_path(args.state_root, "KURATOR_STATE_ROOT", None)
    if state_root is None:
        print(
            "FEHLER: --state-root oder KURATOR_STATE_ROOT setzen.",
            file=sys.stderr,
        )
        return 2

    audit_log_path = state_root / "audit-log.md"

    try:
        result = resync_notebook(
            notebook_id=args.notebook,
            state_root=state_root / "state",
            audit_log_path=audit_log_path,
        )
    except RuntimeError as exc:
        print(f"FEHLER: resync abgebrochen — {exc}", file=sys.stderr)
        return 1

    print(json.dumps(
        {
            "variant": "resync",
            **{k: v for k, v in result.items() if not isinstance(v, set)},
        },
        ensure_ascii=False,
        indent=2,
    ))
    return 0


def _cmd_dedup_check_cmd(args: argparse.Namespace) -> int:
    """Dubletten-Variante: Paare erkennen, nicht löschen.

    Wave-D-Stub: liest `source list` über den Helper und schlägt Paare vor.
    Tatsächliches Löschen folgt einem Approval-Gate, das im LLM-
    Agenten-Ablauf passiert (siehe SKILL.md Sicherheitsregel 1).
    """
    from dedup_check import find_duplicates, suggest_keeper  # noqa: WPS433

    if not args.notebook:
        print("FEHLER: --notebook <UUID> ist Pflicht für --variant dedup-check.", file=sys.stderr)
        return 2

    # Source-Liste aus stdin als JSON erwarten (Diagnose-Modus). In der
    # produktiven Pipeline ruft der Agent erst `notebooklm source list`,
    # dann diesen Helper.
    try:
        raw = sys.stdin.read()
        if not raw.strip():
            print(
                "HINWEIS: Erwarte source-list-JSON auf stdin. Beispiel:\n"
                '  echo \'{"sources":[...]}\' | run_kurator.py --variant dedup-check --notebook <id>',
                file=sys.stderr,
            )
            return 2
        payload = json.loads(raw)
    except json.JSONDecodeError as exc:
        print(f"FEHLER: stdin-JSON kaputt: {exc}", file=sys.stderr)
        return 2

    if isinstance(payload, dict) and "sources" in payload:
        sources = payload["sources"]
    elif isinstance(payload, list):
        sources = payload
    else:
        print("FEHLER: stdin-Payload muss {sources: [...]} oder Liste sein.", file=sys.stderr)
        return 2

    pairs = find_duplicates(sources)
    suggestions = [
        {**pair, "suggested_keeper": suggest_keeper(pair, scores=None)}
        for pair in pairs
    ]
    print(json.dumps(
        {
            "variant": "dedup-check",
            "notebook_id": args.notebook,
            "pair_count": len(pairs),
            "pairs": suggestions,
        },
        ensure_ascii=False,
        indent=2,
        default=str,
    ))
    return 0


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(
        description=(
            "CLI-Einstiegspunkt für den notebooklm-kurator-Skill (Wave D, MVP)."
        ),
    )
    parser.add_argument(
        "--variant",
        choices=["standard", "resync", "dedup-check"],
        default="standard",
        help="Welche Variante laufen soll. Default: standard.",
    )
    parser.add_argument(
        "--notebook",
        help="Notebook-UUID (Pflicht für resync und dedup-check).",
    )
    parser.add_argument(
        "--state-root",
        help="Pfad zu kurator_state_root/ (oder KURATOR_STATE_ROOT). Enthält state/ und backups/.",
    )
    parser.add_argument(
        "--register",
        help="Pfad zur NotebookLM-Register-Markdown (oder KURATOR_REGISTER_PATH).",
    )
    parser.add_argument(
        "--inbox",
        help="Pfad zur Inbox-Wurzel (oder KURATOR_INBOX_ROOT).",
    )
    args = parser.parse_args(argv)

    dispatch = {
        "standard": _cmd_standard,
        "resync": _cmd_resync,
        "dedup-check": _cmd_dedup_check_cmd,
    }
    handler = dispatch[args.variant]
    return handler(args)


if __name__ == "__main__":
    raise SystemExit(main())
