#!/usr/bin/env node
"use strict";

const assert = require("node:assert");
const {
  fetchWithTimeout,
  findFreePort,
  startGateway,
  waitForGateway,
} = require("./task114-rust-web-gateway-entry-smoke.js");

const EXTERNAL_BASE_URL = (process.env.MNOTE_UI_BASE_URL || "").replace(/\/+$/, "");
const CONFIGURED_DOCUMENT_ID = (process.env.MNOTE_DOCUMENT_ID || "").trim();
const CONFIGURED_WORKSPACE_ID = (process.env.MNOTE_WORKSPACE_ID || "").trim();
const CONFIGURED_TITLE = (process.env.MNOTE_DOCUMENT_TITLE || "").trim();

async function readJsonResponse(response, label) {
  const text = await response.text();
  let payload = null;
  try {
    payload = text ? JSON.parse(text) : null;
  } catch {
    throw new Error(`${label} 返回了非 JSON 内容: ${text.slice(0, 1200)}`);
  }
  assert(response.ok, `${label} 请求失败: ${response.status}; body: ${text.slice(0, 1200)}`);
  return payload;
}

async function createTempDocument(baseUrl) {
  const title = `task115-rust-web-${Date.now()}`;
  const requestBody = {
    action: "create",
    title,
  };
  if (CONFIGURED_WORKSPACE_ID) {
    requestBody.workspaceId = CONFIGURED_WORKSPACE_ID;
  }

  const response = await fetchWithTimeout(`${baseUrl}/api/tree/commands`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify(requestBody),
  });
  const payload = await readJsonResponse(response, "创建临时文档");
  const result = payload && typeof payload.result === "object" ? payload.result : null;
  const documentId = result && typeof result.documentId === "string" ? result.documentId : "";
  const workspaceId = result && typeof result.workspaceId === "string" ? result.workspaceId : "";
  assert(documentId, "创建临时文档缺少 documentId");
  assert(workspaceId, "创建临时文档缺少 workspaceId");
  return { documentId, workspaceId, title };
}

async function purgeTempDocument(baseUrl, target) {
  const response = await fetchWithTimeout(`${baseUrl}/api/tree/commands`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({
      action: "purge",
      workspaceId: target.workspaceId,
      documentId: target.documentId,
    }),
  });
  await readJsonResponse(response, "清理临时文档");
}

async function validateDocumentShell(baseUrl, target) {
  const targetPath = `/documents/${encodeURIComponent(target.documentId)}?workspaceId=${encodeURIComponent(target.workspaceId)}`;
  const response = await fetchWithTimeout(`${baseUrl}${targetPath}`);
  const html = await response.text();
  assert.equal(response.status, 200, `文档 shell 请求失败: ${response.status}; body: ${html.slice(0, 1200)}`);
  assert.equal(response.headers.get("x-mnote-web-owner"), "mnote-web");
  assert.equal(response.headers.get("x-mnote-web-shell"), "document");
  assert.match(response.headers.get("content-type") || "", /text\/html/);
  assert.match(html, /data-mnote-shell="document"/);
  assert.match(html, /data-testid="wolai-sidebar"/);
  assert.match(html, /data-testid="wolai-topbar"/);
  assert.match(html, /data-testid="wolai-floating-ai"/);
  assert.match(html, /data-page-aggregate-snapshot="mnote\.page_aggregate\.v1"/);
  assert.match(html, /id="__MNOTE_PAGE_AGGREGATE__"/);
  assert.match(html, /data-editor-host="leptos_tiptap_island"/);
  assert.doesNotMatch(html, /mnote-web-document-shell/);
  assert.doesNotMatch(html, /convex_upstream_error|未登录/);

  const aggregate = await fetchWithTimeout(
    `${baseUrl}/api/page-aggregate/${encodeURIComponent(target.documentId)}?workspaceId=${encodeURIComponent(target.workspaceId)}`,
  );
  const aggregateText = await aggregate.text();
  assert.equal(aggregate.status, 200, `page aggregate 请求失败: ${aggregate.status}; body: ${aggregateText.slice(0, 1200)}`);
  const payload = JSON.parse(aggregateText);
  assert.equal(aggregate.headers.get("x-mnote-web-owner"), "mnote-web");
  assert.equal(payload.owner, "mnote-web");
  assert.equal(payload.schema, "mnote.page_aggregate.v1");
  assert.equal(payload.result.identity.documentId, target.documentId);
  assert.equal(payload.result.identity.workspaceId, target.workspaceId);
  assert.equal(payload.result.schema, "mnote.page_aggregate.v1");
  assert.equal(typeof payload.result.head.title, "string");
  assert(payload.result.head.title.trim(), "Page Aggregate 标题不能为空");
  if (target.expectedTitle) {
    assert.equal(payload.result.head.title, target.expectedTitle);
  }
}

async function main() {
  let gateway = null;
  let baseUrl = EXTERNAL_BASE_URL;
  let createdTarget = null;

  if (!baseUrl) {
    const port = await findFreePort();
    baseUrl = `http://127.0.0.1:${port}`;
    gateway = startGateway(port);
    await waitForGateway(baseUrl);
  }

  try {
    const target = CONFIGURED_DOCUMENT_ID
      ? {
          documentId: CONFIGURED_DOCUMENT_ID,
          workspaceId: CONFIGURED_WORKSPACE_ID || "ws_demo",
          expectedTitle: CONFIGURED_TITLE || null,
        }
      : gateway
        ? {
            documentId: "doc_1",
            workspaceId: "ws_demo",
            expectedTitle: CONFIGURED_TITLE || "服务端页面",
          }
        : await createTempDocument(baseUrl);
    if (!CONFIGURED_DOCUMENT_ID && !gateway) {
      createdTarget = target;
      target.expectedTitle = target.title;
    }

    await validateDocumentShell(baseUrl, target);
    console.log(
      JSON.stringify(
        {
          ok: true,
          baseUrl,
          owner: "mnote-web",
          shell: "document",
          editorHost: "leptos_tiptap_island",
          documentId: target.documentId,
          workspaceId: target.workspaceId,
        },
        null,
        2,
      ),
    );
  } finally {
    if (createdTarget) {
      await purgeTempDocument(baseUrl, createdTarget);
    }
    if (gateway && gateway.pid) {
      gateway.kill("SIGTERM");
      setTimeout(() => {
        if (!gateway.killed) {
          gateway.kill("SIGKILL");
        }
      }, 2000).unref();
    }
  }
}

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