"""
최종 검증:
 req3) fk(weld_path arc 포즈) 점들이 weld_path 오버레이 위에 얹히는가 (274mm→0 증명)
 EditD) 팔 정반 정합 + 토치팁이 용접선에 닿는가 (weld 자세 근접 캡처)
"""
import asyncio, json, sys, math
from playwright.async_api import async_playwright
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=[{k:p[k] for k in ['S','L','U','R','B','T']} for p in wp['poses'] if p.get('arc')==1]
segs=[pt for seg in wp['segs'] for pt in seg]

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(32000)
        # 오버레이 로드 + fk(arc포즈) 점 주입(초록), 오버레이 world와 비교
        out=await pg.evaluate("""async (data)=>{
          const a=window.__dzw, T=a._T, grp=a._grp;
          a.loadWeldPath(); await new Promise(r=>setTimeout(r,2500));
          const mat=new T.MeshBasicMaterial({color:0x22ff44});
          const fkw=[];
          data.arc.forEach(j=>{ const t=a.fk(j); const s=new T.Mesh(new T.SphereGeometry(6,10,8),mat);
            s.position.set(t.x,t.y,t.z); grp.add(s);
            const w=grp.localToWorld(new T.Vector3(t.x,t.y,t.z)); fkw.push([w.x,w.y,w.z]); });
          const ov=(a._icpPathPts||[]).map(pt=>{const w=grp.localToWorld(new T.Vector3(pt.x,pt.y,pt.z));return[w.x,w.y,w.z];});
          return {fkw, ov};
        }""",{'arc':arc})
        fkw=out['fkw']; ov=out['ov']
        d=[min(math.sqrt(sum((x-y)**2 for x,y in zip(pf,po))) for po in ov) for pf in fkw] if ov else []
        if d:
            print(f"req3: fk(weld_path포즈) → 오버레이 최근접 최대 {max(d)*1000:.3f}mm 평균 {sum(d)/len(d)*1000:.3f}mm")
            print("  판정:", "포개짐 ✅ (274mm→0)" if max(d)*1000<1.0 else f"어긋남 {max(d)*1000:.1f}mm")
        # 경로 위에서 캡처
        await pg.evaluate("(()=>{const a=window.__dzw; if(a.orbit){a.orbit.phi=0.35;a.orbit.theta=1.2;a.orbit.r=3.4;a.orbit.tgt={x:0.0,y:0.0,z:0.0};a.updateCam();}})()")
        await pg.wait_for_timeout(1200); await pg.screenshot(path='shots/verify_final_pathoverlay.png')
        # 용접 자세: 팔이 용접선에 닿는지 (SEAM-01 근처 포즈)
        j0=arc[0]
        await pg.evaluate("""(j)=>{const a=window.__dzw; a.setJoints(j);
          if(a.orbit){a.orbit.phi=1.05;a.orbit.theta=0.5;a.orbit.r=2.6;a.orbit.tgt={x:0,y:0,z:0};a.updateCam();}}""",j0)
        await pg.wait_for_timeout(1000); await pg.screenshot(path='shots/verify_final_armweld.png')
        # 전체 측면 (정반 정합)
        await pg.evaluate("(()=>{const a=window.__dzw; a.setJoints({S:0,L:0,U:0,R:0,B:0,T:0}); if(a.orbit){a.orbit.phi=1.45;a.orbit.theta=0.0;a.orbit.r=4.5;a.updateCam();}})()")
        await pg.wait_for_timeout(1000); await pg.screenshot(path='shots/verify_final_side.png')
        print("캡처: verify_final_pathoverlay / armweld / side  콘솔에러", len(errs))
        await br.close()
asyncio.run(main())
