<template>
  <el-dialog :modelValue="visible"
             :close-on-click-modal="false"
             :before-close="handleClose"
             class="avue-dialog avue-code-edit"
             :title="title || '数据处理'"
             width="90%">
    <other-list>
      <div class="item">
        <el-button type="primary"
                   @click="$refs.codeTip.open()"
                   icon="el-icon-notebook">说明</el-button>
      </div>
      <div class="item">
        <el-button icon="el-icon-plus"
                   type="primary"
                   @click="handleSc()">加入代码库</el-button>
      </div>
      <div class="item">
        <el-button icon="el-icon-download"
                   type="primary"
                   @click="handleImport()">从代码库导入</el-button>
      </div>
      <div class="item">
        <el-button icon="el-icon-edit"
                   type="primary"
                   v-if="isCode"
                   @click="handleOpen">放大编辑器</el-button>
      </div>
      <div class="item">
        <el-button icon="el-icon-user"
                   type="success"
                   v-if="$website.aiSwitch"
                   @click="handleOpenGpt()">智能AI</el-button>
      </div>
    </other-list>
    <div class="avue-flex"
         :key="reload"
         style="align-items: flex-start;">
      <monaco-editor v-model="code"
                     v-loading="loading"
                     v-bind="$loadingParams"
                     :language="isObject?'json':language"></monaco-editor>
      <gpt ref="gpt"
           @code="handleCode"
           :type="type"
           style="max-height: 400px;"
           :prompt-option="promptOption"
           v-if="gptBox&&$website.aiSwitch"
           @start="handleStart"></gpt>
      <json-viewer :value="dataView"
                   copyable
                   v-show="dataView"
                   :expand-depth="1"
                   theme="avue-json-theme"
                   boxed></json-viewer>
      <json-viewer :value="dataView"
                   copyable
                   v-show="dataView"
                   :expand-depth="1"
                   theme="avue-json-theme"
                   boxed></json-viewer>
    </div>
    <span class="avue-dialog__footer avue-dialog__footer--right">
      <el-button @click="setVisible(false)">取 消</el-button>
      <el-button type="primary"
                 @click="submit">确 定</el-button>
    </span>
    <code-tip ref="codeTip"
              :type="type"></code-tip>
    <code-edit ref="code"
               @change="handleCodeChange"
               v-model="form"></code-edit>
    <el-dialog title="代码库"
               append-to-body
               class="avue-dialog"
               v-model="api.box"
               width="70%">
      <fun-list v-if="api.box"
                @change="handleApiChange"
                :menu="false"></fun-list>
    </el-dialog>
  </el-dialog>
</template>

