import { expect, test } from "@playwright/test"
import { focusLastBlockAtEnd } from "./helpers"

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

  test("triple backtick creates a code block", async ({ page }) => {
    await focusLastBlockAtEnd(page)
    await page.keyboard.press("Enter")
    await page.keyboard.type("```")

    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const lastId = blockIds?.[blockIds?.length - 1]
    const codeBlock = page.locator(
      `[role="textbox"][data-block-id="${lastId}"] [data-codeblock-editor]`,
    )
    await expect(codeBlock).toBeVisible({ timeout: 5000 })
  })

  test("typing in code block updates content", async ({ page }) => {
    await focusLastBlockAtEnd(page)
    await page.keyboard.press("Enter")
    await page.keyboard.type("```")

    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const lastId = blockIds?.[blockIds?.length - 1]

    const codeBlock = page.locator(
      `[role="textbox"][data-block-id="${lastId}"] [data-codeblock-editor]`,
    )
    await expect(codeBlock).toBeVisible({ timeout: 5000 })
    await codeBlock.locator(".cm-content").click()
    await page.keyboard.type("const x = 1;")

    const content = await page.evaluate(() =>
      window.__testUtils__?.getContent(),
    )
    expect(content).toContain("const x = 1;")
  })

  test("code block content is wrapped in fences", async ({ page }) => {
    await focusLastBlockAtEnd(page)
    await page.keyboard.press("Enter")
    await page.keyboard.type("```")

    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const lastId = blockIds?.[blockIds?.length - 1]

    const codeBlock = page.locator(
      `[role="textbox"][data-block-id="${lastId}"] [data-codeblock-editor]`,
    )
    await expect(codeBlock).toBeVisible({ timeout: 5000 })
    await codeBlock.locator(".cm-content").click()
    await page.keyboard.type("const x = 1;")

    const content = await page.evaluate(() =>
      window.__testUtils__?.getContent(),
    )
    expect(content).toContain("```")
    expect(content).toContain("const x = 1;")
  })

  test("ArrowUp at code block start exits to paragraph above", async ({
    page,
  }) => {
    await focusLastBlockAtEnd(page)
    await page.keyboard.press("Enter")
    await page.keyboard.type("paragraph above")
    await page.keyboard.press("Enter")
    await page.keyboard.type("```")

    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const lastId = blockIds?.[blockIds?.length - 1]

    const codeBlock = page.locator(
      `[role="textbox"][data-block-id="${lastId}"] [data-codeblock-editor]`,
    )
    await expect(codeBlock).toBeVisible({ timeout: 5000 })
    await codeBlock.locator(".cm-content").click()

    // ArrowUp should exit the code block to the previous block
    await page.keyboard.press("ArrowUp")
    await page.waitForTimeout(100)

    // Type should go to the paragraph above
    await page.keyboard.type(" added above")

    const content = await page.evaluate(() =>
      window.__testUtils__?.getContent(),
    )
    expect(content).toContain("paragraph above added above")
  })

  test("empty code block removed by Backspace", async ({ page }) => {
    await focusLastBlockAtEnd(page)
    await page.keyboard.press("Enter")
    await page.keyboard.type("```")

    const blockIds = await page.evaluate(() =>
      window.__testUtils__?.getBlockIds(),
    )
    const lastId = blockIds?.[blockIds?.length - 1]
    const scoped = `[role="textbox"][data-block-id="${lastId}"]`

    const codeBlock = page.locator(`${scoped} [data-codeblock-editor]`)
    await expect(codeBlock).toBeVisible({ timeout: 5000 })
    await codeBlock.locator(".cm-content").click()

    // Backspace in empty code block should remove it
    await page.keyboard.press("Backspace")
    await page.waitForTimeout(100)

    await expect(
      page.locator(`${scoped} [data-codeblock-editor]`),
    ).not.toBeVisible()
  })
})
