import asyncio, math
from playwright.async_api import async_playwright

JS = """
() => {
    var app = window.__dzw;
    var T = app && app._T;
    if(!app || !T) return {err:'no app'};
    app._grp.updateMatrixWorld(true);

    // SGN 제거 확인
    var src = (app.poseRobot||'').toString();
    var hasSGN = src.includes('SGN');

    // 홈자세 확인
    var jArr = app.state && app.state.joints;
    var jVals = Array.isArray(jArr) && Array.isArray(jArr[1]) ? jArr[1] : null;
    var home = [-0.12,-63.80,-36.73,0.01,-90.97,-5.53];
    var isHome = jVals && home.every(function(v,i){return Math.abs(jVals[i]-v)<0.05;});

    // FK 4점 검증
    var csvPoses = app._csvPoses || [];
    var arc = csvPoses.filter(function(p){return p.arc===1;});
    var seg = [].concat.apply([], app._weldSegs || []);
    var n = arc.length; var fkMax = 0;
    [0, Math.floor(n/3), Math.floor(n*2/3), n-1].forEach(function(i){
        if(i<0||i>=n) return;
        var fk = app.fk(arc[i]);
        var t = seg[i] || [0,0,0];
        var d = Math.sqrt((fk.x-t[0])*(fk.x-t[0])+(fk.y-t[1])*(fk.y-t[1])+(fk.z-t[2])*(fk.z-t[2]));
        if(d>fkMax) fkMax=d;
    });

    // urdf sign 확인 (건드리지 않았나)
    var D = window.DZW_DATA;
    var urdfSigns = {};
    if(D && D.urdf) D.urdf.forEach(function(u){ urdfSigns[u.a] = u.sign||1; });

    // 로봇 메시 수
    var mc = 0;
    if(app._robotGrp) app._robotGrp.traverse(function(o){if(o.isMesh)mc++;});

    // 콘솔 에러는 Playwright 레벨에서 수집

    return {
        hasSGN: hasSGN,
        isHome: !!isHome,
        jVals: jVals,
        fkMax: +(fkMax.toFixed(4)),
        urdfSigns: urdfSigns,
        meshCount: mc
    };
}
"""

CAMERAS = [
    ('FRONT', -math.pi/2,  math.pi/2*0.6, 3.5),
    ('RIGHT',  0.0,         math.pi/2*0.6, 3.5),
    ('LEFT',   math.pi,     math.pi/2*0.6, 3.5),
    ('TOP',   -math.pi/2,   0.15,          4.0),
]
JS_CAM = """(a)=>{
    var app=window.__dzw; if(!app||!app.orbit)return;
    app.orbit.theta=a.theta; app.orbit.phi=a.phi; app.orbit.r=a.r;
    if(app.orbit.tgt)app.orbit.tgt.set(0,0,0.5);
    if(app.updateCam)app.updateCam();
}"""

async def main():
    async with async_playwright() as p:
        br = await p.chromium.launch(headless=True)
        pg = await br.new_page()
        await pg.set_viewport_size({'width':1536,'height':1024})
        errors = []
        pg.on('console', lambda m: errors.append(m.text) if m.type=='error' else None)
        pg.on('pageerror', lambda e: errors.append(str(e)))
        await pg.goto('http://localhost:8090/DOZIKWORKS_OS_v4_pathcreate.dc.html')
        await pg.wait_for_timeout(22000)

        r = await pg.evaluate(JS)
        if 'err' in r:
            print('ERROR:', r); await br.close(); return

        print('=== SGN 제거 검증 ===')
        print(f'SGN 없음:      {"✅" if not r["hasSGN"] else "❌ SGN 아직 있음"}')
        print(f'홈 자세:       {"✅" if r["isHome"] else "❌"} {r["jVals"]}')
        print(f'FK 4점 오차:   {r["fkMax"]}mm  {"✅" if r["fkMax"]<=1.0 else "❌"}')
        print(f'urdf sign:     {r["urdfSigns"]}  (U/R/B/T=-1 유지됐나 확인)')
        print(f'로봇 메시:     {r["meshCount"]}개  {"✅" if r["meshCount"]<200 else "❌"}')
        print(f'콘솔 에러:     {len(errors)}건  {"✅" if len(errors)==0 else "❌"}')
        if errors: print('  에러:', errors[:3])

        print('\n4방향 스크린샷 촬영...')
        for (name,theta,phi,rv) in CAMERAS:
            await pg.evaluate(JS_CAM, {'theta':theta,'phi':phi,'r':rv})
            await pg.wait_for_timeout(350)
            fn = f'verify_sgn_{name.lower()}.png'
            await pg.screenshot(path=fn)
            print(f'  {name} → {fn}')

        await br.close()

asyncio.run(main())
