#!/usr/bin/env python3
"""Return a compact agent starting context for a 1C metadata object."""

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 get_1c_form_context import collect_forms, merge_effective as merge_effective_forms  # noqa: E402
from get_1c_object_code_context import (  # noqa: E402
    collect_modules,
    extension_name_from_path,
    merge_effective as merge_effective_modules,
)
from get_1c_object_metadata import build_object_metadata  # noqa: E402
from resolve_1c_object import load_json, resolve_object  # noqa: E402


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


def module_summary(module: dict[str, Any]) -> dict[str, Any]:
    overlays = module.get("extension_overlays") or []
    return {
        "name": module.get("name"),
        "kind": module.get("kind"),
        "origin": module.get("origin"),
        "effective_action": module.get("effective_action"),
        "size": module.get("size"),
        "relative_path": module.get("relative_path"),
        "overlay_count": len(overlays),
        "overlays": [
            {
                "extension": (overlay.get("origin") or {}).get("extension"),
                "effective_action": overlay.get("effective_action"),
                "size": overlay.get("size"),
                "relative_path": overlay.get("relative_path"),
            }
            for overlay in overlays
        ],
    }


def form_summary(form: dict[str, Any]) -> dict[str, Any]:
    overlays = form.get("extension_overlays") or []
    return {
        "name": form.get("name"),
        "synonym": form.get("synonym"),
        "uuid": form.get("uuid"),
        "origin": form.get("origin"),
        "effective_action": form.get("effective_action"),
        "meta_xml_path": form.get("meta_xml_path"),
        "form_xml_path": form.get("form_xml_path"),
        "module_path": form.get("module_path"),
        "overlay_count": len(overlays),
        "overlays": [
            {
                "extension": (overlay.get("origin") or {}).get("extension"),
                "effective_action": overlay.get("effective_action"),
                "uuid": overlay.get("uuid"),
                "form_xml_path": overlay.get("form_xml_path"),
                "module_path": overlay.get("module_path"),
            }
            for overlay in overlays
        ],
    }


def attribute_summary(attribute: dict[str, Any]) -> dict[str, Any]:
    result = {
        "name": attribute.get("name"),
        "synonym": attribute.get("synonym"),
        "type": attribute.get("type"),
        "types": attribute.get("types") or [],
        "origin": attribute.get("origin"),
        "effective_action": attribute.get("effective_action"),
    }
    if attribute.get("is_composite"):
        result["is_composite"] = True
    return {key: value for key, value in result.items() if value not in (None, [], "")}


def extension_names_from_resolution(resolution: dict[str, Any]) -> list[str]:
    names = []
    for overlay in resolution.get("extension_overlays") or []:
        name = extension_name_from_path(overlay.get("path")) or overlay.get("extension_name")
        if name and name not in names:
            names.append(name)
    return names


def view_modules(canonical: dict[str, Any], resolution: dict[str, Any], *, view: str, extension: str | None) -> tuple[list[dict[str, Any]], dict[str, int]]:
    base_modules = collect_modules(canonical.get("path"), source="base")
    extension_modules = []
    for overlay in resolution.get("extension_overlays") or []:
        overlay_extension = extension_name_from_path(overlay.get("path")) or overlay.get("extension_name")
        extension_modules.extend(collect_modules(overlay.get("path"), source="extension", extension_name=overlay_extension))
    if view == "base":
        modules = [{**item, "effective_action": "base"} for item in base_modules]
    elif view == "extension":
        if not extension:
            raise SystemExit("Use --extension with --view extension.")
        modules = [
            {**item, "effective_action": "extended_or_added"}
            for item in extension_modules
            if (item.get("origin") or {}).get("extension") == extension
        ]
    else:
        modules = merge_effective_modules(base_modules, extension_modules)
    return modules, {"modules": len(modules), "base_modules": len(base_modules), "extension_modules": len(extension_modules)}


def view_forms(canonical: dict[str, Any], resolution: dict[str, Any], *, view: str, extension: str | None) -> tuple[list[dict[str, Any]], dict[str, int]]:
    base_forms = collect_forms(canonical.get("path"), source="base")
    extension_forms = []
    for overlay in resolution.get("extension_overlays") or []:
        overlay_extension = extension_name_from_path(overlay.get("path")) or overlay.get("extension_name")
        extension_forms.extend(collect_forms(overlay.get("path"), source="extension", extension_name=overlay_extension))
    if view == "base":
        forms = [{**item, "effective_action": "base"} for item in base_forms]
    elif view == "extension":
        if not extension:
            raise SystemExit("Use --extension with --view extension.")
        forms = [
            {**item, "effective_action": "extended_or_added"}
            for item in extension_forms
            if (item.get("origin") or {}).get("extension") == extension
        ]
    else:
        forms = merge_effective_forms(base_forms, extension_forms)
    return forms, {"forms": len(forms), "base_forms": len(base_forms), "extension_forms": len(extension_forms)}


