<template>
  <el-dialog @opened="dialogOpen"
             :title='pageTitle'
             :visible.sync="dialogVisible"
             @closed="dialogClose"
             width="95%"
             :append-to-body='true'
             :close-on-click-modal='false'>
    <div id="jsonEditBox">
      <div style="display:flex;">
        <div class="editItemBox1">
          <div class="editeTitleItem">配置</div>
          <div :id='ideditor1'
               style="width: 100%; height: 100%;"></div>
        </div>
        <div class="editItemBox2">
          <div class="editeTitleItem">模拟数据</div>
          <div :id='ideditor2'
               style="width: 100%; height: 100%;"></div>
        </div>
        <div class="editItemBox3"
             v-show="false">
          <div class="editeTitleItem">SQL</div>
          <div :id='ideditor3'
               style="width: 100%; height: 100%;"></div>
        </div>
        <div class="editItemBox3">
          <div class="editeTitleItem">SQL</div>
          <div ref='monacoEdit'
               style="width: 100%; height: 100%;border:1px solid #1160f1"></div>
        </div>
      </div>

      <el-row :gutter="20">
        <div class="buttonBox">
          <div class="infopageItem">
            <div class="pageItem">
              <span>组件名称：{{elInfo_.el}}</span>
            </div>
            <div class="pageItem">
              <span>版本号：{{this.editDataAll.version}}</span>
            </div>
            <div class="pageItem">
              <span>时间：{{this.editDataAll.update_time}}</span>
            </div>
          </div>
          <div class="button_hanlde">
            <el-switch v-model="is_mock"
                       active-text="模拟"
                       inactive-text="正式">
            </el-switch>
            <el-button v-show="layout"
                       size='mini'
                       plain
                       type="danger"
                       @click='changControl(1)'>上一个</el-button>
            <el-button v-show="layout"
                       size='mini'
                       plain
                       type="warning"
                       @click='changControl(2)'>下一个</el-button>
            <el-button size='mini'
                       plain
                       type="success"
                       @click='execSql'>模拟数据</el-button>
            <el-button size='mini'
                       type="primary"
                       @click='showView'
                       v-show="is_show_preview">查看效果</el-button>
            <el-button size='mini'
                       type="danger"
                       @click="submitToDb">提交到数据库</el-button>
            <el-button size='mini'
                       type="warning"
                       @click='resetEdit'>撤销修改</el-button>
            <el-button size='mini'
                       plain
                       @click='lookPageLogView'>查看日志</el-button>
            <el-button size='mini'
                       type="success"
                       @click='downSql_'>另存</el-button>
          </div>
        </div>
        <div v-show="!lookPageLogVisible">
          <template v-if='elInfo_.el=="hsLineBar"||elInfo_.el=="hsPie"||elInfo_.el=="hsRadar"'>
            <commonEchart :elInfo='elInfo_'
                          :initStyle='initStyle'
                          :allSourceData="commonData"></commonEchart>
          </template>
          <template v-if='elInfo_.el==="hsCarousel"'>
            <commonCarousel :initStyle='initStyle'
                            :setOptions="commonData"></commonCarousel>
          </template>
          <template v-if='elInfo_.el==="hsTable"'>
            <commonTable :initStyle='initStyle'
                         :setOptions="commonData"></commonTable>
          </template>
          <template v-if='elInfo_.el==="hsSelect"'>
            <commonSelect :setOptions="commonData"></commonSelect>
          </template>
        </div>

      </el-row>
    </div>
    <lookPageLog @revertVersion='revertVersion_'
                 :isrequest='isrequest'
                 @showView='showViewLog'
                 v-if="lookPageLogVisible"
                 :elInfo='elInfo_'>
    </lookPageLog>
  </el-dialog>
</template>

