import { unsafeCSS, html } from "lit";
import { flowElement, FRoot } from "@nonfx/flow-core";
import * as monaco from "monaco-editor";
import { property, query } from "lit/decorators.js";
import { injectCss } from "@nonfx/flow-core-config";
function WorkerWrapper$4(options) {
  return new Worker(
    "/assets/editor.worker-CWHbK_Qb.js",
    {
      name: options == null ? void 0 : options.name
    }
  );
}
function WorkerWrapper$3(options) {
  return new Worker(
    "/assets/json.worker-B3q3vi-e.js",
    {
      name: options == null ? void 0 : options.name
    }
  );
}
function WorkerWrapper$2(options) {
  return new Worker(
    "/assets/css.worker-FWki1IyG.js",
    {
      name: options == null ? void 0 : options.name
    }
  );
}
function WorkerWrapper$1(options) {
  return new Worker(
    "/assets/html.worker-HsGXyQpq.js",
    {
      name: options == null ? void 0 : options.name
    }
  );
}
function WorkerWrapper(options) {
  return new Worker(
    "/assets/ts.worker-3Pm-0kTV.js",
    {
      name: options == null ? void 0 : options.name
    }
  );
}
const globalStyle = "f-code-editor {\n  font-family: var(--flow-font);\n  box-sizing: border-box;\n  flex-shrink: 0;\n  scrollbar-color: var(--color-border-secondary) transparent;\n  scrollbar-width: none;\n  display: block;\n  min-height: 100px;\n  overflow: visible;\n  text-align: initial;\n}\nf-code-editor::-webkit-scrollbar {\n  display: none;\n}\nf-code-editor::-webkit-scrollbar-track {\n  -webkit-box-shadow: inset 0 0 2px transparent;\n  background-color: transparent;\n}\nf-code-editor::-webkit-scrollbar-thumb {\n  background-color: var(--color-border-secondary);\n}\nf-code-editor::-webkit-scrollbar-corner {\n  background-color: transparent;\n}\nf-code-editor [class^=codicon-],\nf-code-editor [class*=codicon-] {\n  font-family: codicon, Arial, Helvetica, sans-serif !important;\n}\nf-code-editor .f-code-editor-header {\n  border-radius: 4px 4px 0px 0px !important;\n}\nf-code-editor .monaco-editor {\n  --vscode-editor-foreground: var(--color-text-default);\n  --vscode-editorSuggestWidget-foreground: var(--color-text-default);\n}\nf-code-editor .monaco-editor[state=default] {\n  --vscode-editor-background: var(--color-surface-default);\n  --vscode-editorStickyScroll-background: var(--color-surface-default);\n  --vscode-breadcrumb-background: var(--color-surface-default);\n  --vscode-editorGutter-background: var(--color-surface-default);\n  --vscode-editorMarkerNavigation-background: var(--color-surface-default);\n}\nf-code-editor .monaco-editor[state=secondary] {\n  --vscode-editor-background: var(--color-surface-secondary);\n  --vscode-editorStickyScroll-background: var(--color-surface-secondary);\n  --vscode-breadcrumb-background: var(--color-surface-secondary);\n  --vscode-editorGutter-background: var(--color-surface-secondary);\n  --vscode-editorMarkerNavigation-background: var(--color-surface-secondary);\n}\nf-code-editor .monaco-editor[state=subtle] {\n  --vscode-editor-background: var(--color-surface-subtle);\n  --vscode-editorStickyScroll-background: var(--color-surface-subtle);\n  --vscode-breadcrumb-background: var(--color-surface-subtle);\n  --vscode-editorGutter-background: var(--color-surface-subtle);\n  --vscode-editorMarkerNavigation-background: var(--color-surface-subtle);\n}\nf-code-editor .monaco-editor .margin-view-overlays .line-numbers {\n  font-size: 12px;\n}\nf-code-editor .mtk1 {\n  color: var(--color-text-default);\n}";
const commonItem = {
  singleLine: "//",
  multiLine: { start: "/*", end: "*/" }
};
const languageCommentsMap = /* @__PURE__ */ new Map([
  // JavaScript
  ["javascript", commonItem],
  // TypeScript
  ["typescript", commonItem],
  // Python
  [
    "python",
    {
      singleLine: "#",
      multiLine: { start: "'''", end: "'''" }
    }
  ],
  // Java
  ["java", commonItem],
  // C++
  ["cpp", commonItem],
  // C#
  ["csharp", commonItem],
  // PHP
  ["php", commonItem],
  // Ruby
  [
    "ruby",
    {
      singleLine: "#",
      multiLine: { start: "=begin", end: "=end" }
    }
  ],
  // Swift
  ["swift", commonItem],
  // Go
  ["go", commonItem],
  // Rust
  ["rust", commonItem],
  // Kotlin
  ["kotlin", commonItem],
  // Dart
  ["dart", commonItem],
  // HTML (HTML does not support multi-line comments)
  [
    "html",
    {
      singleLine: "<!--",
      multiLine: null
    }
  ],
  // CSS (CSS does not support multi-line comments)
  [
    "css",
    {
      singleLine: "//",
      multiLine: null
    }
  ],
  // SCSS (SCSS does not support multi-line comments)
  [
    "scss",
    {
      singleLine: "//",
      multiLine: null
    }
  ],
  // Less (Less does not support multi-line comments)
  [
    "less",
    {
      singleLine: "//",
      multiLine: null
    }
  ],
  // JSON (JSON does not support multi-line comments)
  [
    "json",
    {
      singleLine: "//",
      multiLine: null
    }
  ],
  // YAML (YAML does not support multi-line comments)
  [
    "yaml",
    {
      singleLine: "#",
      multiLine: null
    }
  ]
]);
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result) __defProp(target, key, result);
  return result;
};
injectCss("f-code-editor", globalStyle);
let FCodeEditor = class extends FRoot {
  constructor() {
    super(...arguments);
    this.title = "";
    this.state = "default";
    this.language = "typescript";
    this.height = "100%";
    this.width = "100%";
    this.settings = {};
    this.services = {};
    this.comments = false;
    this.copyButton = false;
    this.showLineNumbers = true;
    this.readOnly = false;
    this.removedCommentsMap = /* @__PURE__ */ new Map();
  }
  get dymanicWidth() {
    return this.title ? "hug-content" : "100%";
  }
  get fixedLang() {
    return this.language ?? "javascript";
  }
  multiLineStart(startIndex, endIndex, line) {
    if (startIndex >= 0 && endIndex >= 0) {
      return line.substring(0, startIndex) + line.substring(endIndex + 2);
    } else {
      return line.substring(0, startIndex);
    }
  }
  multiLineEnd(endIndex, line) {
    if (endIndex >= 0) {
      return { code: line.substring(endIndex + 2), insideMultiLine: false };
    } else {
      return { code: "", insideMultiLine: true };
    }
  }
  addNewLine(modifiedLine, newLines) {
    if (modifiedLine.trim() !== "") {
      newLines.push(modifiedLine);
    }
  }
  toggleComments() {
    var _a, _b, _c, _d, _e;
    if (!this.editor) return;
    const code = this.editor.getValue();
    const lines = code.split("\n");
    const newLines = [];
    let insideMultiLineComment = false;
    const removedCommentsMap = /* @__PURE__ */ new Map();
    const startPattern = (_b = (_a = languageCommentsMap.get(this.fixedLang)) == null ? void 0 : _a.multiLine) == null ? void 0 : _b.start;
    const endPattern = (_d = (_c = languageCommentsMap.get(this.fixedLang)) == null ? void 0 : _c.multiLine) == null ? void 0 : _d.end;
    const singleLinePattern = (_e = languageCommentsMap.get(this.fixedLang)) == null ? void 0 : _e.singleLine;
    for (const [index, line] of lines.entries()) {
      let modifiedLine = line;
      if (startPattern && endPattern && !insideMultiLineComment && line.includes(startPattern)) {
        insideMultiLineComment = true;
        const startIndex = line.indexOf(startPattern);
        const endIndex = line.indexOf(endPattern);
        modifiedLine = this.multiLineStart(startIndex, endIndex, line);
        removedCommentsMap.set(index, line);
      }
      if (endPattern && insideMultiLineComment) {
        const endIndex = line.indexOf(endPattern);
        const { code: code2, insideMultiLine } = this.multiLineEnd(endIndex, line);
        modifiedLine = code2;
        insideMultiLineComment = insideMultiLine ?? true;
        removedCommentsMap.set(index, line);
      }
      if (singleLinePattern) {
        const commentIndex = modifiedLine.indexOf(singleLinePattern);
        if (commentIndex >= 0 && !insideMultiLineComment) {
          modifiedLine = modifiedLine.substring(0, commentIndex);
          removedCommentsMap.set(index, line);
        }
        this.addNewLine(modifiedLine, newLines);
      }
    }
    this.editor.setValue(newLines.join("\n"));
    this.removedCommentsMap = removedCommentsMap;
  }
  restoreComments() {
    var _a;
    if (!this.editor) return;
    const modifiedLines = this.editor.getValue().split("\n");
    const lines = modifiedLines.slice();
    const restoredLines = modifiedLines.slice();
    for (const [_index, removedComment] of this.removedCommentsMap.entries()) {
      lines.forEach((item, lineIndex) => {
        if (removedComment.trim().includes(item.trim())) {
          restoredLines.splice(lineIndex, 1);
        }
      });
    }
    for (const [index, removedComment] of this.removedCommentsMap.entries()) {
      restoredLines.splice(index, 0, removedComment);
    }
    const code = restoredLines.join("\n");
    (_a = this.editor) == null ? void 0 : _a.setValue(code);
    this.removedCommentsMap.clear();
  }
  errorMessageOnCopy() {
    if (this.copyCodeButton) {
      this.copyCodeButton.state = "danger";
      this.copyCodeButton.label = "ERROR!";
      this.copyCodeButton.iconLeft = "i-close";
    }
    setTimeout(() => {
      if (this.copyCodeButton) {
        this.copyCodeButton.state = "primary";
        this.copyCodeButton.label = "COPY";
        this.copyCodeButton.iconLeft = "i-copy";
      }
    }, 2e3);
  }
  successMessageOnCopy() {
    if (this.copyCodeButton) {
      this.copyCodeButton.state = "success";
      this.copyCodeButton.label = "COPIED!";
      this.copyCodeButton.iconLeft = "i-tick";
    }
    setTimeout(() => {
      if (this.copyCodeButton) {
        this.copyCodeButton.state = "primary";
        this.copyCodeButton.label = "COPY";
        this.copyCodeButton.iconLeft = "i-copy";
      }
    }, 2e3);
  }
  // Function to copy the code inside the editor to the clipboard
  copyCodeToClipboard() {
    var _a;
    if (this.editor) {
      const code = (_a = this.editor) == null ? void 0 : _a.getValue();
      navigator.clipboard.writeText(code).then(() => {
        this.successMessageOnCopy();
      }).catch(() => {
        this.errorMessageOnCopy();
      });
    }
  }
  handleChange(e) {
    if (!e.detail.value) {
      this.toggleComments();
    } else {
      this.restoreComments();
    }
  }
  /**
   * monoco editor never works in shadow dom
   */
  createRenderRoot() {
    return this;
  }
  render() {
    const titleSection = this.title ? html` <f-div gap="medium" align="middle-left">
					<f-icon source="i-code" state="default" size="x-small"></f-icon>
					<f-text variant="code" size="small" weight="regular" state="secondary"
						>${this.title}</f-text
					>
				</f-div>` : null;
    const copyButtonSection = this.copyButton ? html` <f-button
					class="copy-button"
					variant="curved"
					category="fill"
					size="x-small"
					label="COPY"
					icon-left="i-copy"
					@click=${this.copyCodeToClipboard}
				></f-button>` : null;
    const commentsToggleSection = this.comments ? html` <f-div gap="small" align="middle-left" width="hug-content">
					<f-text variant="heading" size="x-small" weight="regular" state="subtle">Comments</f-text>
					<f-div width="hug-content" overflow="hidden">
						<f-switch size="small" @input=${this.handleChange} .value=${true}></f-switch>
					</f-div>
				</f-div>` : null;
    const actionSection = this.copyButton || this.comments ? html` <f-div gap="medium" align="middle-right" width=${this.dymanicWidth}>
						${commentsToggleSection} ${copyButtonSection}
					</f-div>` : null;
    if (this.comments || this.copyButton || this.title) {
      return html` <f-div state="secondary" class="f-code-editor-header" padding="medium">
				${titleSection} ${actionSection}
			</f-div>`;
    } else {
      return "";
    }
  }
  willUpdate(changedProperties) {
    super.willUpdate(changedProperties);
    if (this.editor) {
      this.editor.dispose();
    }
  }
  updated(changedProperties) {
    var _a, _b, _c;
    super.updated(changedProperties);
    this.style.height = this.height;
    this.style.width = this.width;
    if (this.code) {
      this.editor = monaco.editor.create(
        this,
        {
          value: this.code,
          theme: "vs-dark",
          language: this.language,
          automaticLayout: true,
          autoDetectHighContrast: false,
          readOnly: this.readOnly,
          fontSize: 16,
          padding: {
            top: 16
          },
          minimap: { enabled: false },
          dimension: {
            width: this.offsetWidth,
            height: this.offsetHeight
          },
          ...this.settings
        },
        this.services
      );
      if (this.showLineNumbers) {
        this.editor.updateOptions({ lineNumbers: "on" });
      } else {
        this.editor.updateOptions({ lineNumbers: "off" });
      }
      (_b = (_a = this.editor) == null ? void 0 : _a.getModel()) == null ? void 0 : _b.onDidChangeContent(() => {
        var _a2, _b2;
        const inputEvent = new CustomEvent("content-change", {
          detail: {
            value: (_b2 = (_a2 = this.editor) == null ? void 0 : _a2.getModel()) == null ? void 0 : _b2.getValue()
          },
          bubbles: true,
          composed: true
        });
        this.dispatchEvent(inputEvent);
      });
      (_c = this.querySelector(".monaco-editor")) == null ? void 0 : _c.setAttribute("state", this.state ?? "default");
    }
  }
};
FCodeEditor.styles = [unsafeCSS(globalStyle)];
__decorateClass([
  property({ type: String })
], FCodeEditor.prototype, "code", 2);
__decorateClass([
  property({ reflect: true, type: String })
], FCodeEditor.prototype, "title", 2);
__decorateClass([
  property({ reflect: true, type: String })
], FCodeEditor.prototype, "state", 2);
__decorateClass([
  property({ reflect: true, type: String })
], FCodeEditor.prototype, "language", 2);
__decorateClass([
  property({ type: String })
], FCodeEditor.prototype, "height", 2);
__decorateClass([
  property({ type: String })
], FCodeEditor.prototype, "width", 2);
__decorateClass([
  property({ type: Object })
], FCodeEditor.prototype, "settings", 2);
__decorateClass([
  property({ type: Object })
], FCodeEditor.prototype, "services", 2);
__decorateClass([
  property({ type: Boolean, reflect: true })
], FCodeEditor.prototype, "comments", 2);
__decorateClass([
  property({ type: Boolean, reflect: true, attribute: "copy-button" })
], FCodeEditor.prototype, "copyButton", 2);
__decorateClass([
  property({ type: Boolean, reflect: true, attribute: "show-line-numbers" })
], FCodeEditor.prototype, "showLineNumbers", 2);
__decorateClass([
  property({ type: Boolean, reflect: true, attribute: "read-only" })
], FCodeEditor.prototype, "readOnly", 2);
__decorateClass([
  query(".copy-button")
], FCodeEditor.prototype, "copyCodeButton", 2);
FCodeEditor = __decorateClass([
  flowElement("f-code-editor")
], FCodeEditor);
self.MonacoEnvironment = {
  getWorker(_, label) {
    if (label === "json") {
      return new WorkerWrapper$3();
    }
    if (label === "css" || label === "scss" || label === "less") {
      return new WorkerWrapper$2();
    }
    if (label === "html" || label === "handlebars" || label === "razor") {
      return new WorkerWrapper$1();
    }
    if (label === "typescript" || label === "javascript") {
      return new WorkerWrapper();
    }
    return new WorkerWrapper$4();
  }
};
export {
  FCodeEditor
};
//# sourceMappingURL=flow-code-editor.es.js.map
