<template>
  <div :class="{'max-box':max, 'min-box':!max, ...customClass}" :style="{height: height, ...customStyle}"
       class="jsonEditor-container">
    <div ref="jsonEditor" class="jsonEditor-box"></div>
    <button v-if="mode === 'code'" class="max-btn" type="button" @click="max = !max"></button>
  </div>
</template>

<script>
// 引入组件
import JSONEditor from "jsoneditor/dist/jsoneditor.min"
import './jsoneditor.scss'
import {OPTIONS} from './hooks'

/**
 * JSON编辑器
 * - 示例
 *
 * ```vue
 * <ed-json-editor v-model="value"></ed-json-editor>
 * ```
 *
 * [](./EdJsonEditorProps.md ':include')
 */
export default {
  name: "EdJsonEditor",
  data() {
    return {
      editor: null,
      expandedModes: ["tree", "view", "form"],
      max: false,
      internalChange: false,
    }
  },
  props: {
    // 显示模式
    mode: {type: String, default: 'code'},
    // 值
    value: [Array, Object, String],
    // 高度
    height: {type: [String, Number], default: '500px'},
    // 属性
    options: {type: Object, default: () => {return OPTIONS}},
    // 自定义class 类名
    customClass: {type: Object, default: () => ({})},
    // 自定义样式
    customStyle: {type: Object, default: () => ({})},
    // 是否启动时展开所有
    expandedOnStart: {type: Boolean, default: true}
  },
  model: {
    prop: "value",
    event: "change"
  },
  methods: {
    /**
     * @private
     */
    onChange() {
      let error = null
      let json = {}
      try {
        json = this.editor.get()
      } catch (err) {
        error = err
      }
      if (error) {
        this.$emit("error", error)
      } else {
        if (this.editor) {
          this.internalChange = true
          this.$emit("change", json)
          this.$nextTick(() => {
            this.internalChange = false
          })
        }
      }
    },
    // 初始化
    initView() {
      if (!this.editor) {
        const container = this.$refs.jsonEditor;
        this.editor = new JSONEditor(container, {
          mode: this.mode, // 默认模式
          ...this.options,
          onChange: this.onChange,
          onModeChange: this.expandAll
        })
      }
      this.editor.set(this.value !== undefined ? this.value : {})
    },

    // 启动时展开所有
    expandAll() {
      if (this.expandedOnStart && this.expandedModes.includes(this.editor.getMode())) {
        this.editor.expandAll();
      }
    },

    // 销毁
    destroyView() {
      if (this.editor) {
        this.editor.destroy()
        this.editor = null
      }
    }
  },
  watch: {
    value: {
      handler(value) {
        if (this.editor && value !== undefined && !this.internalChange) {
          this.editor.set(value)
        }
      },
      deep: true
    },
    max(value) {
      this.$nextTick(() => {
        this.initView()
      })
    },
    options: {
      handler(value) {
        if (this.options && this.options.mode && this.editor) {
          this.editor.setMode(this.options.mode)
        }
      },
      deep: true
    }
  },
  mounted() {
    this.initView()
  },
  beforeDestroy() {
    this.destroyView()
  },
  computed: {
    getHeight() {
      if (this.height && !this.max) {
        return {
          height: this.height
        }
      }
      return {}
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep {
  .jsoneditor-poweredBy, .jsoneditor-jmespath-label, #wizard {
    display: none !important;
  }
}



</style>