<script>
import funList from '@/page/list/fun.vue'
import codeEdit from '@/page/components/code-edit.vue'
import { getFunction } from '@/utils/utils'
import otherList from './other-list.vue'
import MonacoEditor from '@/page/components/monaco-editor'
import codeTip from './code-tip.vue'
import gpt from '@/page/list/chatgpt.vue'
import { addObj, getObj } from '@/api/fun'
import { dicOption } from '@/option/config';
import dataFormat from './data-format'
export default {
  inject: ["contain"],
  components: { codeEdit, MonacoEditor, codeTip, otherList, gpt, funList },
  data () {
    return {
      promptOption: {},
      form: {},
      api: {
        box: false,
        item: {}
      },
      reload: Math.random(),
      gptBox: false,
      loading: false,
      code: ''
    }
  },
  props: {
    rules: {
      type: Boolean,
      default: true
    },
    language: {
      type: String,
      default: 'javascript'
    },
    dataView: [String, Object, Array],
    codeType: String,
    title: String,
    visible: Boolean,
    isObject: Boolean,
    type: String,
    modelValue: [String, Object, Array]
  },
  computed: {
    isCode () {
      let prop = this.codeType
      return ['vue', 'common', 'html', 'echart'].includes(prop)
    }
  },
  watch: {
    modelValue: {
      handler (val) {
        if (this.validatenull(val)) {
          if (['dataFormatter', 'stylesFormatter'].includes(this.type) && this.validatenull(val)) {
            this.code = `(data,params,refs)=>{
    return {}
}`
          } else if (['query', 'header', 'dataQuery', 'dataHeader'].includes(this.type) && this.validatenull(val)) {
            this.code = `(data)=>{
    return {}
}`
          } else if (['echartFormatter'].includes(this.type) && this.validatenull(val)) {
            this.code = `(data)=>{
    const myChart = this.myChart;
    const option={}
    return option
}`
          } else if (['clickFormatter', 'dblClickFormatter', 'mouseEnterFormatter', 'mouseLeaveFormatter', 'dataBeforeFormatter', 'dataAfterFormatter'].includes(this.type) && this.validatenull(val)) {
            this.code = `(params,refs,safe)=>{
    console.log(params,refs,safe)
}`
          } else if (['labelFormatter', 'formatter'].includes(this.type) && this.validatenull(val)) {
            this.code = `(name,data)=>{
    console.log(name,data)
    return ''
}`
          } else if (['before'].includes(this.type) && this.validatenull(val)) {
            this.code = `(data)=>{
    return new Promise(resolve=>{
      resolve()
    })
}`
          } else {
            this.code = val;
          }
        } else {
          this.code = val;
        }
      },
      immediate: true,
      deep: true,
    },
    type: {
      handler (val) {
        this.setOption(val)
      },
      immediate: true,
    }
  },
  methods: {
    setOption (val) {
      const formatDataValue = (value) => {
        return typeof value === 'object' ? JSON.stringify(value) : value
      }
      if (val === 'dataFormatter') {
        const componentData = dataFormat[this.contain.activeComponent.prop].data
        this.promptOption = {
          type: 'filter',
          examData: formatDataValue(componentData),
          data: formatDataValue(this.dataView)
        }
      } else if (val === 'column') {
        this.promptOption = {
          type: 'crud',
          code: this.code
        }
      } else if (val === 'sql') {
        this.promptOption = {
          type: 'sql',
          code: this.code
        }
      } else {
        this.promptOption = {
          type: this.codeType || val,
          code: this.code
        }
      }
    },
    handleOpen () {
      let typeList = {
        vue: 0,
        echart: 1,
        html: 2
      };
      this.form = {
        content: this.code,
        type: typeList[this.codeType]
      }
      this.$refs.code.handleOpen()
    },
    handleCodeChange (val) {
      if (val.content) this.code = val.content
    },
    handleApiChange (val) {
      this.api.item = val
      getObj(this.api.item.id).then(res => {
        const data = res.data.data;
        this.code = data.content
        this.api.box = false;
        this.api.item = {}
        this.$message.success('导入成功')
      })
    },
    handleImport () {
      this.api.box = true
    },
    handleSc () {
      this.$DialogForm({
        title: '收藏代码',
        width: '400px',
        menuPosition: 'right',
        option: {
          labelWidth: 80,
          submitText: '确认',
          span: 24,
          column: [{
            label: "名称",
            prop: "name",
            rules: [{
              required: true,
              message: "请输入名称",
              trigger: "blur"
            }],
          }, {
            label: "类别",
            prop: "type",
            type: 'select',
            dicData: dicOption.funType,
            rules: [{
              required: true,
              message: "请选择类别",
              trigger: "blur"
            }],
          }]
        },
        callback: (res) => {
          const form = res.data || {}
          addObj({
            type: form.type,
            name: form.name,
            content: this.formatDataValue(this.code)
          }).then(() => {
            res.close()
            this.$message.success('收藏成功')
          })
        }
      })
    },
    handleOpenGpt () {
      this.gptBox = !this.gptBox
      this.reload = Math.random()
    },
    handleStart () {
      this.loading = true
    },
    handleCode (code) {
      this.loading = false
      this.code = code
      this.$message.success('代码生成完成')
    },
    handleClose () {
      this.setVisible(false);
    },
    submit () {
      let value = this.code;
      if (!this.rules) {
        this.$emit('submit', value);
        this.setVisible(false)
      }else {
        if (this.isObject&&typeof(value)=='string') value = getFunction(value);
        this.$emit('submit', value);
        this.setVisible(false)
      }
    },
    setVisible (val) {
      this.$emit('update:visible', val);
    }
  }
}
</script>

<style lang="scss" scoped>
.filter-tip-content {
  padding: 5px;
  min-width: 250px;
  .el-input {
    width: 100%;
  }
}
</style>