<template>
  <div class="ed-ace">
    <el-button v-if="isDialog" :size="size" icon="el-icon-edit" v-bind="btnProps" @click="handlerOpen">编写代码
    </el-button>

    <component :is="compName" :title="title" :visible.sync="visible" @ok="handlerOk">
      <div class="tree-warning" v-if="Object.keys($slots).includes('tooltip')">
        <slot name="tooltip"></slot>
      </div>

      <toolbar v-if="isToolbar" v-model="form"></toolbar>
      <editor ref="aceEditor" :isDialog="isDialog" :lines="lines" :mode="form.mode" :readOnly="readOnly"
              :theme="form.theme" :value="dataValue" @change="handlerChange"></editor>
    </component>
  </div>
</template>

<script>
import {getOption}  from "./AceConfig"
import Editor       from "./Editor";
// 自定义组件
import Toolbar      from "./Toolbar";
import {getVarType} from "../../../../tools/utils";

export default {
  name: "EdCodeEditor",
  components: {Toolbar, Editor},
  props: {
    // 代码内容
    value: {type: [String, Array, Object], default: ""},

    // 是否显示toolbar
    isToolbar: {type: Boolean, default: false},

    // 是否弹窗打开
    isDialog: {type: Boolean, default: false},

    // 只读
    readOnly: {type: Boolean, default: false},

    // 大小控制
    size: {type: String, default: "small"},

    // 弹窗名称
    title: {type: String, default: "编写代码"},

    // 编辑器高度
    lines: {type: Number},

    // 编辑器主题
    theme: {type: String, default: "monokai"},
    // 编辑器语言
    language: {type: String, default: "Javascript"},
    // 弹窗模式下按钮属性
    btnProps: {
      type: Object, default: () => {
        return {
          round: true,
          type: "primary",
          plain: true
        }
      }
    }
  },
  data() {
    return {
      aceEditor: null,
      visible: false,
      dataValue: "",
      form: {
        mode: getOption(this.language, "mode"),
        theme: getOption(this.theme, "theme"),
        wrap: true
      },
    }
  },
  watch:{
    value:{
      deep: true,
      immediate: true,
      handler(newVal){
        if(newVal && ['object', 'array'].includes(getVarType(newVal))){
          this.dataValue = this.jsonFormat(newVal)
        }
        else if(newVal && getVarType(newVal) === 'string'){
          this.dataValue = newVal
        }
      }
    },
    language: {
      deep: true,
      handler(newVal, oldVal) {
        if (newVal) {
          this.form.mode = getOption(this.language, "mode")
        }
      }
    },
    theme: {
      deep: true,
      handler(newVal, oldVal) {
        if (newVal) {
          this.form.theme = getOption(this.theme, "theme")
        }
      }
    }
  },
  computed: {
    compName() {
      return this.isDialog ? "ed-dialog" : "div"
    }
  },
  methods: {
    // 格式化代码函数
    jsonFormat(dataForm) {
      return JSON.stringify(dataForm, null, 2)
    },

    // 打开弹窗
    handlerOpen() {
      this.visible = true
    },

    // 弹窗确认按钮
    handlerOk() {
      if (this.isDialog) {
        this.$emit("input", this.$refs.aceEditor.getValue())
        this.$emit("change", this.$refs.aceEditor.getValue())
      }
      this.$nextTick(() => {
        this.visible = false
      })
    },

    // 编辑器内容变更
    handlerChange(value) {
      if (!this.isDialog) {
        this.$emit("input", value)
        this.$emit("change", value)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.tree-warning {
  padding: 8px 16px;
  background-color: #ecf8ff;
  border-radius: 4px;
  border-left: 5px solid #50bfff;
  margin: 20px 0;
  font-size: 14px;
  color: #5e6d82;
  line-height: 25px;
}
</style>
