from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any
from urllib import request


def rpc(adapter_url: str, method: str, payload: dict[str, Any]) -> dict[str, Any]:
    body = json.dumps({"method": method, "payload": payload}, ensure_ascii=False).encode("utf-8")
    req = request.Request(
        f"{adapter_url.rstrip('/')}/rpc",
        data=body,
        headers={"Content-Type": "application/json; charset=utf-8"},
        method="POST",
    )
    with request.urlopen(req, timeout=240) as resp:
        return json.loads(resp.read().decode("utf-8", errors="replace"))


def latest_configcas_rows(adapter_url: str, base_id: str, limit: int) -> list[dict[str, Any]]:
    result = rpc(
        adapter_url,
        "query.run",
        {
            "base_id": base_id,
            "diagnostic": True,
            "query": f"SELECT TOP {int(limit)} FileName, DATALENGTH(BinaryData) AS Bytes, PartNo, Creation, Modified FROM ConfigCAS ORDER BY Modified DESC",
            "timeout_seconds": 120,
        },
    )
    return result.get("rows") or []


def template_summary(adapter_url: str, base_id: str, file_name: str) -> dict[str, Any]:
    result = rpc(
        adapter_url,
        "templates.map",
        {
            "base_id": base_id,
            "table": "ConfigCAS",
            "file_name": file_name,
            "view": "summary",
            "sections": "cells,styles,named_areas,named_ranges,diagnostics",
            "max_cells": 200,
            "max_areas": 100,
            "timeout_seconds": 120,
        },
    )
    templates = result.get("templates") or []
    if not templates:
        return {}
    return (templates[0] or {}).get("structure") or {}


def compact_signature(item: dict[str, Any]) -> dict[str, Any]:
    data: dict[str, Any] = {}
    for key in (
        "name",
        "kind",
        "text",
        "cell_id",
        "tree_position",
        "range",
        "range_candidate",
        "next_moxel_record",
    ):
        if key in item:
            data[key] = item.get(key)
    style = item.get("style_evidence")
    if isinstance(style, dict):
        compact_style: dict[str, Any] = {}
        for key in ("immediate_preceding_values", "last_7_preceding_values"):
            if key in style:
                compact_style[key] = style.get(key)
        if compact_style:
            data["style_evidence"] = compact_style
    return data


def build_history(
    adapter_url: str,
    base_id: str,
    limit: int,
    track_name: str | None,
    track_text: str | None,
) -> list[dict[str, Any]]:
    rows = latest_configcas_rows(adapter_url, base_id, limit)
    history: list[dict[str, Any]] = []
    for row in rows:
        file_name = str(row.get("FileName") or "")
        byte_count = int(row.get("Bytes") or 0)
        if not file_name or byte_count <= 0 or byte_count > 5000:
            continue
        structure = template_summary(adapter_url, base_id, file_name)
        if str(structure.get("format") or "") != "MOXCEL":
            continue
        item: dict[str, Any] = {
            "file_name": file_name,
            "bytes": byte_count,
            "modified": row.get("Modified"),
            "counts": structure.get("counts") or {},
        }
        if track_name:
            matches = []
            for candidate in structure.get("named_range_candidates") or []:
                if str((candidate or {}).get("name") or "") == track_name:
                    matches.append(compact_signature(candidate))
            item["named_range_matches"] = matches
        if track_text:
            matches = []
            for candidate in structure.get("cell_style_candidates") or []:
                if str((candidate or {}).get("text") or "") == track_text:
                    matches.append(compact_signature(candidate))
            item["text_matches"] = matches
        history.append(item)
    return history


def main() -> int:
    parser = argparse.ArgumentParser(description="Track recent MOXCEL template signatures from live ConfigCAS.")
    parser.add_argument("--adapter-url", default="http://docker.cin.su:8011")
    parser.add_argument("--base-id", default="upo_test")
    parser.add_argument("--limit", type=int, default=12)
    parser.add_argument("--track-name", default="R7C2_TEST")
    parser.add_argument("--track-text", default="Ячейка 7 - 2")
    parser.add_argument("--output", help="Optional JSON output path.")
    args = parser.parse_args()

    history = build_history(args.adapter_url, args.base_id, args.limit, args.track_name, args.track_text)
    payload = {
        "schema": "codex_1c_template_history.v1",
        "adapter_url": args.adapter_url,
        "base_id": args.base_id,
        "track_name": args.track_name,
        "track_text": args.track_text,
        "items": history,
        "counts": {"items": len(history)},
    }
    rendered = json.dumps(payload, ensure_ascii=False, indent=2)
    if args.output:
        Path(args.output).write_text(rendered, encoding="utf-8")
    print(rendered)
    return 0


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