"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const Vue = require("vue");
const vueCodemirror_esm = require("../../../../node_modules/vue-codemirror/dist/vue-codemirror.esm.js");
const index$1 = require("../../../../node_modules/codemirror/dist/index.js");
const index$2 = require("../../../../node_modules/@codemirror/lang-javascript/dist/index.js");
const index$3 = require("../../../../node_modules/@codemirror/autocomplete/dist/index.js");
const index = require("../../../../node_modules/@codemirror/view/dist/index.js");
const index$4 = require("./core/index.js");
const FieldVariable = require("./components/FieldVariable.vue2.js");
const FormulaList = require("./components/FormulaList.vue2.js");
const _function = require("./function.js");
;/* empty css           */
const _pluginVue_exportHelper = require("../../../../_virtual/_plugin-vue_export-helper.js");
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 = Vue.ref(null);
    const editorView = Vue.ref(null);
    const code = Vue.ref("");
    const currentFormula = Vue.ref(null);
    const validInfo = Vue.ref("");
    Vue.ref("");
    class FieldWidget extends index.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 index.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 index.Decoration.replace({
          widget: new FieldWidget(label)
        });
      }
    });
    const fieldMarkPlugin = index.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) => index.EditorView.atomicRanges.of((view) => {
          var _a;
          return ((_a = view.plugin(plugin)) == null ? void 0 : _a.placeholders) || index.Decoration.none;
        })
      }
    );
    const autoCompletions = (context) => {
      const word = context.matchBefore(/\w*/);
      if (word.from === word.to && !context.explicit) return null;
      const formulas = _function.default.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 = [
      index$1.basicSetup,
      index$2.javascript(),
      index$3.autocompletion({
        override: [autoCompletions]
      }),
      index$3.closeBrackets(),
      fieldMarkPlugin
    ];
    const nodes = Vue.computed(() => {
      return _function.default || [];
    });
    Vue.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 : "";
    });
    Vue.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 index$4.default(payload.view, "", _function.default);
      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;
    };
    Vue.onMounted(() => {
    });
    __expose({
      reset,
      getData,
      getDisplayData
    });
    return (_ctx, _cache) => {
      return Vue.openBlock(), Vue.createElementBlock("div", _hoisted_1, [
        _cache[1] || (_cache[1] = Vue.createElementVNode("div", { class: "formula-info-header" }, "公式 =", -1)),
        Vue.createVNode(Vue.unref(vueCodemirror_esm.Codemirror), {
          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 ? (Vue.openBlock(), Vue.createElementBlock("div", {
          key: 0,
          class: "formula-info-container",
          "data-error": `${validInfo.value != ""}`
        }, [
          Vue.createElementVNode("span", null, "公式错误：" + Vue.toDisplayString(validInfo.value), 1)
        ], 8, _hoisted_2)) : Vue.createCommentVNode("", true),
        Vue.createElementVNode("div", _hoisted_3, [
          Vue.createVNode(FieldVariable.default, {
            class: "field-variable",
            onFieldSelect,
            fieldList: __props.fieldList
          }, null, 8, ["fieldList"]),
          Vue.createVNode(FormulaList.default, {
            nodes: nodes.value,
            class: "formula-list",
            onFormulaClick,
            onEnterInfo
          }, null, 8, ["nodes"]),
          currentFormula.value ? (Vue.openBlock(), Vue.createElementBlock("div", _hoisted_4, [
            Vue.createElementVNode("div", _hoisted_5, Vue.toDisplayString(currentFormula.value.name), 1),
            Vue.createElementVNode("div", _hoisted_6, [
              Vue.createElementVNode("div", _hoisted_7, Vue.toDisplayString(currentFormula.value.tip), 1),
              Vue.createElementVNode("div", _hoisted_8, "用法：" + Vue.toDisplayString(currentFormula.value.usage), 1),
              Vue.createElementVNode("div", _hoisted_9, "示例：" + Vue.toDisplayString(currentFormula.value.example), 1)
            ])
          ])) : Vue.createCommentVNode("", true)
        ])
      ]);
    };
  }
};
const FormulaEditor = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["__scopeId", "data-v-432eb74e"]]);
exports.default = FormulaEditor;
