// MNote debug /tree shell filetree context menu runtime.

import {
  getFileTreeRowAssetId,
  getFileTreeRowDocumentId,
} from "./tree-shell-filetree-runtime.js";
import { normalizeTreeShellText as normalizeText } from "./tree-shell-state-runtime.js";

const createFileTreeMenuItem = (kind, label, options = {}) => ({
  kind,
  label,
  disabled: options.disabled === true,
  reason: normalizeText(options.reason),
  separatorBefore: options.separatorBefore === true,
});

function buildFileTreeMenuTarget(context, rowId, rowKind, documentId, assetId) {
  const fileTreeRowById = context.getFileTreeRowById();
  const item = rowId ? fileTreeRowById.get(rowId) : null;
  return {
    item,
    rowId: rowId || null,
    rowKind: rowKind || item?.rowKind || "root",
    documentId: documentId || getFileTreeRowDocumentId(item) || null,
    assetId: assetId || getFileTreeRowAssetId(item) || null,
  };
}

export function buildTreeShellFileTreeContextMenuProfile(context, target) {
  const selectedFileTreeRowIds = context.getSelectedFileTreeRowIds();
  const fileTreeClipboard = context.getFileTreeClipboard();
  const selectedCount = selectedFileTreeRowIds.size;
  const isMulti = selectedCount > 1 && target.rowId && selectedFileTreeRowIds.has(target.rowId);
  const item = target.item;
  const rowKind = target.rowKind || "root";
  const canPaste = Boolean(fileTreeClipboard.action && fileTreeClipboard.rowIds.length > 0);
  const hasDocument = Boolean(getFileTreeRowDocumentId(item));
  const hasAsset = Boolean(getFileTreeRowAssetId(item));
  const localSource = context.sourceKind === "local_folder";
  const convexSource = context.sourceKind === "convex_workspace";
  const canCreateFolder = localSource;
  const canCreatePage = rowKind === "root" || rowKind === "folder" || rowKind === "document";
  const canRename =
    rowKind === "markdown" ||
    rowKind === "document" ||
    rowKind === "folder" ||
    rowKind === "index";
  const canCopyCut =
    rowKind === "markdown" ||
    rowKind === "document" ||
    rowKind === "index";
  const canDelete =
    rowKind === "markdown" ||
    rowKind === "document" ||
    rowKind === "index" ||
    (localSource && rowKind === "asset");

  if (rowKind === "root") {
    return [
      createFileTreeMenuItem("newPage", "新建页面", {
        disabled: !canCreatePage,
        reason: "当前 root 不支持新建页面",
      }),
      createFileTreeMenuItem("newFolder", "新建文件夹", {
        disabled: !canCreateFolder,
        reason: convexSource ? "Convex workspace 当前未暴露 folder capability" : "当前 source 不支持新建文件夹",
      }),
      createFileTreeMenuItem("upload", "上传/导入", {
        disabled: true,
        reason: localSource ? "外部文件请拖入 Explorer" : "Convex 上传 executor 尚未接入",
      }),
      createFileTreeMenuItem("refresh", "刷新", { separatorBefore: true }),
      createFileTreeMenuItem("collapseAll", "全部折叠"),
    ];
  }

  if (isMulti) {
    return [
      createFileTreeMenuItem("copy", "复制"),
      createFileTreeMenuItem("cut", "剪切"),
      createFileTreeMenuItem("delete", "删除", { disabled: false }),
      createFileTreeMenuItem("moveTo", "移动到", {
        separatorBefore: true,
        disabled: true,
        reason: "目标选择器尚未接入 filetree 菜单",
      }),
    ];
  }

  const items = [];
  if (rowKind === "folder") {
    items.push(createFileTreeMenuItem("newPage", "新建页面", {
      disabled: !canCreatePage,
      reason: "当前文件夹不支持新建页面",
    }));
    items.push(createFileTreeMenuItem("newFolder", "新建文件夹", {
      disabled: !canCreateFolder,
      reason: convexSource ? "Convex workspace 当前未暴露 folder capability" : "当前 source 不支持新建文件夹",
    }));
    items.push(createFileTreeMenuItem("paste", "粘贴", {
      disabled: !canPaste,
      reason: "剪贴板为空",
    }));
    items.push(createFileTreeMenuItem("rename", "重命名", {
      separatorBefore: true,
      disabled: !canRename,
      reason: "当前文件夹不支持重命名",
    }));
    items.push(createFileTreeMenuItem("delete", "删除", {
      disabled: true,
      reason: "目录删除尚未收口到统一 executor",
    }));
    return items;
  }

  items.push(createFileTreeMenuItem("open", "打开", {
    disabled: !hasDocument && !hasAsset,
    reason: "当前行没有可打开资源",
  }));
  items.push(createFileTreeMenuItem("rename", "重命名", {
    disabled: !canRename,
    reason: "当前资源暂不支持重命名",
  }));
  items.push(createFileTreeMenuItem("copy", "复制", {
    disabled: !canCopyCut,
    reason: "当前资源暂不支持复制",
  }));
  items.push(createFileTreeMenuItem("cut", "剪切", {
    disabled: !canCopyCut,
    reason: "当前资源暂不支持剪切",
  }));
  items.push(createFileTreeMenuItem("paste", "粘贴", {
    disabled: !canPaste,
    reason: "剪贴板为空",
  }));
  items.push(createFileTreeMenuItem("moveTo", "移动到", {
    disabled: true,
    reason: "目标选择器尚未接入 filetree 菜单",
  }));
  items.push(createFileTreeMenuItem("delete", "删除", {
    disabled: !canDelete,
    reason: "当前资源暂不支持删除",
  }));
  items.push(createFileTreeMenuItem("reveal", "Reveal", { separatorBefore: true }));
  if (hasAsset) {
    items.push(createFileTreeMenuItem("download", "下载", {
      disabled: true,
      reason: "下载 executor 尚未接入",
    }));
  }
  if (item?.capabilities?.includes("share")) {
    items.push(createFileTreeMenuItem("share", "分享", { separatorBefore: true }));
  }
  if (item?.capabilities?.includes("publish")) {
    items.push(createFileTreeMenuItem("publish", "发布"));
  }
  return items;
}

