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

test('Thread list recovers after a shell stream defect and reconnect', WEB, async ({ t3, app, screen, browser }) => {
  const project = await t3.project('Stream recovery');
  const thread = await t3.thread({ project, title: 'go', messages: ['go'], model: 'todo-list' });
  await browser.addInitScript(() => {
    const send = WebSocket.prototype.send;
    (window as any).__sockets = [];
    WebSocket.prototype.send = function(data) {
      if (!(window as any).__sockets.includes(this)) (window as any).__sockets.push(this);
      return send.call(this, data);
    };
  });
  await t3.open(thread);
  await screen.getByRole('button', 'go, Stream recovery', { exact: true }).waitFor({ state: 'visible' });
  await screen.getByText('todo list fixture complete', { exact: true }).waitFor({ state: 'visible' });
  writeFileSync(process.env.T3_SHELL_DEFECT_FLAG!, 'inject once');
  await new Promise(resolve => setTimeout(resolve, 1000));
  const { cli } = makeState(T3_HOME);
  await runPromise(cli(['thread', 'send', thread.threadId, 'go again', '--wait', '--json']));
  await browser.evaluate(() => { for (const socket of (window as any).__sockets) if (socket.readyState === WebSocket.OPEN) socket.close(); });
  await t3.thread({ project, title: 'ask me', messages: ['ask me'], model: 'question' });
  await browser.evaluate(() => { document.dispatchEvent(new Event('visibilitychange')); });
  await new Promise(resolve => setTimeout(resolve, 16000));
  await app.screenshot('thread-list-after-reconnect-and-wakeup');
  await expect(screen.getByRole('button', 'ask me', { exact: false })).toBeVisible();
  await expect(screen.getByText('Input', { exact: true })).toBeVisible();
});