def build_brief_context(
    index: dict[str, Any],
    *,
    kind: str,
    name: str,
    view: str,
    extension: str | None,
    max_attributes: int,
    max_modules: int,
    max_forms: int,
) -> dict[str, Any]:
    resolution = resolve_object(index, kind=kind, name=name, limit=100)
    canonical = resolution.get("canonical")
    if not canonical:
        raise SystemExit(f"Object not found: {kind}.{name}")

    metadata = build_object_metadata(index, kind=kind, name=name, view=view, extension=extension, include_storage=False)
    modules, module_counts = view_modules(canonical, resolution, view=view, extension=extension)
    forms, form_counts = view_forms(canonical, resolution, view=view, extension=extension)

    attributes = metadata.get("attributes") or []
    tabular_sections = metadata.get("tabular_sections") or []
    extension_names = extension_names_from_resolution(resolution)
    return {
        "schema": "onec_object_brief_context.v1",
        "view": view,
        "extension": extension if view == "extension" else None,
        "object": metadata.get("object"),
        "active_extensions": extension_names,
        "attributes": {
            "items": [attribute_summary(item) for item in attributes[:max_attributes]],
            "total": len(attributes),
            "truncated": len(attributes) > max_attributes,
        },
        "tabular_sections": {
            "items": [
                {
                    "name": item.get("name"),
                    "synonym": item.get("synonym"),
                    "origin": item.get("origin"),
                }
                for item in tabular_sections
            ],
            "total": len(tabular_sections),
        },
        "forms": {
            "items": [form_summary(item) for item in forms[:max_forms]],
            "counts": form_counts,
            "truncated": len(forms) > max_forms,
        },
        "modules": {
            "items": [module_summary(item) for item in modules[:max_modules]],
            "counts": module_counts,
            "truncated": len(modules) > max_modules,
        },
        "next_tools": {
            "metadata": "python scripts/get_1c_object_metadata.py --kind <Kind> --name <Name> --view effective",
            "read_data": "python scripts/read_1c_object_view.py --kind <Kind> --name <Name> --view effective",
            "form": "python scripts/get_1c_form_context.py --kind <Kind> --name <Name> --form <FormName> --view effective",
            "code_context": "python scripts/get_1c_object_code_context.py --kind <Kind> --name <Name> --view effective",
            "module": "python scripts/get_1c_module.py --kind <Kind> --name <Name> --module <ModuleName> --view effective",
        },
        "counts": {
            "attributes": len(attributes),
            "tabular_sections": len(tabular_sections),
            **form_counts,
            **module_counts,
        },
        "resolution": {
            "schema": resolution.get("schema"),
            "canonical": canonical,
            "summary": resolution.get("summary"),
        },
    }


def main() -> int:
    parser = argparse.ArgumentParser(description="Get compact 1C object context for agents.")
    parser.add_argument("--index", type=Path, required=True)
    parser.add_argument("--kind")
    parser.add_argument("--name")
    parser.add_argument("--kind-b64")
    parser.add_argument("--name-b64")
    parser.add_argument("--view", choices=["effective", "base", "extension"], default="effective")
    parser.add_argument("--extension")
    parser.add_argument("--max-attributes", type=int, default=40)
    parser.add_argument("--max-modules", type=int, default=30)
    parser.add_argument("--max-forms", type=int, default=20)
    parser.add_argument("--output", type=Path)
    args = parser.parse_args()

    kind = decode_arg(args.kind, args.kind_b64)
    name = decode_arg(args.name, args.name_b64)
    if not kind or not name:
        raise SystemExit("Use --kind/--name or --kind-b64/--name-b64.")
    result = build_brief_context(
        load_json(args.index),
        kind=kind,
        name=name,
        view=args.view,
        extension=args.extension,
        max_attributes=args.max_attributes,
        max_modules=args.max_modules,
        max_forms=args.max_forms,
    )
    text = 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(text, encoding="utf-8")
        print(json.dumps({"output": str(args.output), "counts": result["counts"], "view": result["view"]}, ensure_ascii=False))
    else:
        print(text)
    return 0


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