export function createTreeShellFileTreeMenuRuntime(context) {
  let activeFileTreeMenuElement = null;

  const closeFileTreeContextMenu = () => {
    if (!activeFileTreeMenuElement) return;
    activeFileTreeMenuElement.remove();
    activeFileTreeMenuElement = null;
  };

  const executeFileTreeContextMenuAction = async (kind, target) => {
    closeFileTreeContextMenu();
    const item = target.item;
    if (kind === "open") {
      if (item) context.openHydratedFileTreeItem(item);
      return;
    }
    if (kind === "rename") {
      if (target.rowId && getFileTreeRowDocumentId(item)) {
        context.beginInlineRename("filetree", target.rowId);
      }
      return;
    }
    if (kind === "copy" || kind === "cut") {
      const selectedFileTreeRowIds = context.getSelectedFileTreeRowIds();
      if (target.rowId && !selectedFileTreeRowIds.has(target.rowId)) {
        context.commitFileTreeSelection({
          selectedRowIds: [target.rowId],
          anchorRowId: target.rowId,
          focusedRowId: target.rowId,
        });
        context.syncFileTreeSelectionDom();
      }
      context.setFileTreeClipboard(kind);
      return;
    }
    if (kind === "paste") {
      await context.pasteFileTreeClipboardInto(target.rowId);
      return;
    }
    if (kind === "delete") {
      await context.runFileTreeDelete(target.rowId);
      return;
    }
    if (kind === "newPage") {
      const parentId = item && item.rowKind === "folder"
        ? item.nodeId
        : item && item.rowKind === "document"
          ? item.nodeId
          : null;
      await context.handleCreate(parentId);
      return;
    }
    if (kind === "newFolder") {
      const parentId = item && item.rowKind === "folder" ? item.nodeId : null;
      const result = await context.sendCommand({
        action: "createFolder",
        workspaceId: context.workspaceId,
        documentId: "",
        parentId,
        title: "新建文件夹",
      });
      context.setStatus("创建文件夹成功");
      context.setLastAction("已创建新建文件夹");
      context.scheduleRefresh({
        renameRowId: context.localCreatedRowIdFromCommandResult(result, "folder"),
      });
      return result;
    }
    if (kind === "refresh") {
      await context.refreshLocalFolderSnapshot();
      return;
    }
    if (kind === "collapseAll") {
      context.expanded.clear();
      context.renderTree();
      return;
    }
    if (kind === "reveal") {
      context.setLastAction(`Reveal ${target.documentId || target.assetId || target.rowId || "root"}`);
      context.postToHost("tree.filetree.reveal", {
        documentId: target.documentId,
        assetId: target.assetId,
        rowId: target.rowId,
        payload: target,
      });
      return;
    }
    context.postToHost(`tree.filetree.${kind}`, {
      documentId: target.documentId,
      assetId: target.assetId,
      rowId: target.rowId,
      payload: target,
    });
  };

  const openFileTreeContextMenu = ({
    documentId,
    assetId,
    rowId,
    rowKind,
    clientX,
    clientY,
  }) => {
    closeFileTreeContextMenu();
    const target = buildFileTreeMenuTarget(context, rowId, rowKind, documentId, assetId);
    const profile = buildTreeShellFileTreeContextMenuProfile(context, target);
    const menu = document.createElement("div");
    menu.className = "tree-context-menu";
    menu.dataset.testid = "filetree-context-menu";
    menu.dataset.sourceKind = context.sourceKind;
    menu.dataset.rowKind = target.rowKind;
    menu.setAttribute("role", "menu");

    profile.forEach((entry) => {
      if (entry.separatorBefore) {
        const separator = document.createElement("div");
        separator.className = "tree-menu-separator";
        separator.setAttribute("role", "separator");
        menu.appendChild(separator);
      }
      const button = document.createElement("button");
      button.type = "button";
      button.className = "tree-menu-item";
      button.dataset.menuAction = entry.kind;
      button.setAttribute("role", "menuitem");
      button.textContent = entry.label;
      if (entry.disabled) {
        button.disabled = true;
        if (entry.reason) {
          button.title = entry.reason;
          button.dataset.disabledReason = entry.reason;
        }
      } else {
        button.addEventListener("click", () => {
          void executeFileTreeContextMenuAction(entry.kind, target);
        });
      }
      menu.appendChild(button);
    });

    const closeOnOutside = (event) => {
      if (activeFileTreeMenuElement && !activeFileTreeMenuElement.contains(event.target)) {
        closeFileTreeContextMenu();
        document.removeEventListener("mousedown", closeOnOutside, true);
        document.removeEventListener("keydown", closeOnKeyDown, true);
      }
    };
    const closeOnKeyDown = (event) => {
      if (event.key === "Escape") {
        closeFileTreeContextMenu();
        document.removeEventListener("mousedown", closeOnOutside, true);
        document.removeEventListener("keydown", closeOnKeyDown, true);
      }
    };

    document.body.appendChild(menu);
    const x = Number.isFinite(clientX) ? clientX : 16;
    const y = Number.isFinite(clientY) ? clientY : 16;
    const rect = menu.getBoundingClientRect();
    menu.style.left = `${Math.max(4, Math.min(x, window.innerWidth - rect.width - 4))}px`;
    menu.style.top = `${Math.max(4, Math.min(y, window.innerHeight - rect.height - 4))}px`;
    activeFileTreeMenuElement = menu;
    window.setTimeout(() => {
      document.addEventListener("mousedown", closeOnOutside, true);
      document.addEventListener("keydown", closeOnKeyDown, true);
    }, 0);
    context.setLastAction(
      assetId
        ? `已打开资源 ${assetId} 的更多操作`
        : `已打开文件树节点 ${documentId || rowId || "unknown"} 的更多操作`,
    );
    context.postToHost("tree.filetree.context-menu", {
      documentId,
      assetId,
      rowId,
      rowKind,
      payload: {
        documentId,
        assetId,
        rowId,
        rowKind,
        x: clientX,
        y: clientY,
      },
      x: clientX,
      y: clientY,
    });
  };

  return {
    closeFileTreeContextMenu,
    executeFileTreeContextMenuAction,
    openFileTreeContextMenu,
  };
}
