"""Step 1~4를 같은 슬라이드 레이아웃 위에 레이어로 쌓아 PNG 생성."""
import json, urllib.parse, time, sys
from pathlib import Path

sys.path.insert(0, ".")

run_dir = Path("data/runs/20260402_091318")

ctx_1a = json.loads((run_dir / "stage_1a_context.json").read_text(encoding="utf-8"))
ctx_1b = json.loads((run_dir / "stage_1b_context.json").read_text(encoding="utf-8"))
ctx_15a = json.loads((run_dir / "stage_1_5a_context.json").read_text(encoding="utf-8"))
ctx_17 = json.loads((run_dir / "stage_1_7_context.json").read_text(encoding="utf-8"))
ctx_15b = json.loads((run_dir / "stage_1_5b_context.json").read_text(encoding="utf-8"))

topics = ctx_1b.get("topics", [])
containers = ctx_15a.get("containers", {})
fh = ctx_15a.get("font_hierarchy", {})
ratio = ctx_15a.get("container_ratio", [72, 28])
refs = ctx_17.get("references", {})
ps = ctx_1a.get("page_structure", {})
if "roles" in ps:
    ps = ps["roles"]
containers_b = ctx_15b.get("containers", {})
topic_map = {t["id"]: t for t in topics}

slide_w, slide_h = 1280, 720
pad = 40
header_h = 66
gap = 20
footer_h = containers.get("결론", {}).get("height_px", 60)
inner_w = slide_w - pad * 2
body_pct = ratio[0] if ratio else 72
sidebar_pct = ratio[1] if len(ratio) > 1 else 28
body_w = int(inner_w * body_pct / 100)
sidebar_w = inner_w - body_w - gap
body_zone_h = slide_h - pad * 2 - header_h - footer_h - gap * 2
bg_h = containers.get("배경", {}).get("height_px", 117)
core_h = body_zone_h - bg_h - 12

L = {
    "배경": {"x": pad, "y": pad+header_h+gap, "w": body_w, "h": bg_h},
    "본심": {"x": pad, "y": pad+header_h+gap+bg_h+12, "w": body_w, "h": core_h},
    "첨부": {"x": pad+body_w+gap, "y": pad+header_h+gap, "w": sidebar_w, "h": body_zone_h},
    "결론": {"x": pad, "y": slide_h-pad-footer_h, "w": inner_w, "h": footer_h},
}
C = {"배경": "#dc2626", "본심": "#2563eb", "첨부": "#16a34a", "결론": "#7c3aed"}


def area(role, inner):
    p = L[role]; c = C[role]
    return (f'<div style="position:absolute;left:{p["x"]}px;top:{p["y"]}px;'
            f'width:{p["w"]}px;height:{p["h"]}px;border:2px solid {c};'
            f'border-radius:6px;overflow:hidden;background:{c}08;'
            f'padding:6px;font-size:9px;line-height:1.4;">{inner}</div>')


def header(title):
    return (f'<div style="position:absolute;left:{pad}px;top:{pad}px;width:{inner_w}px;'
            f'height:{header_h}px;background:#f8fafc;border-bottom:3px solid #2563eb;'
            f'display:flex;align-items:center;padding:0 20px;font-size:22px;'
            f'font-weight:900;color:#1e293b;">건설산업 DX의 올바른 이해</div>')


def slide(step_title, areas_html):
    return (f'<!DOCTYPE html><html><head><meta charset="UTF-8">'
            f'<style>*{{margin:0;padding:0;box-sizing:border-box;}}'
            f'body{{background:#e5e5e5;padding:10px;font-family:sans-serif;}}</style></head><body>'
            f'<div style="font-size:14px;font-weight:bold;margin-bottom:6px;">{step_title}</div>'
            f'<div style="width:{slide_w}px;height:{slide_h}px;background:white;'
            f'position:relative;border:1px solid #ccc;">'
            f'{header(step_title)}{areas_html}</div></body></html>')


# Step 1
a1 = ""
for role in L:
    c = C[role]; p = L[role]
    fk = {"배경":"bg","본심":"core","첨부":"sidebar","결론":"key_msg"}.get(role,"core")
    fv = fh.get(fk, 12)
    a1 += area(role,
        f'<div style="text-align:center;margin-top:{p["h"]//2-15}px;">'
        f'<b style="color:{c};font-size:13px;">{role}</b><br>'
        f'<span style="color:#888;font-size:10px;">{p["w"]}x{p["h"]}px / font:{fv}px</span></div>')