<script>
import commonEchart from './commonEchart'
import commonCarousel from './commonCarousel'
import commonTable from './commonTable'
import lookPageLog from './lookPageLog'
import commonSelect from './commonSelect'
import uuidv1 from 'uuid/v1'
import * as monaco from 'monaco-editor'
import sqlFormatter from 'sql-formatter'
import mockData from './initDbConfigDataJson'
export default {
  components: { commonEchart, commonCarousel, commonTable, lookPageLog, commonSelect },
  name: 'jsoneditor',
  props: {
    elInfo: {
      type: Object,
      default() {
        return {}
      }
    },
    // saveConfigDataFun: {
    //   type: Function
    // },
    initStyle: {
      type: Object,
      default() {
        return {}
      }
    },
    complatData: {
      type: Array,
      default() {
        return []
      }
    },
    value: Boolean,
    layout: {},
    is_show_preview: {
      type: Boolean,
      default() {
        return true
      }
    }
  },
  watch: {
    value(val) {
      this.dialogVisible = val
    },
    dialogVisible(val) {
      this.$emit('input', val)
    }
  },
  data() {
    return {
      options: {
        mode: 'text',
        indentation: 2,
        search: true
      },
      ideditor1: 'b' + uuidv1(),
      ideditor2: 'b' + uuidv1(),
      ideditor3: 'b' + uuidv1(),
      editor1: null,
      editor2: null,
      commonData: {},
      copyJsoneditorData: null,
      monacoEdit: null,
      pageTitle: '配置',
      dialogVisible: false,
      editDataAll: {},
      lookPageLogVisible: false,
      isrequest: false,
      elInfo_: {},
      is_mock: true
    }
  },
  mounted() {
    this.elInfo_ = JSON.parse(JSON.stringify(this.elInfo))
  },
  methods: {
    changeElMock() {
      console.log(this.layout, this.is_mock)
    },
    // 折线图的模拟数据
    getMockData(type) {
      return mockData[type]
    },
    changControl(flage) {
      if (this.layout) {
        const list = this.layout.filter(item => item.isRequestControl)
        const currIndex = list.findIndex(item => item.control.position === this.elInfo_.position)
        let nextIndex = 0
        let target = null
        if (flage === 1) { // 上一个
          if (currIndex === 0) {
            this.$message('已经是第一个了')
            return
          }
          nextIndex = currIndex - 1
          target = list[nextIndex]
        } else { // 下一个
          if (currIndex === list.length - 1) {
            this.$message('已经是最后个了')
            return
          }
          nextIndex = currIndex + 1
          target = list[nextIndex]
        }
        this.elInfo_ = target.control
        this.getPageInfo(target.control)
      }
    },
    lookPageLogView() {
      this.lookPageLogVisible = true
      this.isrequest = !this.isrequest
    },
    showViewLog(data) {
      this.editor1.set(data.config)
      this.editor2.set(data.sourceData)
      this.initSqlEdit('monacoEdit', 'monacoEdit', data.sql || '')
      this.showView()
    },
    revertVersion_(parm) {
      this.$API.revertPageLog(parm).then(res => {
        this.getPageInfo()
        this.isrequest = !this.isrequest
      })
    },
    execSql() {
      const exec = this.monacoEdit.getValue()
      this.$API.execSql(exec).then(res => {
        this.editor2.set(res)
      })
    },
    getPageInfo(info = this.elInfo) {
      const parm = {}
      parm.position = info.position
      parm.page = info.page
      this.$API.getSql(parm).then(data => {
        if (data && data.length) {
          this.editDataAll = data[0]
          const { app_code, control_name, json_config, json_data, page_name, query_sql, is_mock } = this.editDataAll
          this.pageTitle = `配置: AppCode: <${app_code}>---page_name: <${page_name}>---control_name: <${control_name}>`
          const jsonData = {
            config: JSON.parse(json_config),
            sourceData: JSON.parse(json_data),
            sql: query_sql || ''
          }
          this.copyJsoneditorData = JSON.parse(JSON.stringify(jsonData))
          this.setJson(jsonData)
          this.initSqlEdit('monacoEdit', 'monacoEdit', query_sql || '')
          this.is_mock = !!is_mock
        } else {
          this.initData()
        }
      })
    },
    downSql_() {
      const appCode = sessionStorage['app_code']
      this.$API.downSql({
        page: this.elInfo_.page
      }).then(res => {
        this.download(`spappWebChartConfig_Upgrade_${appCode}_${this.elInfo_.page}.sql`, res)
      })
    },
    download(name, data) {
      var urlObject = window.URL || window.webkitURL || window
      var downloadData = new Blob([data])
      var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a')
      save_link.href = urlObject.createObjectURL(downloadData)
      save_link.download = name
      this.fake_click(save_link)
    },
    fake_click(obj) {
      var ev = document.createEvent('MouseEvents')
      ev.initMouseEvent(
        'click', true, false, window, 0, 0, 0, 0, 0
        , false, false, false, false, 0, null
      )
      obj.dispatchEvent(ev)
    },
    dialogClose() {
      // this.$store.commit('change_viewStatus', false)
      this.dialogVisible = false
      // this.$store.commit('set_pause_status', false)
    },
    dialogOpen() {
      this.revertVersion = false
      // this.$store.commit('set_pause_status', true)
      // this.$store.commit('change_viewStatus', true)
      this.getPageInfo()
    },
    initData() {
      const app_code = sessionStorage['AppCode_'] || ''
      this.pageTitle = `配置: AppCode: <${app_code}>---page_name: <${this.elInfo_.page}>---control_name: <${this.elInfo_.position}>`
      const mockdata = this.getMockData(this.elInfo_.el)
      this.copyJsoneditorData = JSON.parse(JSON.stringify(mockdata))
      this.setJson(mockdata)
      this.initSqlEdit('monacoEdit', 'monacoEdit', this.copyJsoneditorData.sql || '')
    },
    formatterSql(monacoEdit) {
      if (!monacoEdit) {
        // 尚未初始化
        this.$message.error('尚未初始化! 请刷新页面')
        return
      }
      const contanterSql = monacoEdit.getValue()
      monacoEdit.setValue(sqlFormatter.format(contanterSql))
    },
    initSqlEdit(el, monacoEdit, initValue) {
      const that = this
      this.$refs[el].innerHTML = ''
      this[monacoEdit] = monaco.editor.create(that.$refs[el], {
        value: initValue, // sqlFormatter.format(initValue),
        language: 'sql',
        wordWrapColumn: 0,
        wrappingIndent: 'indent',
        fontSize: 14,
        autoIndent: true,
        folding: true,
        foldingStrategy: 'indentation',
        minimap: {
          enabled: false
        }
      })
      this[monacoEdit].onDidChangeModelContent(function(event) {
        initValue = that[monacoEdit].getValue()
      })
    },
    resetEdit() {
      this.openTips('是否确定撤销修改？', this.setOldJson)
    },
    setOldJson() {
      this.setJson(this.copyJsoneditorData)
    },
    submitToDb() {
      const that = this
      this.openTips('此操作将覆盖数据库中的数据, 是否继续?', that.submitData)
    },
    openTips(message, fun) {
      this.$confirm(message, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          fun()
        })
        .catch((e) => {
          this.$message({
            type: 'info',
            message: '已取消'
          })
        })
    },
    submitData() {
      if (this.complatData.length) {
        const complatData = JSON.parse(JSON.stringify(this.complatData))
        const index = complatData.findIndex(item => {
          return item.config.id === this.editor1.get().id
        })
        complatData[index].config = this.editor1.get()
        complatData[index].sourceData = this.editor2.get()
        const sql = this.monacoEdit.getValue()
        const routerParms = {
          page: this.elInfo_.page,
          position: this.elInfo_.position
        }
        const sConfig = this.editor1.get()
        const sData = complatData
        const is_mock = this.is_mock ? 1 : 0
        this.savePaggControl({ routerParms, sConfig, sData, sql, is_mock })
      } else {
        const sql = this.monacoEdit.getValue()
        const routerParms = {
          page: this.elInfo_.page,
          position: this.elInfo_.position
        }
        const sConfig = this.editor1.get()
        const sData = this.editor2.get()
        const is_mock = this.is_mock ? 1 : 0
        this.savePaggControl({ routerParms, sConfig, sData, sql, is_mock })
      }
    },
    // 保存单个文件的配置
    savePaggControl(data) {
      const { routerParms, sConfig, sData, sql, is_mock } = data
      this.$API.runSave(routerParms, sConfig, sData, sql, is_mock).then(x => {
        this.$message.success('保存成功')
      })
    },
    setJson(data) {
      const { config, sourceData } = JSON.parse(JSON.stringify(data))
      console.log(config)
      if (!this.editor1) {
        this.drow(this.ideditor1, config, 'editor1')
        this.drow(this.ideditor2, sourceData, 'editor2')
      } else {
        this.editor1.set(config)
        this.editor2.set(sourceData)
      }
    },
    showView() {
      this.lookPageLogVisible = false
      this.showEchart()
    },
    showEchart() {
      const config = this.editor1.get()
      const sourceData = this.editor2.get()
      this.commonData = {
        config,
        sourceData
      }
    },
    drow(el, json = {}, flage) {
      const container = document.getElementById(el)
      this[flage] = new this.$jsoneditor(container, this.options)
      this[flage].set(json)
    }
  }
}
</script>
<style>
.el-message-box {
  background-color: #f6f6f9 !important;
  color: #040404 !important;
}
.el-message-box__content {
  color: #040404 !important;
}
.el-message-box > .el-button {
  color: #040404 !important;
  background-color: #4a4d5d4f !important;
}
.buttonBox {
  padding-top: 30px;
  padding-bottom: 20px;
  display: flex;
}
.editItemBox1 {
  flex: 1;
  height: 400px;
}
.editItemBox2 {
  flex: 1;
  height: 400px;
}
.editItemBox3 {
  flex: 2;
  height: 400px;
}
.editeTitleItem {
  text-align: center;
  font-weight: bold;
  font-family: "宋体";
}
.pageItem {
  margin-right: 10px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.infopageItem {
  display: flex;
}
.button_hanlde {
  position: absolute;
  right: 10px;
}
</style>
