<template>
  <div :id="id" v-loading="loading" class="fm-code-editor" :style="{width: width, height: height}"></div>
</template>

<script>
import {loadJs} from '../../util'

export default {
  props: {
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '100%'
    },
    mode: {
      type: String,
      default: 'xml'
    },
    value: {
      type: [String, Object, Array]
    }
  },
  data () {
    return {
      id: 'code_' + Math.random().toString(36).slice(-8),
      codeValue: this.value,
      loading: true,
      observer: null,
      editor: null
    }
  },
  computed: {
    aceMode () {
      switch (this.mode) {
        case 'xml':
          return 'ace/mode/xml'
        case 'html':
          return 'ace/mode/html'
        case 'json':
          return 'ace/mode/json'
        case 'css':
          return 'ace/mode/css'
        case 'javascript':
          return 'ace/mode/javascript'
        case 'tsx':
          return 'ace/mode/tsx'
        default:
          return 'ace/mode/xml'
      }
    }
  },
  mounted () {

    console.log('code editor mounted.')

    setTimeout(() => {
      // if (window.ace) {
      //   console.log(window.ace);
      //   this.loadEditor()
      // } else {
      //   loadJs(`${window.FormMaking_OPTIONS.aceurl}/ace.js`).then(() => {
      //     loadJs(`${window.FormMaking_OPTIONS.aceurl}/ext-language_tools.js`).then(() => {
      //       this.loadEditor()
      //     })
      //   })
      // }
      loadJs(`${window.FormMaking_OPTIONS.aceurl}/ace.js`).then(() => {
        loadJs(`${window.FormMaking_OPTIONS.aceurl}/ext-language_tools.js`).then(() => {
          this.loadEditor()
        })
      })
    }, 0)
  },
  methods: {
    loadEditor () {
      this.loading = false

      ace.require("ace/ext/language_tools")

      this.editor = ace.edit(this.id)

      // const beautify = ace.require("ace/ext/beautify")

      this.editor.session.setMode(this.aceMode)
      this.editor.setFontSize(13)
      this.editor.getSession().setTabSize(2)
      this.editor.setShowPrintMargin(false)
      // editor.setReadOnly(true)

      this.editor.setOptions({
        // enableBasicAutoCompletion : true,
        enableSnippets : true,
        enableLiveAutocompletion : true
      });

      this.editor.commands.addCommand({

          name: 'myCommand',

          bindKey: {win: 'Ctrl-Enter',  mac: 'Command-Enter'},

          exec: function(editor) {

              const currentCursor = editor.selection.getCursor();

              editor.selection.moveCursorLineEnd()

              editor.selection.moveTo(editor.selection.getCursor().row, editor.selection.getCursor().column)

              editor.session.insert(editor.getCursorPosition(), '\n')
          }

      });

      this.editor.setValue(typeof this.codeValue === 'string' ? this.codeValue : JSON.stringify(this.codeValue, null, '\t'), -1)

      this.editor.on('change', (e) => {
        this.codeValue = this.editor.getValue()
      })

      this.editor.on('paste', (e) => {
        this.mode === 'json' && setTimeout(() => {
          this.editor.setValue(JSON.stringify(JSON.parse(e.text), null, 2), -1)
        })
      })
    },
    setValue (value) {
      this.editor.setValue(JSON.stringify(JSON.parse(value), null, 2), -1)
    }
  },
  watch: {
    value (val) {
      this.codeValue =  val
    },
    codeValue (val) {
      this.$emit('input', val)
    }
  },
  beforeUnmount () {
    this.editor.destroy()
    this.editor.container.remove()
  },
}
</script>

<style lang="scss">
.fm-code-editor{
  border: 1px solid #DCDFE6;
}
</style>