# Step 2
a2 = ""
for role in L:
    c = C[role]; info = ps.get(role, {}); tids = info.get("topic_ids", [])
    w = info.get("weight", 0)
    inner = f'<div style="font-size:8px;color:{c};font-weight:bold;">{role} (w:{w})</div>'
    for tid in tids:
        t = topic_map.get(tid, {})
        inner += (f'<div style="background:white;border:1px solid #ddd;border-radius:3px;'
                  f'padding:3px;margin:2px 0;">'
                  f'<b style="font-size:8px;">T{tid}: {t.get("title","")[:25]}</b><br>'
                  f'<span style="font-size:7px;color:#888;">'
                  f'{t.get("purpose","")} / {t.get("relation_type","")}</span></div>')
    a2 += area(role, inner)

# Step 3
a3 = ""
for role in L:
    c = C[role]; ref = refs.get(role, {}); p = L[role]
    bid = ref.get("block_id", "?"); vtype = ref.get("visual_type", "?")
    info = ps.get(role, {}); tids = info.get("topic_ids", [])
    tnames = ", ".join(f"T{tid}" for tid in tids)
    mt = max(0, p["h"]//2-25)
    a3 += area(role,
        f'<div style="text-align:center;margin-top:{mt}px;">'
        f'<div style="font-size:9px;color:{c};">{role} ({tnames})</div>'
        f'<div style="font-size:14px;margin:2px 0;">📦</div>'
        f'<div style="font-size:11px;font-weight:bold;">{bid}</div>'
        f'<div style="font-size:8px;color:#888;">type: {vtype}</div></div>')

# Step 4
a4 = ""
for role in L:
    c = C[role]; ref = refs.get(role, {}); p = L[role]
    bid = ref.get("block_id", "?")
    cb = containers_b.get(role, {}); db = cb.get("design_budget") or {}
    text_h = db.get("text_height_px", 0)
    avail_h = db.get("available_height_px", 0)
    fits = db.get("fits", False)
    total = max(text_h + avail_h, 1)
    tp = int(text_h / total * 100)
    bw = p["w"] - 20
    fc = "green" if fits else "red"
    a4 += area(role,
        f'<div style="padding:2px;">'
        f'<div style="font-size:9px;color:{c};font-weight:bold;">{role}: {bid}</div>'
        f'<div style="display:flex;height:14px;border-radius:3px;overflow:hidden;margin:4px 0;width:{bw}px;">'
        f'<div style="width:{tp}%;background:#ff6b6b;font-size:7px;color:white;text-align:center;line-height:14px;">텍스트{text_h}px</div>'
        f'<div style="width:{100-tp}%;background:#51cf66;font-size:7px;color:white;text-align:center;line-height:14px;">여유{avail_h}px</div>'
        f'</div>'
        f'<div style="font-size:8px;color:{fc};font-weight:bold;">fits:{fits} / {p["w"]}x{p["h"]}px</div></div>')

htmls = {
    "viz_1_containers": slide(f"Step 1: 컨테이너 포션과 위치 (비율 {body_pct}:{sidebar_pct})", a1),
    "viz_2_content": slide("Step 2: 각 영역별 내용 배치", a2),
    "viz_3_blocks": slide("Step 3: 블록 선택 결과", a3),
    "viz_4_budget": slide("Step 4: 블록별 디자인 예산", a4),
}

for name, html in htmls.items():
    (run_dir / f"{name}.html").write_text(html, encoding="utf-8")

# PNG
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

opts = Options()
opts.add_argument("--headless")
opts.add_argument("--no-sandbox")
opts.add_argument("--force-device-scale-factor=2")
driver = webdriver.Chrome(options=opts)
driver.set_window_size(1380, 820)

for name in htmls:
    html = (run_dir / f"{name}.html").read_text(encoding="utf-8")
    encoded = urllib.parse.quote(html, safe="")
    driver.get(f"data:text/html;charset=utf-8,{encoded}")
    time.sleep(2)
    driver.save_screenshot(str(run_dir / f"{name}.png"))
    print(f"{name}.png")

driver.quit()
print("완료")
