const fs = require("fs");
const path = require("path");
const { chromium } = require("playwright");

const runtimePath = path.join(
  __dirname,
  "..",
  "rust",
  "crates",
  "mnote-web",
  "browser",
  "sidebar-tree-live-apply-runtime.js",
);

async function main() {
  const source = fs
    .readFileSync(runtimePath, "utf8")
    .replace(
      "export const createSidebarTreeLiveApplyRuntime =",
      "window.createSidebarTreeLiveApplyRuntime =",
    );

  const browser = await chromium.launch({ headless: true });
  const page = await browser.newPage();
  await page.goto("http://127.0.0.1:3000/", { waitUntil: "domcontentloaded" });
  await page.setContent(
    '<!doctype html><html><body><div id="sidebar-file-tree-root"></div><div id="sidebar-tree-root"></div></body></html>',
  );
  await page.addScriptTag({ content: source });

  const result = await page.evaluate(async () => {
    const escapeHtml = (value) =>
      String(value || "")
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#39;");
    const rootProjection = {
      dataset: {
        kernel_file_tree_projection: {
          items: [
            {
              rowId: "local:folder:design",
              rowKind: "folder",
              nodeId: "local:node:design",
              parentNodeId: null,
              title: "design",
              depth: 0,
              childCount: 1,
              expandable: true,
              expandedByDefault: false,
              resourceMeta: {
                extra: {
                  source: {
                    relativePath: "design",
                  },
                },
              },
            },
          ],
        },
      },
    };
    const childrenProjection = {
      result: {
        items: [
          {
            rowId: "local:folder:design/03-rust-web",
            rowKind: "folder",
            nodeId: "local:node:design/03-rust-web",
            parentNodeId: "local:node:design",
            title: "03-rust-web",
            depth: 1,
            childCount: 0,
            expandable: false,
            expandedByDefault: false,
            resourceMeta: {
              extra: {
                source: {
                  relativePath: "design/03-rust-web",
                },
              },
            },
          },
        ],
      },
    };

    window.fetch = async () => ({
      ok: true,
      json: async () => childrenProjection,
    });

    const runtime = window.createSidebarTreeLiveApplyRuntime({
      activeSidebarTreeMode: () => "filetree",
      cssEscape: (value) => CSS.escape(String(value || "")),
      currentDocumentId: () => "local-md:AGENTS.md",
      currentFileTreeActiveRowId: () => "",
      currentRootUri: () => "file:///tmp/mnote-smoke",
      currentSourceKind: () => "local_folder",
      currentWorkspaceId: () => "local:test",
      escapeHtml,
      fileTreeRuntimeFunction: () => null,
      localFilePathFromAssetId: () => "",
      navigateToDocument: () => {},
      refreshEditorLocalAttachmentExistence: () => {},
      restoreSidebarTreeTab: () => {},
      rowTitle: (row) => (row ? row.textContent || "" : ""),
      schedulePendingLocalFolderRestoreFocus: () => {},
      shortMindmapFileName: () => "mindmap.json",
      syncSidebarFileTreeSelection: () => {},
    });

    const rendered = runtime.renderSidebarSnapshot(rootProjection);
    const designRow = document.querySelector('[data-row-id="local:folder:design"]');
    if (!rendered || !designRow) {
      return {
        rendered,
        loadedBeforeRefresh: false,
        expandedBeforeRefresh: false,
        loadedAfterRefresh: false,
        expandedAfterRefresh: false,
        html: document.getElementById("sidebar-file-tree-root").innerHTML,
      };
    }
    const toggle = designRow && designRow.querySelector('[data-rust-action="toggle"]');
    runtime.toggleChildren(designRow, toggle);

    await new Promise((resolve) => setTimeout(resolve, 100));
    const loadedBeforeRefresh = Boolean(
      document.querySelector('[data-row-id="local:folder:design/03-rust-web"]'),
    );
    const expandedBeforeRefresh = designRow.getAttribute("aria-expanded") === "true";

    runtime.renderSidebarSnapshot(rootProjection);
    const loadedAfterRefresh = Boolean(
      document.querySelector('[data-row-id="local:folder:design/03-rust-web"]'),
    );
    const refreshedDesignRow = document.querySelector('[data-row-id="local:folder:design"]');
    const expandedAfterRefresh =
      refreshedDesignRow && refreshedDesignRow.getAttribute("aria-expanded") === "true";

    return {
      loadedBeforeRefresh,
      expandedBeforeRefresh,
      loadedAfterRefresh,
      expandedAfterRefresh,
      error: document.documentElement.getAttribute("data-mnote-tree-live-apply-error") || "",
      html: document.getElementById("sidebar-file-tree-root").innerHTML,
    };
  });

  await browser.close();

  if (!result.loadedBeforeRefresh || !result.expandedBeforeRefresh) {
    throw new Error(`懒加载前置步骤失败: ${JSON.stringify(result, null, 2)}`);
  }
  if (!result.loadedAfterRefresh || !result.expandedAfterRefresh) {
    throw new Error(`FileTree root projection 刷新后丢失已展开子树: ${JSON.stringify(result, null, 2)}`);
  }
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});
