import { expect } from "e2e";
import { test, WEB } from "./t3.ts";

test("Wide terminal glyphs and their cursor stay on the cell grid", WEB, async ({ t3, app, screen, browser }) => {
  const project = await t3.project("terminal-grid");
  await t3.thread({ project, title: "Wide glyph grid", messages: ["Ready"] });
  await t3.open();
  await screen.getByText("Wide glyph grid", { exact: true }).first().tap({ timeout: 120_000 });
  await app.open("/settings/appearance");
  await browser.locator("#typography").getByRole("button", "Advanced").tap();
  await screen.getByRole("switch", "Separate fonts").tap();
  await screen.getByRole("textbox", "Terminal font family").fill("HackGen35 Console NF");
  await screen.getByRole("textbox", "Terminal font family").press("Enter");
  await screen.getByRole("combobox", "Terminal font size").tap();
  await screen.getByRole("option", "18 px", { exact: true }).tap();
  await app.screenshot("terminal-font-settings");
  await screen.getByText("Wide glyph grid", { exact: true }).first().tap({ timeout: 120_000 });
  await screen.getByRole("button", "Toggle terminal drawer").tap();
  const input = browser.locator('canvas:has(+ textarea[aria-label="Terminal input"])');
  await input.tap();
  await browser.keyboard.type("export PS1='$ '; printf '\\033[2 q\\033[2J\\033[H'; printf 'あいうえお¦\\nabcdefghij¦\\n'");
  await browser.keyboard.press("Enter");
  const settle = () => browser.evaluate(async () => {
    const canvas = document.querySelector('textarea[aria-label="Terminal input"]')!.parentElement!.querySelector("canvas")!;
    let prior = "";
    for (let i = 0; i < 20; i++) {
      await new Promise(resolve => setTimeout(resolve, 500));
      const current = canvas.toDataURL();
      if (prior === current) return;
      prior = current;
    }
    throw new Error("Terminal did not settle");
  });
  await settle();
  await app.screenshot("printed-markers");
  const alignment = await browser.evaluate(() => {
    const canvas = document.querySelector('textarea[aria-label="Terminal input"]')!.parentElement!.querySelector("canvas")!;
    const ctx = canvas.getContext("2d")!;
    const { data } = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const rows: { y: number; right: number }[] = [];
    let active = false;
    for (let y = 0; y < Math.min(100, canvas.height); y++) {
      let right = -1;
      for (let x = 0; x < Math.min(300, canvas.width); x++) {
        const i = (y * canvas.width + x) * 4;
        const bg = (y * canvas.width + canvas.width - 1) * 4;
        if (Math.abs(data[i]! - data[bg]!) + Math.abs(data[i + 1]! - data[bg + 1]!) + Math.abs(data[i + 2]! - data[bg + 2]!) > 200) right = x;
      }
      if (right >= 0) {
        if (!active) rows.push({ y, right });
        else rows[rows.length - 1]!.right = Math.max(rows[rows.length - 1]!.right, right);
        active = true;
      } else active = false;
    }
    return { rows, difference: rows.length >= 2 ? Math.abs(rows[0]!.right - rows[1]!.right) : 999 };
  });
  console.log("Printed marker pixels", alignment);
  await input.tap();
  await browser.keyboard.type("echo あいうえお");
  await settle();
  await app.screenshot("unsubmitted-five-kana");
  await browser.keyboard.type("かきくけこ");
  await settle();
  await app.screenshot("unsubmitted-kana");
  await browser.keyboard.press("ArrowLeft");
  await settle();
  await app.screenshot("wide-block-cursor");
  await screen.getByText("Ready", { exact: true }).tap();
  await settle();
  await app.screenshot("wide-outline-cursor");
  await input.tap();
  await browser.keyboard.press("Control+c");
  await browser.keyboard.type("printf '\\033[4 q'");
  await browser.keyboard.press("Enter");
  await browser.keyboard.type("echo あいうえおかきくけこ");
  await browser.keyboard.press("ArrowLeft");
  await settle();
  await app.screenshot("wide-underline-cursor");
  expect(alignment.difference).toBeLessThanOrEqual(1);
});
