"""
토치 TCP 정합 자가검증 하네스 (읽기 전용 + 스크린샷)
- 실제 뷰어 엔진(window.__dzw.fk)으로 4자세 TCP 계산 → weld_path.json 진실과 비교
- 스크린샷 캡처
사용: python _verify_tcp.py [태그]
"""
import asyncio, json, sys, math
from playwright.async_api import async_playwright

TAG = sys.argv[1] if len(sys.argv) > 1 else 'base'
URL = 'http://localhost:8090/DOZIKWORKS_OS_v5_locked.dc.html'

wp = json.loads(open(r'E:\도진팩토리\3D스캔및티칭시스템\weld_path.json', encoding='utf-8').read())
arc = [p for p in wp['poses'] if p.get('arc') == 1]
segs = [pt for seg in wp['segs'] for pt in seg]
n = min(len(arc), len(segs))
# 4자세 대표 인덱스 (SEAM 01~04 대표점)
idxs = [0, min(34, n-1), min(63, n-1), min(99, n-1)]
poses4 = [{k: arc[i][k] for k in ['S','L','U','R','B','T']} for i in idxs]
truth4 = [segs[i] for i in idxs]

async def main():
    async with async_playwright() as p:
        br = await p.chromium.launch(channel='msedge', headless=True)
        pg = await br.new_page(viewport={'width':1536,'height':864})
        errs=[]
        pg.on('console', lambda m: errs.append(m.text) if m.type=='error' else None)
        await pg.goto(URL)
        await pg.wait_for_timeout(30000)
        ready = await pg.evaluate("(()=> typeof window.__dzw!=='undefined' && !!window.__dzw.fk)()")
        print('__dzw 준비:', ready)
        if not ready:
            await pg.wait_for_timeout(15000)
        # 실제 엔진으로 4자세 fk
        result = await pg.evaluate("""(poses)=>{
            const a=window.__dzw;
            return poses.map(j=>{ const t=a.fk(j); return [t.x,t.y,t.z]; });
        }""", poses4)
        print(f"\n=== 실제 엔진 fk vs 진실 (태그 {TAG}) ===")
        print(f"tcpOffset(엔진):", await pg.evaluate("(()=>window.__dzw.tcpOffset)()"))
        maxe=0
        for lbl,fk,tr in zip(['SEAM-01','SEAM-02','SEAM-03','SEAM-04'], result, truth4):
            e=math.sqrt(sum((a-b)**2 for a,b in zip(fk,tr)))
            maxe=max(maxe,e)
            print(f"  {lbl}: fk={[round(x,2) for x in fk]}  truth={[round(x,2) for x in tr]}  오차={e:.3f}mm")
        print(f"  ★ 최대오차 {maxe:.3f}mm  →", "통과 ✅" if maxe<0.01 else "실패 ❌")
        # 스크린샷
        await pg.screenshot(path=f'shots/verify_{TAG}_home.png')
        print(f"캡처: shots/verify_{TAG}_home.png")
        print('콘솔에러:', len(errs), errs[:2])
        await br.close()

asyncio.run(main())
