#!/usr/bin/env python3
"""T2 300 张 → 12 页盲选页 (25张/页) + GT 明牌 + 优良中差 + 票串.
盲 key 只进本地; 页面零泄底 (slot 编号, 无轴/引擎词)."""
import json, os, shutil, random, csv

ROOT = "/home/kai/shared/virtual-idol/week1"
MD = f"{ROOT}/T2_matrix"
REV = f"{ROOT}/review"
GT = f"{ROOT}/assets/t1_style_final_v1.png"

rows = {int(r["combo_id"]): r for r in csv.DictReader(open(f"{MD}/matrix_300.csv"))}
all_ids = sorted(rows)
rng = random.Random(20261018)
order = all_ids[:]
rng.shuffle(order)  # 全局乱序 → 12页

PAGES = 12
PER = 25
assert len(order) == 300

master_key = {}
for pg in range(PAGES):
    chunk = order[pg*PER:(pg+1)*PER]
    pid = pg + 1
    PAGE = f"{REV}/t2_blind_p{pid:02d}"
    os.makedirs(PAGE, exist_ok=True)
    shutil.copy(GT, f"{PAGE}/GT_anchor.png")
    cards = []
    for i, cid in enumerate(chunk):
        slot = f"slot{i+1:02d}"
        fname = None
        for f in os.listdir(f"{MD}/first20") + os.listdir(f"{MD}/full300"):
            pass
        # find source file
        for d in ("first20", "full300"):
            for f in os.listdir(os.path.join(MD, d)):
                if f.startswith(f"T2_{cid:03d}_"):
                    fname = (d, f)
        d, fname = fname
        shutil.copy(os.path.join(MD, d, fname), os.path.join(PAGE, fname))
        master_key[f"p{pid:02d}:{slot}"] = {"combo_id": cid, "A": rows[cid]["A"], "B": rows[cid]["B"], "C": rows[cid]["C"]}
        cards.append(f"""<div class="card"><div class="slothead">{slot}</div><img src="{fname}" loading="lazy">
<div class="judge"><label><input type="radio" name="{slot}" value="优">优</label><label><input type="radio" name="{slot}" value="良">良</label><label><input type="radio" name="{slot}" value="中">中</label><label><input type="radio" name="{slot}" value="差">差</label></div></div>""")
    page_html = f"""<!DOCTYPE html><html lang="zh"><head><meta charset="utf-8"><title>T2 盲选 {pid}/12</title>
<style>body{{background:#0d1117;color:#e6edf3;font-family:system-ui;margin:0;padding:24px}}h1{{font-size:20px}}
.gt{{border:1px solid #f0883e;border-radius:10px;padding:14px;margin-bottom:20px;background:#161b22}}.gt img{{max-width:340px;border-radius:8px;display:block;margin-top:8px}}
.grid{{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}}
.card{{background:#161b22;border:1px solid #30363d;border-radius:10px;padding:10px}}.card img{{width:100%;border-radius:6px}}
.slothead{{font-weight:700;margin-bottom:6px}}.judge{{display:flex;gap:10px;margin-top:8px;font-size:14px}}.judge label{{cursor:pointer}}
#bar{{position:sticky;bottom:0;background:#0d1117ee;padding:12px 0;border-top:1px solid #30363d}}
textarea{{width:100%;min-height:56px;background:#0d1117;color:#e6edf3;border:1px solid #30363d;border-radius:6px}}
button{{margin-top:8px;background:#238636;color:#fff;border:0;border-radius:6px;padding:8px 18px;font-size:15px;cursor:pointer}}
#tally{{margin-top:8px;font-size:13px;color:#8b949e}}</style></head><body>
<h1>T2 三标签矩阵 · 盲选 {pid}/12（本页 25 张）</h1>
<div class="gt"><b>GT 风格参照板</b>（明牌·禁作候选）：T1 定稿风格锚 —— 判读真值。任务：判「赛博国风×敦煌」命中度与角色辨识度。<img src="GT_anchor.png"></div>
<div class="grid">{''.join(cards)}</div>
<div id="bar"><b>票串（自动生成，复制回传）：</b><textarea id="out" readonly></textarea><button onclick="gen()">生成票串</button><div id="tally">已判 0/25</div></div>
<script>
function gen(){{const cards=[...document.querySelectorAll('.card')];const parts=cards.map(c=>{{const s=c.dataset?c.dataset.slot:c.querySelector('.slothead').textContent;const v=document.querySelector(`input[name="${{s}}"]:checked`);return s+'='+(!v?'—':v.value);}});const n=parts.filter(p=>!p.endsWith('—')).length;document.getElementById('out').value=parts.join(', ')+' | 已判='+n+'/25';document.getElementById('tally').textContent='已判 '+n+'/25';}}
document.querySelectorAll('input[type=radio]').forEach(r=>r.addEventListener('change',gen));
</script></body></html>"""
    open(f"{PAGE}/t2_blind_p{pid:02d}.html", "w").write(page_html)
    print(f"p{pid:02d}: {len(chunk)} cards → {PAGE}")

json.dump(master_key, open(f"{REV}/t2_blind_master_key.json", "w"), ensure_ascii=False, indent=1)
print("master key:", f"{REV}/t2_blind_master_key.json")
