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

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

  async function replaceFirstBlockContent(page: any, text: string) {
    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const firstId = blockIds?.[0]
    await page.evaluate(
      ({ bid, t }: { bid: string; t: string }) =>
        window.__testUtils__?.replaceContent(bid, t),
      { bid: firstId, t: text },
    )
  }

  test("bold button wraps selected text in **", async ({ page }) => {
    await replaceFirstBlockContent(page, "bold this")

    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const firstId = blockIds?.[0]
    await page.evaluate(
      ({ bid, from, to }) => window.__testUtils__?.selectText(bid, from, to),
      { bid: firstId, from: 0, to: 9 },
    )

    await page.locator('[data-toolbar-action="bold"]').click()

    const content = await page.evaluate(() =>
      window.__testUtils__?.getContent(),
    )
    expect(content).toContain("**bold this**")
  })

  test("italic button wraps selected text in *", async ({ page }) => {
    await replaceFirstBlockContent(page, "italic this")

    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const firstId = blockIds?.[0]
    await page.evaluate(
      ({ bid, from, to }) => window.__testUtils__?.selectText(bid, from, to),
      { bid: firstId, from: 0, to: 11 },
    )

    await page.locator('[data-toolbar-action="italic"]').click()

    const content = await page.evaluate(() =>
      window.__testUtils__?.getContent(),
    )
    expect(content).toContain("*italic this*")
  })

  test("undo button reverts last change", async ({ page }) => {
    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const firstId = blockIds?.[0]
    await page.evaluate(
      (bid: string) => window.__testUtils__?.focusAtEnd(bid),
      firstId,
    )
    await page.keyboard.type("X")

    const before = await page.evaluate(() => window.__testUtils__?.getContent())

    await page.locator('[data-toolbar-action="undo"]').click()

    const after = await page.evaluate(() => window.__testUtils__?.getContent())
    expect(after).not.toBe(before)
  })

  test("redo button restores undone change", async ({ page }) => {
    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const firstId = blockIds?.[0]
    await page.evaluate(
      (bid: string) => window.__testUtils__?.focusAtEnd(bid),
      firstId,
    )
    await page.keyboard.type("X")

    const beforeUndo = await page.evaluate(() =>
      window.__testUtils__?.getContent(),
    )

    await page.locator('[data-toolbar-action="undo"]').click()
    await page.locator('[data-toolbar-action="redo"]').click()

    const afterRedo = await page.evaluate(() =>
      window.__testUtils__?.getContent(),
    )
    expect(afterRedo).toBe(beforeUndo)
  })

  test("toolbar buttons are visible", async ({ page }) => {
    await expect(page.locator('[data-toolbar-action="bold"]')).toBeVisible()
    await expect(page.locator('[data-toolbar-action="italic"]')).toBeVisible()
    await expect(page.locator('[data-toolbar-action="undo"]')).toBeVisible()
    await expect(page.locator('[data-toolbar-action="redo"]')).toBeVisible()
  })
})
