#!/usr/bin/env python3
from __future__ import annotations
import json, pathlib, subprocess, textwrap

ROOT=pathlib.Path(__file__).resolve().parents[1]
QA=ROOT/'qa_screenshots'
REPORT=ROOT/'assets/data/image-admin/rc47_motion_trace_verification.json'
QA.mkdir(exist_ok=True)
report=json.loads(REPORT.read_text(encoding='utf-8'))

def esc(s):
    return str(s).replace('&','&amp;').replace('<','&lt;').replace('>','&gt;').replace('"','&quot;').replace("'",'&#39;')

def make_html(name,w,h):
    s=report['summary']; iss=s['issues']; crit=report.get('criticalExerciseSummary',{})
    cards=[('Safe w/o visual', 'YES' if report['safeToContinueWithoutVisualTest'] else 'NO'),('Errors',iss.get('error',0)),('Frames',s['frames']),('Sequences',s['sequences']),('Missing anchors',s['missingAnchors']),('Jump errors',s['jumpContactErrors']),('Review holds',s['reviewHoldExercises']),('Active MP anchors',s['activeMediapipeAnchorFrames'])]
    exercises=''.join(f"<div class='ex'><b>{esc(k)}</b><span>{esc(v.get('family',''))}</span><em>{esc(v.get('runtimeGate') or v.get('status') or '')}</em><small>{len(v.get('frames',[]))} frames · anchors: {esc(' → '.join(sorted(set(fr.get('anchor','') for fr in v.get('frames',[])))))}</small></div>" for k,v in crit.items())
    issues=''.join(f"<li class='{esc(i['level'])}'><b>{esc(i['level']).upper()} · {esc(i['code'])}</b> {esc(i['message'])} <code>{esc(i.get('exerciseKey',''))}</code></li>" for i in report.get('issues',[])) or '<li>No issues</li>'
    card_html=''.join(f"<div class='card'><b>{esc(v)}</b><span>{esc(k)}</span></div>" for k,v in cards)
    return f"""<!doctype html><html><head><meta charset='utf-8'><style>
@page {{ size:{w}px {h}px; margin:0; }}
*{{box-sizing:border-box}} body{{margin:0;width:{w}px;height:{h}px;background:linear-gradient(135deg,#061623,#0d2b3b 55%,#05121c);color:#f4fbff;font-family:Inter,system-ui,-apple-system,Segoe UI,sans-serif;overflow:hidden}}.wrap{{padding:{max(20,int(w*.035))}px}}.hero{{border:1px solid rgba(125,211,252,.32);border-radius:26px;padding:22px;background:rgba(12,36,51,.72)}}.eyebrow{{color:#7dd3fc;font-size:13px;text-transform:uppercase;font-weight:900;letter-spacing:.16em}}h1{{font-size:{max(34,int(w*.055))}px;letter-spacing:-.055em;line-height:.95;margin:8px 0 12px}}p{{font-size:{max(15,int(w*.018))}px;color:#cfe7f0;margin:0;max-width:900px}}.grid{{display:grid;grid-template-columns:repeat({2 if w<700 else 4},1fr);gap:12px;margin:18px 0}}.card{{border:1px solid rgba(125,211,252,.2);border-radius:18px;padding:14px;background:rgba(16,47,66,.62)}}.card b{{display:block;font-size:{max(22,int(w*.028))}px;color:#6ee7b7}}.card span{{color:#aecbd8;font-size:12px}}h2{{font-size:{max(20,int(w*.025))}px;margin:18px 0 10px}}.exwrap{{display:grid;grid-template-columns:repeat({1 if w<700 else 2},1fr);gap:10px}}.ex{{border:1px solid rgba(125,211,252,.18);border-radius:16px;background:rgba(16,47,66,.45);padding:12px;min-height:84px}}.ex b{{font-size:16px;display:block}}.ex span{{display:block;color:#9fd6ea;font-size:12px}}.ex em{{font-style:normal;color:#fbbf24;font-size:12px}}.ex small{{display:block;color:#cfe7f0;font-size:12px;margin-top:5px}}ul{{margin:8px 0 0;padding:0;list-style:none}}li{{border:1px solid rgba(125,211,252,.18);padding:10px;border-radius:14px;margin:8px 0;background:rgba(18,56,77,.45);font-size:13px}}li.info{{border-color:rgba(125,211,252,.42)}}code{{background:rgba(0,0,0,.24);border-radius:6px;padding:1px 4px}}.footer{{position:absolute;left:{max(20,int(w*.035))}px;right:{max(20,int(w*.035))}px;bottom:14px;color:#8cb5c4;font-size:12px}}
</style></head><body><div class='wrap'><section class='hero'><div class='eyebrow'>NEXT Pose Atlas · {esc(name)}</div><h1>RC47 Motion Trace Verifier</h1><p>{esc(report['principle'])}</p></section><div class='grid'>{card_html}</div><h2>Critical exercise trace</h2><div class='exwrap'>{exercises}</div><h2>Issues / review holds</h2><ul>{issues}</ul></div><div class='footer'>Static fallback QA · visual app animation not browser-tested in sandbox · {esc(report['createdAt'])}</div></body></html>"""

def render(name,w,h):
    html=QA/f'rc47_{name}_static_qa.html'
    pdf=QA/f'rc47_{name}_static_qa.pdf'
    png_prefix=QA/f'rc47_{name}_static_qa'
    html.write_text(make_html(name,w,h),encoding='utf-8')
    subprocess.run(['weasyprint',str(html),str(pdf)],check=True)
    subprocess.run(['pdftoppm','-png','-singlefile','-r','144',str(pdf),str(png_prefix)],check=True)

for name,w,h in [('mobile',390,844),('ipad',820,1180),('desktop',1180,820)]:
    render(name,w,h)
print('Rendered RC47 static QA screenshots to',QA)
