#!/usr/bin/env python3
"""Render one-shot 1C saved-state watch manifest as Markdown."""

from __future__ import annotations

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


def load_json(path: Path) -> dict[str, Any]:
    return json.loads(path.read_text(encoding="utf-8-sig"))


def line(text: str = "") -> str:
    return text.rstrip() + "\n"


def bullet(text: str) -> str:
    return f"- {text}\n"


def code(value: Any) -> str:
    if value is None:
        return "`null`"
    return f"`{value}`"


def linked_path(manifest_path: Path, value: Any) -> Path | None:
    if not value:
        return None
    path = Path(str(value))
    if path.is_absolute():
        return path
    return (manifest_path.parent / path).resolve()


def render_delta_summary(manifest_path: Path, manifest: dict[str, Any]) -> str:
    delta_path = linked_path(manifest_path, manifest.get("delta"))
    if not delta_path or not delta_path.exists():
        return ""
    delta = load_json(delta_path)
    objects = delta.get("objects") or {}
    changed = objects.get("changed") or []
    added = objects.get("added") or []
    removed = objects.get("removed") or []
    if not changed and not added and not removed:
        return ""
    out = line()
    out += line("## Delta Objects")
    for item in added:
        out += bullet(f"Added {code(item.get('full_name'))}")
    for item in removed:
        out += bullet(f"Removed {code(item.get('full_name'))}")
    for item in changed:
        out += bullet(f"Changed {code(item.get('full_name'))}")
        term_delta = item.get("term_delta") or {}
        added_terms = ((term_delta.get("added_terms") or {}).get("added") or [])
        removed_terms = ((term_delta.get("removed_terms") or {}).get("added") or [])
        if added_terms:
            out += f"  New added terms: {', '.join(code(value) for value in added_terms)}\n"
        if removed_terms:
            out += f"  New removed terms: {', '.join(code(value) for value in removed_terms)}\n"
        for part in (item.get("part_delta") or {}).get("changed") or []:
            before = part.get("before") or {}
            after = part.get("after") or {}
            out += (
                f"  Part changed: {code(part.get('file_name'))}, "
                f"role={code(after.get('payload_role'))}, "
                f"delta_chars {code(before.get('delta_chars'))}->{code(after.get('delta_chars'))}\n"
            )
    return out


def render(manifest_path: Path, manifest: dict[str, Any]) -> str:
    counts = manifest.get("counts") or {}
    safety = manifest.get("safety") or {}
    out = ""
    out += line("# 1C Saved State Watch Run")
    out += line()
    out += line(f"Database: `{manifest.get('database')}`")
    out += line(f"Run dir: `{manifest.get('run_dir')}`")
    out += line(f"Previous report: `{manifest.get('previous_report')}`")
    out += line()
    out += line("## Artifacts")
    for key in ("report", "markdown", "check", "manifest_check", "delta", "delta_markdown", "delta_check"):
        if manifest.get(key):
            out += bullet(f"{key}: `{manifest.get(key)}`")
    out += line()
    out += line("## Counts")
    for key in (
        "object_changes",
        "system_changes",
        "delta_objects_added",
        "delta_objects_removed",
        "delta_objects_changed",
        "delta_objects_unchanged",
    ):
        out += bullet(f"{key}: `{counts.get(key)}`")
    out += render_delta_summary(manifest_path, manifest)
    out += line()
    out += line("## Safety")
    for key in ("read_only", "sql_write_performed", "secrets_in_report"):
        out += bullet(f"{key}: `{safety.get(key)}`")
    return out


def main() -> int:
    parser = argparse.ArgumentParser(description="Render one-shot 1C saved-state watch Markdown.")
    parser.add_argument("--manifest", type=Path, required=True)
    parser.add_argument("--output", type=Path)
    args = parser.parse_args()

    markdown = render(args.manifest, load_json(args.manifest))
    if args.output:
        args.output.parent.mkdir(parents=True, exist_ok=True)
        args.output.write_text(markdown, encoding="utf-8")
        print(json.dumps({"output": str(args.output)}, ensure_ascii=False))
    else:
        print(markdown)
    return 0


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