import { ref, computed, watch, onMounted, createElementBlock, openBlock, createElementVNode, createVNode, createCommentVNode, unref, toDisplayString } from "vue";
import { Codemirror as T } from "../../../../node_modules/vue-codemirror/dist/vue-codemirror.esm.mjs";
import { basicSetup } from "../../../../node_modules/codemirror/dist/index.mjs";
import { javascript } from "../../../../node_modules/@codemirror/lang-javascript/dist/index.mjs";
import { autocompletion, closeBrackets } from "../../../../node_modules/@codemirror/autocomplete/dist/index.mjs";
import { MatchDecorator, Decoration, ViewPlugin, EditorView, WidgetType } from "../../../../node_modules/@codemirror/view/dist/index.mjs";
import FormulaEditorCore from "./core/index.mjs";
import FieldVariable from "./components/FieldVariable.vue2.mjs";
import FormulaList from "./components/FormulaList.vue2.mjs";
import functionList from "./function.mjs";
/* empty css           */
import _export_sfc from "../../../../_virtual/_plugin-vue_export-helper.mjs";
const _hoisted_1 = { class: "vue-formula" };
const _hoisted_2 = ["data-error"];
const _hoisted_3 = { class: "operator-container" };
const _hoisted_4 = {
  key: 0,
  class: "formula-desc"
};
const _hoisted_5 = { class: "info-name" };
const _hoisted_6 = { class: "formula-info" };
const _hoisted_7 = { class: "info-text" };
const _hoisted_8 = { class: "info-text" };
const _hoisted_9 = { class: "info-text" };
const _sfc_main = {
  __name: "index",
  props: {
    fieldList: {
      type: Array,
      default: () => []
    },
    formulaConf: {
      type: Object,
      default: () => ({})
    }
  },
  emits: ["fieldSelect", "formulaClick", "enterInfo"],
  setup(__props, { expose: __expose, emit: __emit }) {
    const props = __props;
    const editorCore = ref(null);
    const editorView = ref(null);
    const code = ref("");
    const currentFormula = ref(null);
    const validInfo = ref("");
    ref("");
    class FieldWidget extends WidgetType {
      constructor(name) {
        super();
        this.name = name;
      }
      eq(widget) {
        return this.name === widget.name;
      }
      toDOM() {
        const span = document.createElement("span");
        span.className = "cm-field";
        span.textContent = this.name;
        return span;
      }
      ignoreEvent() {
        return false;
      }
    }
    const fieldMatcher = new MatchDecorator({
      regexp: /\{(\w+)\}/g,
      decoration: (match) => {
        const code2 = match[1];
        const field = props.fieldList.find((item) => item.fieldName === code2);
        const label = field ? field.label : code2;
        return Decoration.replace({
          widget: new FieldWidget(label)
        });
      }
    });
    const fieldMarkPlugin = ViewPlugin.fromClass(
      class {
        constructor(view) {
          this.placeholders = fieldMatcher.createDeco(view);
        }
        update(update) {
          this.placeholders = fieldMatcher.updateDeco(update, this.placeholders);
        }
      },
      {
        decorations: (instance) => instance.placeholders,
        provide: (plugin) => EditorView.atomicRanges.of((view) => {
          var _a;
          return ((_a = view.plugin(plugin)) == null ? void 0 : _a.placeholders) || Decoration.none;
        })
      }
    );
    const autoCompletions = (context) => {
      const word = context.matchBefore(/\w*/);
      if (word.from === word.to && !context.explicit) return null;
      const formulas = functionList.flatMap((group) => group.formula || []);
      const formulaOptions = formulas.map((item) => ({
        label: item.name,
        type: "function",
        detail: item.tip,
        apply: (view, completion, from, to) => {
          view.dispatch({
            changes: { from, to, insert: `${item.name}()` },
            selection: { anchor: from + item.name.length + 1 }
          });
        }
      }));
      const entityOptions = props.fieldList.map((item) => ({
        label: item.fieldName,
        type: "variable",
        detail: item.label,
        apply: `{${item.fieldName}}`
      }));
      const allOptions = [...formulaOptions, ...entityOptions];
      const filteredOptions = allOptions.filter(
        (option) => option.label.toLowerCase().startsWith(word.text.toLowerCase())
      );
      return {
        from: word.from,
        options: filteredOptions.length > 0 ? filteredOptions : allOptions
      };
    };
    const extensions = [
      basicSetup,
      javascript(),
      autocompletion({
        override: [autoCompletions]
      }),
      closeBrackets(),
      fieldMarkPlugin
    ];
    const nodes = computed(() => {
      return functionList || [];
    });
    watch(code, (val) => {
      var _a;
      if (!val) {
        validInfo.value = "";
        return;
      }
      const { error, message } = ((_a = editorCore.value) == null ? void 0 : _a.validateFormula(
        props.fieldList
      )) || { error: false };
      validInfo.value = error ? message : "";
    });
    watch(
      () => props.formulaConf,
      (newVal) => {
        if (editorCore.value && newVal) {
          editorCore.value.renderData(newVal);
        }
      },
      { deep: true }
    );
    const reset = () => {
      var _a;
      currentFormula.value = null;
      (_a = editorCore.value) == null ? void 0 : _a.reset();
    };
    const getData = () => {
      var _a;
      return (_a = editorCore.value) == null ? void 0 : _a.getData();
    };
    const getDisplayData = () => {
      var _a;
      return (_a = editorCore.value) == null ? void 0 : _a.getDisplayData(props.fieldList);
    };
    const onReady = (payload) => {
      editorView.value = payload.view;
      editorCore.value = new FormulaEditorCore(payload.view, "", functionList);
      editorCore.value.registerListen();
      editorCore.value.renderData(props.formulaConf);
    };
    const onFormulaClick = (formula) => {
      var _a;
      currentFormula.value = formula;
      (_a = editorCore.value) == null ? void 0 : _a.insertText(`${formula.name}()`, "formula");
    };
    const onFieldSelect = (field) => {
      var _a;
      (_a = editorCore.value) == null ? void 0 : _a.insertText(field, "field");
    };
    const onEnterInfo = (formulaInfo) => {
      currentFormula.value = formulaInfo;
    };
    onMounted(() => {
    });
    __expose({
      reset,
      getData,
      getDisplayData
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", _hoisted_1, [
        _cache[1] || (_cache[1] = createElementVNode("div", { class: "formula-info-header" }, "公式 =", -1)),
        createVNode(unref(T), {
          modelValue: code.value,
          "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => code.value = $event),
          style: { height: "200px" },
          extensions,
          autofocus: true,
          placeholder: "例如:SUM(数值1,数值2)",
          onReady
        }, null, 8, ["modelValue"]),
        validInfo.value ? (openBlock(), createElementBlock("div", {
          key: 0,
          class: "formula-info-container",
          "data-error": `${validInfo.value != ""}`
        }, [
          createElementVNode("span", null, "公式错误：" + toDisplayString(validInfo.value), 1)
        ], 8, _hoisted_2)) : createCommentVNode("", true),
        createElementVNode("div", _hoisted_3, [
          createVNode(FieldVariable, {
            class: "field-variable",
            onFieldSelect,
            fieldList: __props.fieldList
          }, null, 8, ["fieldList"]),
          createVNode(FormulaList, {
            nodes: nodes.value,
            class: "formula-list",
            onFormulaClick,
            onEnterInfo
          }, null, 8, ["nodes"]),
          currentFormula.value ? (openBlock(), createElementBlock("div", _hoisted_4, [
            createElementVNode("div", _hoisted_5, toDisplayString(currentFormula.value.name), 1),
            createElementVNode("div", _hoisted_6, [
              createElementVNode("div", _hoisted_7, toDisplayString(currentFormula.value.tip), 1),
              createElementVNode("div", _hoisted_8, "用法：" + toDisplayString(currentFormula.value.usage), 1),
              createElementVNode("div", _hoisted_9, "示例：" + toDisplayString(currentFormula.value.example), 1)
            ])
          ])) : createCommentVNode("", true)
        ])
      ]);
    };
  }
};
const FormulaEditor = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-432eb74e"]]);
export {
  FormulaEditor as default
};
