import puppeteer from 'puppeteer-core';
import { spawn } from 'node:child_process';
import net from 'node:net';
const preview = spawn('npx', ['vite','preview','--host','127.0.0.1','--port','4815','--strictPort'], { stdio:'ignore' });
process.on('exit', () => { try{preview.kill()}catch{} });
for (let i=0;i<50;i++){ const ok = await new Promise(r=>{const s=net.connect(4815,'127.0.0.1');s.once('connect',()=>{s.end();r(true)});s.once('error',()=>r(false))}); if(ok)break; await new Promise(r=>setTimeout(r,300)); }
const browser = await puppeteer.launch({ executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', headless: true, args: ['--autoplay-policy=no-user-gesture-required','--mute-audio'] });
const page = await browser.newPage();
await page.setViewport({ width: 960, height: 560 });
page.on('pageerror', e => console.log('[pageerror]', (e.stack||e.message).slice(0,400)));
await page.goto('http://127.0.0.1:4815/', { waitUntil: 'networkidle2' });
await page.waitForFunction('window.__game && window.__director', { timeout: 20000 });
await page.waitForFunction(() => window.__game.scene.isActive('TitleScene'), { timeout: 20000 });
await page.evaluate(() => { document.querySelector('#game input[type="text"]').closest('div').querySelector('button').click(); });
await page.waitForFunction(() => window.__game.scene.isActive('HouseScene'), { timeout: 15000 });
const sleep = (ms) => new Promise(r=>setTimeout(r,ms));
const tap = async (code, hold=90) => { await page.keyboard.down(code); await sleep(hold); await page.keyboard.up(code); await sleep(30); };
await sleep(400);
await page.evaluate(() => {
  window.__dlgLog = [];
  const d = window.__director;
  const origShow = d.showDialogue.bind(d);
  d.showDialogue = (p) => { window.__dlgLog.push(`OPEN 「${(p.lines&&p.lines[0]||'').slice(0,14)}」`); return origShow(p); };
  const origRes = d.resolveDialogue.bind(d);
  d.resolveDialogue = (c) => { window.__dlgLog.push('CLOSE'); return origRes(c); };
  const sm = window.__game.scene;
  for (const sc of sm.getScenes(true)) { const k = sc.scene.key; if (k !== 'UIScene' && k !== 'PlazaScene') sm.stop(k); }
  sm.start('PlazaScene', { spawn: 'default' });
});
await page.waitForFunction(() => window.__game.scene.isActive('PlazaScene'), { timeout: 9000 });
await sleep(500);
for (let i = 0; i < 6; i++) { const o = await page.evaluate(() => { const u = window.__game.scene.getScene('UIScene'); return !!(u && u.payload); }); if (!o) break; await tap('KeyE'); await sleep(250); }
await page.evaluate(() => {
  window.__dlgLog.length = 0;
  const s = window.__game.scene.getScene('PlazaScene');
  const d = s.doors.find(d => d.target === 'fog');
  window.__door = d;
  // 记录 canUseDoor 调用现场
  const origCUD = s.canUseDoor.bind(s);
  s.canUseDoor = (t) => {
    const dd = s.doors.find(x => x.target === t);
    const dist = dd ? Math.hypot(s.player.x - dd.x, (s.player.y - 8) - dd.y) : -1;
    window.__dlgLog.push(`canUseDoor(${t}) dist=${dist.toFixed(1)} armed=${dd ? s.armedDoors.has(dd) : '?'}`);
    return origCUD(t);
  };
  s.player.setPosition(d.x, d.y - 10 + 8);
  s.player.setVelocity(0, 0);
});
await sleep(1200); // 等劝离对话弹出
// 关闭对话
for (let i = 0; i < 6; i++) { const o = await page.evaluate(() => { const u = window.__game.scene.getScene('UIScene'); return !!(u && u.payload); }); if (!o) break; await tap('KeyE'); await sleep(250); }
// 高频采样 3 秒
const samples = await page.evaluate(async () => {
  const s = window.__game.scene.getScene('PlazaScene');
  const d = window.__door;
  const out = [];
  const t0 = Date.now();
  return await new Promise((resolve) => {
    const iv = setInterval(() => {
      const dist = Math.hypot(s.player.x - d.x, (s.player.y - 8) - d.y);
      out.push(`${Date.now() - t0}ms pos=(${s.player.x.toFixed(1)},${s.player.y.toFixed(1)}) body=(${s.player.body.x.toFixed(1)},${s.player.body.y.toFixed(1)}) dist=${dist.toFixed(1)} dlg=${window.__director.dialogueActive} log=${window.__dlgLog.length}`);
      if (Date.now() - t0 > 3000) { clearInterval(iv); resolve(out); }
    }, 100);
  });
});
for (const l of samples) console.log(l);
console.log('LOG:', await page.evaluate(() => window.__dlgLog));
await browser.close();
process.exit(0);
