#!/usr/bin/env python3
"""Build a compact movement review summary from candidate browser smoke."""
from __future__ import annotations

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


ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "out"
SOURCE_FILE = "candidate_movement_browser_smoke.json"

TOP_LEVEL_FIELDS = [
    "status",
    "base",
    "url",
    "trace",
    "movementStepSound",
    "movementBump",
    "wallSlideFacing",
    "partyTrailAnimation",
    "fieldPoison",
    "fieldPoisonPartialContinue",
    "fieldPoisonCureContinue",
    "fieldPoisonEffectContinue",
    "fieldParalysisCureContinue",
    "fieldParalysisMovement",
    "fieldParalysisPartialContinue",
    "checksum",
]


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


def build_summary(root: Path = ROOT) -> dict[str, Any]:
    out_dir = root / "out"
    path = out_dir / SOURCE_FILE
    payload = load_json(path)
    movement = {field: payload.get(field) for field in TOP_LEVEL_FIELDS if field in payload}
    movement["snapshots"] = {
        "trace": (payload.get("snapshots") or {}).get("trace") or {},
    }
    movement["sourceFile"] = f"out/{SOURCE_FILE}"
    compact_size = len(json.dumps(movement, ensure_ascii=False, separators=(",", ":")).encode("utf-8"))
    return {
        "kind": "hwanse-movement-candidate-review-summary",
        "source": "tools/summarize_movement_candidate_review.py",
        "status": "ready",
        "sourceFile": f"out/{SOURCE_FILE}",
        "boundary": (
            "Compact browser movement review contract. It keeps movement smoke strings and the "
            "walk trace snapshot used by web/movement_review.html and web/map_occlusion.html; "
            "raw movement smoke remains a build/audit/verifier input until those consumers are replaced."
        ),
        "sourceSizeBytes": path.stat().st_size if path.exists() else 0,
        "compactSizeBytes": compact_size,
        "movement": movement,
    }


def html_page(summary: dict[str, Any]) -> str:
    movement = summary["movement"]
    rows = "\n".join(
        "<tr>"
        f"<td><code>{html.escape(key)}</code></td>"
        f"<td>{html.escape(str(value))[:1000]}</td>"
        "</tr>"
        for key, value in movement.items()
        if key != "snapshots"
    )
    trace = movement.get("snapshots", {}).get("trace", {})
    trace_rows = "\n".join(
        "<tr>"
        f"<td>{html.escape(str(sample.get('label', '-')))}</td>"
        f"<td><code>{html.escape(str(sample.get('selectorHex', '-')))}</code></td>"
        f"<td>{html.escape(str(sample.get('sourceMatchesSelector', '-')))}</td>"
        f"<td>{html.escape(str(sample.get('projectionMatchesDraw', '-')))}</td>"
        "</tr>"
        for sample in trace.get("samples", [])
    )
    return f"""<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <title>Movement Candidate Review Summary</title>
  <style>
    body {{ margin: 24px; color: #202124; font-family: system-ui, sans-serif; line-height: 1.5; }}
    table {{ width: 100%; border-collapse: collapse; margin: 14px 0 28px; }}
    th, td {{ border: 1px solid #d7dce2; padding: 6px 8px; text-align: left; vertical-align: top; }}
    th {{ background: #f4f6f8; }}
    code {{ background: #f4f6f8; padding: 1px 4px; }}
  </style>
</head>
<body>
  <h1>Movement Candidate Review Summary</h1>
  <p>{html.escape(summary['boundary'])}</p>
  <p><code>{html.escape(summary['sourceFile'])}</code>: {int(summary['sourceSizeBytes']):,} bytes raw, {int(summary['compactSizeBytes']):,} bytes compact.</p>
  <h2>Fields</h2>
  <table>
    <thead><tr><th>field</th><th>value</th></tr></thead>
    <tbody>{rows}</tbody>
  </table>
  <h2 id="trace">Trace Samples</h2>
  <table>
    <thead><tr><th>label</th><th>selector</th><th>source rect</th><th>projection</th></tr></thead>
    <tbody>{trace_rows}</tbody>
  </table>
</body>
</html>
"""


def write_outputs(summary: dict[str, Any], out_dir: Path = OUT) -> None:
    out_dir.mkdir(parents=True, exist_ok=True)
    (out_dir / "movement_candidate_review_summary.json").write_text(
        json.dumps(summary, ensure_ascii=False, indent=2) + "\n",
        encoding="utf-8",
    )
    (out_dir / "movement_candidate_review_summary.html").write_text(html_page(summary), encoding="utf-8")


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--root", type=Path, default=ROOT)
    args = parser.parse_args()
    root = args.root.resolve()
    write_outputs(build_summary(root), root / "out")


if __name__ == "__main__":
    main()
