import { ref as $ } from "vue";
import { getMergeMeta as N, useResource as y, useCanvas as C, useRobot as w, getMetaApi as T, META_SERVICE as P } from "@opentiny/tiny-engine-meta-register";
const J = `你是一个JavaScript代码补全器，可以使用JS和ES的语法

以下是一些通用的协议：
常规属性如：{ width: '300px' }
一. 变量引用
{ width: { type: 'JSExpression', value: 'this.state.xxx' }
即当type为JSExpression，取其value并将value的值当做变量调用
二. 方法引用
{ onClickNew: { type: 'JSFunction', value: 'function onClickNew() {}' }
即当type为JSFunction，取其value并将value的值函数调用
以下是一些依赖，调用均以this.开头:
1. 数据源
数据源是定义的数据模型
const dataSource=$dataSource$
调用方式为： this.dataSource.xxx
2. 工具类
工具类是通用的调用方法或npm依赖
const utils=$utils$
调用方式为： this.utils.xxx 
utils有两种类型
type为npm时，读取content内容，可构造如下引用，例如content中package（依赖包名）为@opentiny/vue，destructuring(解构)为true，exportName（导出组件名称）为Notify，实际引用方式是import { Notify } from '@opentiny/vue';
type为function时，读取content内容，当content.type为JSFunction则将value视为JS方法并调用，其他可参考通用的协议
3. 全局变量
全局变量是使用pinia创建的变量
const stores=$globalState$
调用方式为： this.stores.xxx
4. JS变量
js变量
const state=$state$
调用方式为： this.state.xxx
5. JS方法
js方法
const methods=$methods$
调用方式为： this.xxx

以上依赖中没有的，则不能调用，如utils中没有axios，则axios不能使用

以下是当前选中的组件
$currentSchema$
请理解当前组件，componentName为组件名称，组件包括tinyVue组件、ElementPlus组件，和基本html元素
对象中的ref属性即vue组件的ref属性，如ref值为testForm，使用方式为this.$('testForm')
props表示组件的属性，是一个对象，对应vue组件的defineProps和defineEmits中的内容
props中以on开头的表示其传递的是方法，如onClick，其值可以参考通用协议
props中没有以on开头的则是普通属性，如tinyInput组件中的placeholder
props的属性中值为对象，且包含type和value属性，type为JSExpression和JSFunction时，value的值则参考通用协议取用

直接上下文如下：
$codeBeforeCursor$<cursor>$codeAfterCursor$
请从<cursor>（光标位置）后进行补全
注意如果是函数时，须以function关键字开头，不使用箭头函数
请只返回代码，且只返回一个示例，不需要思考过程和解释`, O = [
  "state",
  "stores",
  "props",
  "emit",
  "setState",
  "route",
  "i18n",
  "getLocale",
  "setLocale",
  "history",
  "utils",
  "bridge",
  "dataSourceMap"
], k = [
  {
    lable: "new function",
    type: "Function",
    insertText: "function ${1:funName} (${2}) {\n  ${3}\n}",
    detail: "create new function"
  }
], p = {
  Method: "Method",
  Variable: "Variable"
}, L = (n, t, a) => O.map((r) => ({
  label: `this.${r}`,
  kind: n.languages.CompletionItemKind.Keyword,
  insertText: `this.${r}`,
  detail: "Lowcode API",
  range: t
})).filter(({ insertText: r }) => r.indexOf(a) === 0), A = (n, t, a) => k.map((r) => ({
  label: r.lable,
  insertText: r.insertText,
  detail: r.detail,
  kind: n.languages.CompletionItemKind[r.type],
  insertTextRules: n.languages.CompletionItemInsertTextRule.InsertAsSnippet,
  range: t
})).filter(({ insertText: r }) => r.indexOf(a) === 0), j = () => {
  const { bridge: n = [], dataSource: t = [], utils: a = [], globalState: r = [] } = y().appSchemaState;
  return {
    state: {
      type: p.Variable,
      getInsertText: (e) => `this.state.${e}`,
      data: Object.keys(C().getPageSchema().state || {})
    },
    stores: {
      type: p.Variable,
      getInsertText: (e) => `this.stores.${e}`,
      data: r.filter((e) => e.id).map((e) => [
        e.id,
        ...[...Object.keys(e.state), ...Object.keys(e.getters)].map((o) => `${e.id}.${o}`)
      ]).flat()
    },
    storeFn: {
      type: p.Method,
      getInsertText: (e) => `this.stores.${e}()`,
      data: r.filter((e) => e.id).map((e) => Object.keys(e.actions).map((o) => `${e.id}.${o}`)).flat()
    },
    utils: {
      type: p.Variable,
      getInsertText: (e) => `this.utils.${e}`,
      data: a.map((e) => e.name)
    },
    dataSource: {
      type: p.Method,
      getInsertText: (e) => `this.dataSourceMap.${e}.load()`,
      data: t.map((e) => e.name)
    },
    bridge: {
      type: p.Variable,
      getInsertText: (e) => `this.bridge.${e}`,
      data: n.map((e) => e.name)
    }
  };
}, V = (n, t, a) => {
  const r = j();
  return Object.entries(r).map(
    ([e, o]) => o.data.map((s) => ({
      kind: n.languages.CompletionItemKind[o.type],
      label: o.getInsertText(s),
      insertText: o.getInsertText(s),
      detail: "Lowcode API",
      range: t
    }))
  ).flat().filter(({ insertText: e }) => e.indexOf(a) === 0);
}, b = (n, t) => ({ word: n.getValueInRange({
  startLineNumber: t.lineNumber,
  endLineNumber: t.lineNumber,
  startColumn: t.column - 1,
  endColumn: t.column
}), startColumn: t.column - 1, endColumn: t.column }), v = (n, t) => {
  const a = [], r = n.getWordUntilPosition(t).word ? n.getWordAtPosition(t) : b(n, t);
  a.push(r);
  const e = { ...t, column: r.startColumn };
  for (; e.column > 1; ) {
    const o = n.getWordUntilPosition(e).word ? n.getWordUntilPosition(e) : b(n, e);
    if (!/[\w.]/.test(o.word)) break;
    a.push(o), e.column = o.startColumn;
  }
  return a.reverse();
}, I = (n, t) => ({
  startLineNumber: n.lineNumber,
  endLineNumber: n.lineNumber,
  startColumn: t[0].startColumn,
  endColumn: t[t.length - 1].endColumn
}), E = () => {
  const { dataSource: n = [], utils: t = [], globalState: a = [] } = y().appSchemaState, { state: r, methods: e } = C().getPageSchema(), o = C().getCurrentSchema();
  let s = J;
  return s = s.replace("$dataSource$", JSON.stringify(n)), s = s.replace("$utils$", JSON.stringify(t)), s = s.replace("$globalState$", JSON.stringify(a)), s = s.replace("$state$", JSON.stringify(r)), s = s.replace("$methods$", JSON.stringify(e)), s = s.replace("$currentSchema$", JSON.stringify(o)), s;
}, M = (n, t) => {
  var s;
  const { completeModel: a, apiKey: r, baseUrl: e } = ((s = w().robotSettingState) == null ? void 0 : s.selectedModel) || {};
  if (!a || !r || !e)
    return;
  const o = E();
  return T(P.Http).post(
    "/app-center/api/chat/completions",
    {
      model: a,
      messages: [
        {
          role: "user",
          content: o.replace("$codeBeforeCursor$", n).replace("$codeAfterCursor$", t)
        }
      ],
      baseUrl: e,
      stream: !1
    },
    {
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${r}`
      }
    }
  );
}, R = (n, t) => {
  const a = $(!0), r = $(), e = {
    provideInlineCompletions(o, s, m, f) {
      if (t && o.id !== t.id)
        return new Promise((i) => {
          i({ items: [] });
        });
      r.value && clearTimeout(r.value);
      const S = v(o, s), x = I(s, S), u = S.map((i) => i.word).join("");
      if (!u || u.lastIndexOf("}") === 0 || u.length < 4)
        return new Promise((i) => {
          i({ items: [] });
        });
      if (!a.value)
        return new Promise((i) => {
          i({
            items: [
              {
                insertText: "",
                range: x
              }
            ]
          });
        });
      const g = o.getValueInRange({
        startLineNumber: 1,
        startColumn: 1,
        endLineNumber: s.lineNumber,
        endColumn: s.column
      }), d = o.getValueInRange({
        startLineNumber: s.lineNumber,
        startColumn: s.column,
        endLineNumber: o.getLineCount(),
        endColumn: o.getLineMaxColumn(o.getLineCount())
      });
      return new Promise((i) => {
        r.value = setTimeout(() => {
          a.value = !1, M(g, d).then((h) => {
            let l = h.choices[0].message.content.trim();
            const c = l.indexOf(u);
            c === -1 && (l = `${u}${l}
`), c > 0 && (l = l.slice(c)), a.value = !0, i({
              items: [
                {
                  insertText: l,
                  range: x
                }
              ]
            });
          }).catch(() => {
            a.value = !0;
          });
        }, 800);
      });
    },
    freeInlineCompletions() {
    }
  };
  return ["javascript", "typescript"].map(
    (o) => n.languages.registerInlineCompletionsProvider(o, e)
  );
}, K = (n, t, a) => {
  var s;
  const r = {
    provideCompletionItems(m, f, S, x) {
      if (t && m.id !== t.id)
        return {
          suggestions: []
        };
      const u = v(m, f), g = u.map((c) => c.word).join(""), d = I(f, u), i = L(n, d, g), h = A(n, d, g), l = V(n, d, g);
      return {
        suggestions: [...i, ...h, ...l].filter(
          (c) => a ? a(c) : !0
        )
      };
    },
    triggerCharacters: ["."]
  }, e = ["javascript", "typescript"].map((m) => n.languages.registerCompletionItemProvider(m, r)), { enableAICompletion: o } = ((s = N("engine.plugins.pagecontroller")) == null ? void 0 : s.options) || {};
  return o ? e.concat(R(n, t)) : e;
};
export {
  K as initCompletion
};
//# sourceMappingURL=completion.js.map
