#!/usr/bin/env python3
"""Build the first agent-facing intake packet for a 1C user task."""

from __future__ import annotations

import argparse
import base64
import json
import sys
from pathlib import Path
from typing import Any

sys.path.insert(0, str(Path(__file__).resolve().parent))
from route_1c_question import route_question  # noqa: E402


ROOT = Path(__file__).resolve().parents[1]
DEFAULT_INDEX = ROOT / "reports" / "1c-sql" / "upo" / "unified-object-route-index.json"


def decode_arg(value: str | None, encoded: str | None) -> str | None:
    if encoded:
        return base64.b64decode(encoded).decode("utf-8")
    return value


def fact_summary(fact_checks: list[dict[str, Any]]) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]:
    confirmed = []
    unresolved = []
    for check in fact_checks:
        result = check.get("result") or {}
        row = {
            "path": check.get("path"),
            "status": check.get("status"),
            "exists": result.get("exists") if result else None,
            "confidence": result.get("confidence"),
            "reason": result.get("reason"),
            "object": result.get("object"),
            "match": result.get("match"),
        }
        if result.get("exists") is True:
            confirmed.append(row)
        else:
            unresolved.append(row)
    return confirmed, unresolved


def next_commands(route: dict[str, Any], *, index: Path, view: str) -> list[dict[str, Any]]:
    commands = []
    decision = route.get("decision") or {}
    if decision.get("needs_docs_rag"):
        commands.append(
            {
                "tool": "docs_rag",
                "purpose": "official_documentation_context",
                "api": "/api/rag/query",
                "payload": {
                    "question": route.get("question"),
                    "source_type": decision.get("safe_rag_scope") or "official_1c_docs",
                    "limit": 5,
                },
            }
        )
    for path in route.get("fact_paths") or []:
        commands.append(
            {
                "tool": "fact_resolver",
                "purpose": "current_configuration_fact",
                "command": f"python scripts/resolve_1c_fact.py --index {index} --path <utf8-base64:{path}> --view {view}",
                "api": "/api/1c/fact",
                "payload": {
                    "source_kind": "route_index",
                    "source_path": str(index),
                    "path": path,
                    "view": view,
                },
            }
        )
    if decision.get("needs_current_config") and not route.get("fact_paths"):
        commands.append(
            {
                "tool": "task_evidence",
                "purpose": "discover_objects_and_relevant_metadata",
                "command": f"python scripts/build_1c_task_evidence.py --index {index} --text <utf8-base64 task> --view {view}",
            }
        )
    return commands


def build_intake(text: str, *, index: Path, view: str) -> dict[str, Any]:
    route = route_question(text, index_path=index, view=view)
    confirmed, unresolved = fact_summary(route.get("fact_checks") or [])
    decision = route.get("decision") or {}
    code_allowed = not unresolved and bool(confirmed or not decision.get("needs_current_config"))
    if decision.get("needs_current_config") and not confirmed and not route.get("fact_paths"):
        code_allowed = False

    return {
        "schema": "onec_agent_intake.v1",
        "task": {"text": text},
        "index": str(index),
        "view": view,
        "route": route,
        "source_policy": {
            "allowed_for_current_facts": ["route_index", "metadata_snapshot_explicit_current", "1c_agent_current"],
            "allowed_for_documentation": ["official_1c_docs"],
            "examples_are_current_facts": False,
            "blocked_as_current_fact_sources": ["metadata.example", "synthetic-example", "rag_examples", "old_exports"],
        },
        "facts": {
            "confirmed": confirmed,
            "unresolved": unresolved,
            "confirmed_count": len(confirmed),
            "unresolved_count": len(unresolved),
        },
        "answer_policy": {
            "code_generation_allowed": code_allowed,
            "must_check_current_config_before_code": bool(decision.get("current_config_required_before_code")),
            "must_not_use_examples_as_facts": True,
            "safe_rag_scope": decision.get("safe_rag_scope"),
        },
        "next_commands": next_commands(route, index=index, view=view),
    }


def main() -> int:
    parser = argparse.ArgumentParser(description="Build first agent intake packet for a 1C task.")
    parser.add_argument("--text")
    parser.add_argument("--text-b64")
    parser.add_argument("--index", type=Path, default=DEFAULT_INDEX)
    parser.add_argument("--view", choices=["effective", "base"], default="effective")
    parser.add_argument("--output", type=Path)
    args = parser.parse_args()

    text = decode_arg(args.text, args.text_b64)
    if not text:
        raise SystemExit("Use --text or --text-b64.")
    result = build_intake(text, index=args.index, view=args.view)
    output = json.dumps(result, ensure_ascii=False, indent=2) + "\n"
    if args.output:
        args.output.parent.mkdir(parents=True, exist_ok=True)
        args.output.write_text(output, encoding="utf-8")
        print(json.dumps({"output": str(args.output), "route": result["route"]["decision"]["route"], "code_allowed": result["answer_policy"]["code_generation_allowed"]}, ensure_ascii=False))
    else:
        print(output)
    return 0


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