import { expect, test } from "@playwright/test"

test.describe("History coalescing", () => {
  test.beforeEach(async ({ page }) => {
    await page.goto("/editor?e2e=true")
  })

  test("rapid typing coalesces into single undo step", async ({ page }) => {
    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const firstId = blockIds?.[0]
    await page.evaluate(
      ({ bid }: { bid: string }) =>
        window.__testUtils__?.replaceContent(bid, "hello"),
      { bid: firstId },
    )
    await page.evaluate(
      ({ bid }: { bid: string }) => window.__testUtils__?.focusAtEnd(bid),
      { bid: firstId },
    )

    const before = await page.evaluate(() => window.__testUtils__?.getContent())
    // Type rapidly — coalesced within same event tick (<500ms apart)
    await page.keyboard.type("xyz")
    const afterType = await page.evaluate(() =>
      window.__testUtils__?.getContent(),
    )
    expect(afterType).not.toBe(before)

    // Single undo reverts all three characters
    await page.locator('[data-toolbar-action="undo"]').click()
    expect(await page.evaluate(() => window.__testUtils__?.getContent())).toBe(
      before,
    )

    // Redo restores them
    await page.locator('[data-toolbar-action="redo"]').click()
    expect(await page.evaluate(() => window.__testUtils__?.getContent())).toBe(
      afterType,
    )
  })

  test("pause >500ms creates separate history entry", async ({ page }) => {
    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const firstId = blockIds?.[0]
    await page.evaluate(
      ({ bid }: { bid: string }) =>
        window.__testUtils__?.replaceContent(bid, "hello"),
      { bid: firstId },
    )
    await page.evaluate(
      ({ bid }: { bid: string }) => window.__testUtils__?.focusAtEnd(bid),
      { bid: firstId },
    )

    const before = await page.evaluate(() => window.__testUtils__?.getContent())
    await page.keyboard.type("a")
    const afterA = await page.evaluate(() => window.__testUtils__?.getContent())
    // Pause beyond 500ms coalescing window
    await page.waitForTimeout(600)
    await page.keyboard.type("b")

    // First undo reverts only "b" (separate history entry)
    await page.locator('[data-toolbar-action="undo"]').click()
    expect(await page.evaluate(() => window.__testUtils__?.getContent())).toBe(
      afterA,
    )

    // Second undo reverts "a"
    await page.locator('[data-toolbar-action="undo"]').click()
    expect(await page.evaluate(() => window.__testUtils__?.getContent())).toBe(
      before,
    )
  })
})
