"use strict";

const { chromium } = require("playwright");
const {
  BASE_URL,
  UI_TIMEOUT_MS,
  assert,
  cleanupDocuments,
  ensureAuthenticated,
  prepareTempTreeFixture,
  openDocument,
  requireMnoteWebSmokeBaseUrl,
} = require("./tree-shell-smoke-helpers");

async function openRuntimeDebug(page, fixture) {
  const runtimeBaseUrl = requireMnoteWebSmokeBaseUrl();
  await page.goto(`${BASE_URL}/api/auth/mnote-web-token`, { waitUntil: "commit", timeout: UI_TIMEOUT_MS });
  await page.goto(
    `${runtimeBaseUrl}/document-debug?documentId=${fixture.parentId}&workspaceId=${fixture.workspaceId}&host=task105-smoke`,
    { waitUntil: "commit", timeout: UI_TIMEOUT_MS },
  );
  await page.getByText("Document Runtime Debug").waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
}

async function main() {
  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    viewport: { width: 1440, height: 960 },
  });
  const page = await context.newPage();

  let fixture = null;
  let caughtError = null;

  try {
    await ensureAuthenticated(page, context.request);
    fixture = await prepareTempTreeFixture(context.request);
    await openDocument(page, fixture.workspaceId, fixture.parentId);
    await openRuntimeDebug(page, fixture);

    const firstTextarea = page.locator("textarea[data-block-input-id]").first();
    await firstTextarea.waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
    await firstTextarea.fill("AlphaBeta", { timeout: UI_TIMEOUT_MS });

    await firstTextarea.evaluate((node) => {
      node.setSelectionRange(5, 5);
    });
    await firstTextarea.press("Enter", { timeout: UI_TIMEOUT_MS });

    const textareas = page.locator("textarea[data-block-input-id]");
    await textareas.nth(1).waitFor({ state: "visible", timeout: UI_TIMEOUT_MS });
    assert((await textareas.count()) === 2, "Enter 拆块后未出现第二个输入块");
    assert((await textareas.nth(0).inputValue()) === "Alpha", "拆块后首块文本不正确");
    assert((await textareas.nth(1).inputValue()) === "Beta", "拆块后次块文本不正确");

    await textareas.nth(1).press("Tab", { timeout: UI_TIMEOUT_MS });
    await page.locator(".editor-row-meta").nth(1).getByText("depth=1").waitFor({
      state: "visible",
      timeout: UI_TIMEOUT_MS,
    });

    await textareas.nth(1).press("Shift+Tab", { timeout: UI_TIMEOUT_MS });
    await page.locator(".editor-row-meta").nth(1).getByText("depth=0").waitFor({
      state: "visible",
      timeout: UI_TIMEOUT_MS,
    });

    await textareas.nth(1).evaluate((node) => {
      node.setSelectionRange(0, 0);
    });
    await textareas.nth(1).press("Backspace", { timeout: UI_TIMEOUT_MS });

    assert((await page.locator("textarea[data-block-input-id]").count()) === 1, "合并后块数量未回到 1");
    assert(
      (await page.locator("textarea[data-block-input-id]").first().inputValue()) === "AlphaBeta",
      "Backspace 合并后文本不正确",
    );
    const saveStatus = ((await page.locator("#editor-save-status").textContent()) || "").trim().toLowerCase();
    assert(
      saveStatus === "saved" || saveStatus === "saving" || saveStatus === "idle",
      `结构事务后保存状态异常：${saveStatus}`,
    );

    console.log(
      JSON.stringify(
        {
          ok: true,
          baseUrl: BASE_URL,
          workspaceId: fixture.workspaceId,
          documentId: fixture.parentId,
          saveStatus,
        },
        null,
        2,
      ),
    );
  } catch (error) {
    caughtError = error;
  } finally {
    if (fixture) {
      try {
        await cleanupDocuments(context.request, fixture.createdIds);
      } catch (cleanupError) {
        if (!caughtError) {
          caughtError = cleanupError;
        }
      }
    }
    await page.close().catch(() => undefined);
    await context.close().catch(() => undefined);
    await browser.close().catch(() => undefined);
  }

  if (caughtError) {
    throw caughtError;
  }
}

main().catch((error) => {
  console.error(error instanceof Error ? error.stack || error.message : String(error));
  process.exit(1);
});
