"use strict";
var import_CodeEditor = require("../CodeEditor.css");
const jsxRuntime = require("react/jsx-runtime");
const langMarkdown = require("@codemirror/lang-markdown");
const langPython = require("@codemirror/lang-python");
const language = require("@codemirror/language");
const javascript = require("@codemirror/legacy-modes/mode/javascript");
const yaml = require("@codemirror/legacy-modes/mode/yaml");
const ReactCodeMirror = require("@uiw/react-codemirror");
const antd = require("antd");
const React = require("react");
const kit_Button = require("./Button.cjs");
const kit_Icon = require("./Icon.cjs");
const kit_Message = require("./Message.cjs");
const kit_Spinner = require("./Spinner.cjs");
const kit_Theme_UI = require("./Theme/UI.cjs");
require("./Theme/themeUtils.cjs");
require("./Theme/themes.cjs");
const kit_utils_loadable = require("./utils/loadable.cjs");
const codeEditorBase = "CodeEditor_codeEditorBase_62e3e";
const fileTree = "CodeEditor_fileTree_62e3e";
const fileDir = "CodeEditor_fileDir_62e3e";
const fileInfo = "CodeEditor_fileInfo_62e3e";
const buttonContainer = "CodeEditor_buttonContainer_62e3e";
const filePath = "CodeEditor_filePath_62e3e";
const fileDesc = "CodeEditor_fileDesc_62e3e";
const readOnly = "CodeEditor_readOnly_62e3e";
const buttonsContainer = "CodeEditor_buttonsContainer_62e3e";
const editor = "CodeEditor_editor_62e3e";
const editorMode = "CodeEditor_editorMode_62e3e";
const pageError = "CodeEditor_pageError_62e3e";
const hideElement = "CodeEditor_hideElement_62e3e";
const css = {
  codeEditorBase,
  fileTree,
  fileDir,
  fileInfo,
  buttonContainer,
  filePath,
  fileDesc,
  readOnly,
  buttonsContainer,
  editor,
  editorMode,
  pageError,
  hideElement
};
const JupyterRenderer = React.lazy(() => Promise.resolve().then(() => require("./CodeEditor/IpynbRenderer.cjs")));
const { DirectoryTree } = antd.Tree;
const MARKDOWN_CONFIG = {
  autocompletion: false,
  foldGutter: false,
  highlightActiveLineGutter: false
};
const sortTree = (a, b) => {
  if (a.children)
    a.children.sort(sortTree);
  if (b.children)
    b.children.sort(sortTree);
  const titleA = String(a.title);
  const titleB = String(b.title);
  if (isConfig(a.key) && !isConfig(b.key))
    return -1;
  if (!isConfig(a.key) && isConfig(b.key))
    return 1;
  if (isConfig(a.key) && isConfig(b.key))
    return a.key < b.key ? 1 : -1;
  if (!a.isLeaf && b.isLeaf)
    return -1;
  if (a.isLeaf && !b.isLeaf)
    return 1;
  if (!a.isLeaf && !b.isLeaf)
    return titleA.localeCompare(titleB) - titleB.localeCompare(titleA);
  const [stringA, extensionA] = titleA.split(/^(?=[a-zA-Z])\./);
  const [stringB, extensionB] = titleB.split(/^(?=[a-zA-Z])\./);
  if (!extensionA && extensionB)
    return 1;
  if (!extensionB && extensionA)
    return -1;
  if (!extensionA && !extensionB)
    return stringA.localeCompare(stringB) - stringB.localeCompare(stringA);
  return extensionA.localeCompare(extensionB) - extensionB.localeCompare(extensionB);
};
const Config = {
  Runtime: "Runtime Configuration",
  Submitted: "Submitted Configuration"
};
const isConfig = (key) => key === Config.Submitted || key === Config.Runtime;
const langs = {
  json: () => language.StreamLanguage.define(javascript.json),
  markdown: () => langMarkdown.markdown({ base: langMarkdown.markdownLanguage }),
  python: langPython.python,
  yaml: () => language.StreamLanguage.define(yaml.yaml)
};
const emptyIpynbFile = JSON.stringify({
  cells: []
});
const CodeEditor = ({
  files,
  height = "100%",
  file,
  onChange,
  onError,
  onSelectFile,
  readonly,
  selectedFilePath = String(((_a) => (_a = files[0]) == null ? void 0 : _a.key)())
}) => {
  var _a2, _b;
  const loadableFile = React.useMemo(() => kit_utils_loadable.Loadable.ensureLoadable(file), [file]);
  const sortedFiles = React.useMemo(() => [...files].sort(sortTree), [files]);
  const {
    themeSettings: { themeIsDark, className: themeClass }
  } = kit_Theme_UI.useTheme();
  const viewMode = React.useMemo(() => files.length === 1 ? "editor" : "split", [files.length]);
  const activeFile = React.useMemo(() => {
    if (viewMode === "editor") {
      return files[0];
    }
    if (!selectedFilePath) {
      return null;
    }
    const splitFilePath = selectedFilePath.split("/");
    let matchTopFileOrFolder = null;
    let fileDir2 = files;
    for (let dir = 0; dir < splitFilePath.length; dir++) {
      matchTopFileOrFolder = fileDir2.find(
        (f) => f.key === splitFilePath.slice(0, dir + 1).join("/") || f.key === selectedFilePath
      );
      if (matchTopFileOrFolder == null ? void 0 : matchTopFileOrFolder.children) {
        fileDir2 = matchTopFileOrFolder.children;
      }
    }
    return matchTopFileOrFolder;
  }, [files, selectedFilePath, viewMode]);
  const editorMode2 = React.useMemo(() => {
    const isIpybnFile = /\.ipynb$/i.test(String((activeFile == null ? void 0 : activeFile.key) || ""));
    return isIpybnFile ? "ipynb" : "codemirror";
  }, [activeFile == null ? void 0 : activeFile.key]);
  const syntax = React.useMemo(() => {
    if (String(activeFile == null ? void 0 : activeFile.key).includes(".py"))
      return "python";
    if (String(activeFile == null ? void 0 : activeFile.key).includes(".json"))
      return "json";
    if (String(activeFile == null ? void 0 : activeFile.key).includes(".md"))
      return "markdown";
    return "yaml";
  }, [activeFile == null ? void 0 : activeFile.key]);
  const handleSelectFile = React.useCallback(
    (_, info) => {
      var _a3;
      const selectedKey = String(info.node.key);
      if (selectedKey === (activeFile == null ? void 0 : activeFile.key)) {
        return;
      }
      const nodeAddress = selectedKey.split("/");
      let targetNode = files.find((node) => node.title === nodeAddress[0]);
      for (const dir of nodeAddress.slice(1))
        targetNode = (_a3 = targetNode == null ? void 0 : targetNode.children) == null ? void 0 : _a3.find((file2) => file2.title === dir);
      if (!targetNode) {
        return;
      }
      if (targetNode.isLeaf) {
        onSelectFile == null ? void 0 : onSelectFile(String(targetNode.key));
      }
    },
    [activeFile == null ? void 0 : activeFile.key, files, onSelectFile]
  );
  const handleDownloadClick = React.useCallback(() => {
    if (!loadableFile.isLoaded || !activeFile)
      return;
    const link = document.createElement("a");
    link.download = isConfig(activeFile == null ? void 0 : activeFile.key) ? activeFile.download || "" : String(activeFile.title);
    link.href = URL.createObjectURL(new Blob([kit_utils_loadable.Loadable.getOrElse("", loadableFile)]));
    link.dispatchEvent(new MouseEvent("click"));
    setTimeout(() => {
      URL.revokeObjectURL(link.href);
    }, 2e3);
  }, [activeFile, loadableFile]);
  const classes = [
    css.codeEditorBase,
    loadableFile.isFailed ? css.noEditor : "",
    viewMode === "editor" ? css.editorMode : "",
    themeClass
  ];
  const sectionClass = loadableFile.isFailed ? css.pageError : css.editor;
  const treeClasses = [css.fileTree, viewMode === "editor" ? css.hideElement : ""];
  let fileContent = /* @__PURE__ */ jsxRuntime.jsx("h5", { children: "Please, choose a file to preview." });
  if (loadableFile.isFailed) {
    fileContent = /* @__PURE__ */ jsxRuntime.jsx(kit_Message, { icon: "error", title: ((_a2 = loadableFile.error) == null ? void 0 : _a2.message) ?? "Unknown Error" });
  } else if (activeFile) {
    fileContent = editorMode2 === "codemirror" ? /* @__PURE__ */ jsxRuntime.jsx(
      ReactCodeMirror,
      {
        basicSetup: syntax === "markdown" ? MARKDOWN_CONFIG : void 0,
        extensions: [langs[syntax]()],
        height: "100%",
        readOnly: readonly,
        style: { height: "100%" },
        theme: themeIsDark ? "dark" : "light",
        value: kit_utils_loadable.Loadable.getOrElse("", loadableFile),
        onChange
      }
    ) : /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(kit_Spinner, { spinning: true, tip: "Loading ipynb viewer..." }), children: /* @__PURE__ */ jsxRuntime.jsx(
      JupyterRenderer,
      {
        file: kit_utils_loadable.Loadable.getOrElse(emptyIpynbFile, loadableFile),
        onError
      }
    ) });
  }
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classes.join(" "), style: { height }, children: [
    /* @__PURE__ */ jsxRuntime.jsx(
      DirectoryTree,
      {
        className: treeClasses.join(" "),
        "data-testid": "fileTree",
        defaultExpandAll: true,
        defaultSelectedKeys: [selectedFilePath || ((_b = sortedFiles[0]) == null ? void 0 : _b.key)],
        treeData: sortedFiles,
        onSelect: handleSelectFile
      }
    ),
    !!(activeFile == null ? void 0 : activeFile.title) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: css.fileDir, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: css.fileInfo, children: [
      /* @__PURE__ */ jsxRuntime.jsx("div", { className: css.buttonContainer, children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
        activeFile.icon ?? /* @__PURE__ */ jsxRuntime.jsx(kit_Icon.default, { decorative: true, name: "document" }),
        /* @__PURE__ */ jsxRuntime.jsx("span", { className: css.filePath, children: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: activeFile.title }) }),
        (activeFile == null ? void 0 : activeFile.subtitle) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: css.fileDesc, children: [
          " ",
          activeFile == null ? void 0 : activeFile.subtitle
        ] }),
        readonly && /* @__PURE__ */ jsxRuntime.jsx("span", { className: css.readOnly, children: "read-only" })
      ] }) }),
      /* @__PURE__ */ jsxRuntime.jsx("div", { className: css.buttonsContainer, children: readonly && !loadableFile.isNotLoaded && /* @__PURE__ */ jsxRuntime.jsx(
        kit_Button,
        {
          icon: /* @__PURE__ */ jsxRuntime.jsx(kit_Icon.default, { name: "download", showTooltip: true, size: "small", title: "Download File" }),
          type: "text",
          onClick: handleDownloadClick
        }
      ) })
    ] }) }),
    /* @__PURE__ */ jsxRuntime.jsx("div", { className: sectionClass, children: /* @__PURE__ */ jsxRuntime.jsx(kit_Spinner, { spinning: loadableFile.isNotLoaded, children: fileContent }) })
  ] });
};
module.exports = CodeEditor;
