import { writeFile } from 'node:fs/promises';
import { expect } from 'e2e';
import { test, WEB } from './t3.ts';
import { T3_HOME } from '../e2e.config.ts';

test('Thread shortcuts survive terminal and macOS composer focus and respect conditions', WEB, async ({t3, app, screen, browser}) => {
  await browser.addInitScript(() => Object.defineProperty(navigator, 'platform', {get: () => 'MacIntel'}));
  await browser.setViewport({width: 1280, height: 800});
  const project = await t3.project('Shortcut demo');
  for (const title of ['First thread', 'Middle thread', 'Last thread'])
    await t3.thread({project, title, messages: ['Navigation demonstration']});
  await writeFile(`${T3_HOME}/userdata/keybindings.json`, JSON.stringify([
    {key:'mod+shift+[',command:'thread.previous'},
    {key:'mod+shift+]',command:'thread.next'},
    {key:'mod+arrowup',command:'thread.previous'},
    {key:'mod+arrowdown',command:'thread.next'},
    {key:'mod+1',command:'thread.jump.1',when:'!modelPickerOpen'},
    {key:'mod+3',command:'thread.jump.3',when:'!modelPickerOpen'},
    {key:'mod+arrowleft',command:'thread.previous',when:'!editableFocus'},
    {key:'mod+arrowright',command:'thread.next',when:'!editableFocus'},
    {key:'mod+shift+arrowleft',command:'thread.previous',when:'isDesktop'},
    {key:'mod+shift+arrowright',command:'thread.next',when:'isDesktop'},
    {key:'x',command:'thread.next',when:'isDesktop'},
    {key:'home',command:'thread.previous'},
    {key:'end',command:'thread.next'},
  ]));
  await t3.open();
  const row = (title: string) => browser.locator(`[data-sidebar-row]:has-text("${title}")`).first();
  const urls: Record<string,string> = {};
  for (const title of ['Last thread','Middle thread','First thread']) {
    await row(title).tap();
    urls[title] = await browser.url();
  }
  const note = async (text: string) => browser.evaluate((text) => {
    let el = document.getElementById('proof-caption');
    if (!el) {el = document.createElement('div'); el.id='proof-caption'; document.body.append(el);}
    el.style.cssText='position:fixed;top:8px;left:320px;right:16px;z-index:99999;background:#15334b;color:white;padding:12px;font:16px sans-serif;pointer-events:none;border:1px solid #80cfff;border-radius:6px';
    el.textContent = text;
  },text);
  const check = async (label: string, title: string) => {
    await expect.soft(browser).toHaveURL(urls[title], {timeout:1200});
    await app.screenshot(label);
  };
  await row('Middle thread').tap();
  // Conceal the shell's machine-specific startup prompt until the synthetic prompt is installed.
  await browser.evaluate(() => {const s=document.createElement('style');s.id='terminal-mask';s.textContent='[data-thread-terminal-drawer] canvas {opacity:0}';document.head.append(s);});
  await browser.keyboard.press('Meta+j');
  const terminal = browser.locator('[data-thread-terminal-drawer] canvas').first();
  await terminal.tap();
  await browser.keyboard.type("export PS1='demo $ '; printf '\\033[2J\\033[H'\n");
  await browser.evaluate(() => document.getElementById('terminal-mask')?.remove());
  await row('Last thread').tap();
  await note('Terminal: Cmd+Shift+] enters Middle; repeat with terminal focused → First');
  await browser.keyboard.press('Meta+Shift+]');
  await check('01-enter-middle-terminal','Middle thread');
  await browser.keyboard.press('Meta+Shift+]');
  await check('02-terminal-next','First thread');
  await row('Middle thread').tap(); await terminal.tap();
  await note('Terminal: Cmd+Shift+[ with terminal focused → Last');
  await browser.keyboard.press('Meta+Shift+[');
  await check('03-terminal-previous','Last thread');
  await row('Middle thread').tap(); await terminal.tap();
  await note('Terminal: Cmd+1 with terminal focused → Last (numbered jump)');
  await browser.keyboard.press('Meta+1');
  await check('04-terminal-numbered-jump','Last thread');
  await row('Middle thread').tap(); await terminal.tap();
  await note('Terminal: x is bound only for isDesktop; web stays Middle and types x normally');
  const beforeInput = await browser.evaluate(() => (document.querySelector('[data-thread-terminal-drawer] canvas') as HTMLCanvasElement).toDataURL());
  await browser.keyboard.press('x');
  await expect.poll(() => browser.evaluate(() => (document.querySelector('[data-thread-terminal-drawer] canvas') as HTMLCanvasElement).toDataURL())).not.toBe(beforeInput);
  await check('05-terminal-condition-excluded','Middle thread');
  await browser.keyboard.press('Control+u');
  await browser.keyboard.press('Meta+j');
  await row('Last thread').tap();
  await screen.getByText('first fixture turn complete', {exact:true}).tap();
  await note('Composer control: click outside composer, Cmd+Down → Middle');
  await browser.keyboard.press('Meta+ArrowDown');
  await check('06-composer-unfocused-control','Middle thread');
  const editor=browser.locator('[contenteditable="true"][role="textbox"]').first();
  await editor.fill('alpha beta\ngamma delta');
  await note('macOS composer focused: Cmd+Down → First');
  await browser.keyboard.press('Meta+ArrowDown');
  await check('07-composer-next','First thread');
  await row('Middle thread').tap(); await editor.fill('alpha beta\ngamma delta');
  await note('macOS composer focused: Cmd+Up → Last');
  await browser.keyboard.press('Meta+ArrowUp');
  await check('08-composer-previous','Last thread');
  await row('Middle thread').tap(); await editor.fill('alpha beta\ngamma delta');
  await note('macOS composer focused: Cmd+3 → First (numbered jump)');
  await browser.keyboard.press('Meta+3');
  await check('09-composer-numbered-jump','First thread');
  await row('Middle thread').tap(); await editor.fill('alpha beta\ngamma delta');
  await note('macOS composer: End bound to next → First');
  await browser.keyboard.press('End');
  await check('10-composer-end','First thread');
  await row('Middle thread').tap(); await editor.fill('alpha beta\ngamma delta');
  await note('macOS composer: Home bound to previous → Last');
  await browser.keyboard.press('Home');
  await check('11-composer-home','Last thread');
  await row('Middle thread').tap(); await editor.fill('alpha beta\ngamma delta');
  await note('Condition !editableFocus excludes Cmd+Left/Right: stays Middle; caret moves to line boundaries');
  await browser.keyboard.press('Meta+ArrowLeft');
  const left = await browser.evaluate(() => window.getSelection()?.anchorOffset);
  await browser.keyboard.press('Meta+ArrowRight');
  const right = await browser.evaluate(() => window.getSelection()?.anchorOffset);
  expect.soft(left).toBe(0); expect.soft(right).toBe(11);
  await browser.keyboard.press('Meta+ArrowLeft');
  await browser.keyboard.press('Meta+Shift+ArrowRight');
  expect.soft(await browser.evaluate(() => window.getSelection()?.toString())).toBe('gamma delta');
  await check('12-composer-condition-excluded','Middle thread');
});
