import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        br = await p.chromium.launch(headless=False, args=['--start-maximized'])
        pg = await br.new_page()
        # 16:9 1920x1080 시뮬레이션
        await pg.set_viewport_size({'width':1920,'height':1080})

        errors = []
        pg.on('pageerror', lambda e: errors.append(f'PAGEERROR:{str(e)[:200]}'))
        pg.on('console', lambda m: errors.append(f'[{m.type}]{m.text[:200]}') if m.type=='error' else None)

        await pg.goto('http://localhost:8090/DOZIKWORKS_OS_v4_pathcreate.dc.html')
        print('로드 중 (1920x1080)...')
        await pg.wait_for_timeout(15000)

        real_errors = [e for e in errors if 'favicon' not in e.lower()]
        print(f'콘솔 에러(favicon 제외): {len(real_errors)}개')
        for e in real_errors: print(f'  {e}')

        r = await pg.evaluate("""() => {
            const app = window.__dzw;
            if (!app) return {error:'__dzw 없음'};
            const rnd = app.three && app.three.rnd;
            const cam = app.three && app.three.cam;
            const frame = app.frameEl;
            return {
                frameW: frame ? frame.clientWidth : 0,
                frameH: frame ? frame.clientHeight : 0,
                frameTransform: frame ? frame.style.transform : '',
                rendererW: rnd ? rnd.domElement.width : 0,
                rendererH: rnd ? rnd.domElement.height : 0,
                camAspect: cam ? +cam.aspect.toFixed(4) : 0,
                expectedAspect: +(1920/1080).toFixed(4),
                tcAlive: !!(app._tc && typeof app._tc.setMode==='function'),
                scale: app._scale,
            };
        }""")
        print('\n=== 화면 크기 확인 (1920x1080) ===')
        print(f'  frame 크기: {r.get("frameW")}×{r.get("frameH")} (기대: 1920×1080)')
        print(f'  frame transform: "{r.get("frameTransform")}" (비어있어야 정상)')
        print(f'  renderer 크기: {r.get("rendererW")}×{r.get("rendererH")}')
        print(f'  cam.aspect: {r.get("camAspect")} (기대: {r.get("expectedAspect")})')
        print(f'  _scale: {r.get("scale")} (기대: 1)')
        print(f'  기즈모: {r.get("tcAlive")}')

        # aspect 오차
        diff = abs((r.get('camAspect') or 0) - (r.get('expectedAspect') or 0))
        print(f'  aspect 오차: {diff:.4f} (0.01 이내면 정상)')

        # FK 4점
        fk = await pg.evaluate("""async () => {
            const app = window.__dzw;
            const r = await fetch('/weld_path.json'); const wp = await r.json();
            const arc = wp.poses.filter(p=>p.arc===1), seg = wp.segs.flat(), n=arc.length;
            return [0,Math.floor(n/3),Math.floor(n*2/3),n-1].map(i=>{
                const f=app.fk(arc[i]),t=seg[i];
                return {idx:i,dist:+Math.sqrt((f.x-t[0])**2+(f.y-t[1])**2+(f.z-t[2])**2).toFixed(4)};
            });
        }""")
        print(f'\nFK 4점: {fk}')
        fk_ok = isinstance(fk,list) and all(x['dist']<=1.0 for x in fk)
        print(f'FK 합격: {"✅" if fk_ok else "❌"}')

        await pg.screenshot(path='fullscreen_1920.png', full_page=False)
        print('\n스크린샷 → fullscreen_1920.png')

        # resize 시험: 1280x720 으로 바꾸기
        await pg.set_viewport_size({'width':1280,'height':720})
        await pg.wait_for_timeout(1500)

        r2 = await pg.evaluate("""() => {
            const app=window.__dzw, cam=app&&app.three&&app.three.cam, rnd=app&&app.three&&app.three.rnd;
            return {
                rendererW: rnd?rnd.domElement.width:0, rendererH: rnd?rnd.domElement.height:0,
                camAspect: cam?+cam.aspect.toFixed(4):0, expected:+(1280/720).toFixed(4),
            };
        }""")
        diff2 = abs((r2.get('camAspect') or 0)-(r2.get('expected') or 0))
        print(f'\n=== resize 후 (1280x720) ===')
        print(f'  renderer: {r2.get("rendererW")}×{r2.get("rendererH")} (기대: 1280×720)')
        print(f'  aspect: {r2.get("camAspect")} vs 기대 {r2.get("expected")} (오차 {diff2:.4f})')
        print(f'  resize 따라옴: {"✅" if diff2<0.05 else "❌"}')

        await pg.screenshot(path='fullscreen_1280.png', full_page=False)
        print('스크린샷 → fullscreen_1280.png')

        # 요약
        frame_ok = r.get('frameW')==1920 and r.get('frameH')==1080
        aspect_ok = diff < 0.05
        print(f'\n=== 요약 ===')
        print(f'  frame 꽉 채움: {"✅" if frame_ok else "❌"} ({r.get("frameW")}×{r.get("frameH")})')
        print(f'  aspect 정확: {"✅" if aspect_ok else "❌"} (오차 {diff:.4f})')
        print(f'  기즈모: {"✅" if r.get("tcAlive") else "❌"}')
        print(f'  FK 4점: {"✅" if fk_ok else "❌"}')
        print(f'  콘솔 에러: {"✅ 0건" if len(real_errors)==0 else "❌ "+str(len(real_errors))+"건"}')

        all_ok = frame_ok and aspect_ok and r.get('tcAlive') and fk_ok
        print(f'\n결론: {"✅ 16:9 꽉참+무손상" if all_ok else "❌ 문제 있음"}')

        await br.close()

asyncio.run(main())
