<template>
  <div class="newbi-view-tables">
    <el-drawer :close-on-press-escape="false" :visible.sync="show" custom-class="view-tables-dialog" direction="btt" title="视图编辑">
      <div class="edit-wrapper">
        <div class="table-wrapper my-shadow">
          <div class="tables">
            <div class="title1" style="display: flex">
              <div>可用表</div>
              <el-input v-model="tableKey" clearable placeholder="搜索表" size="mini" style="flex: 1; margin: 0 10px"></el-input>
            </div>
            <div class="wrapper">
              <div v-for="(item, i) of tableSearched" :key="i" :class="{ active: nowTable.tableViewName == item.tableViewName }" :title="item.tableViewName" class="table">
                <div class="name-box" @click="getFields(item)">
                  <div class="name one-line">{{ item.tableViewName }}</div>
                  <div class="comment one-line">{{ item.tableComments }}</div>
                </div>
                <i class="iconfont icon-fuzhi" @click="insertStr(item.tableViewName)"></i>
                <i class="el-icon-view" style="color: #409eff; margin-left: 5px" @click="onTablePreview(item)"></i>
              </div>
            </div>
          </div>
          <div class="fields">
            <div class="title1" style="display: flex">
              <div>当前字段</div>
              <el-input v-model="fieldKey" clearable placeholder="搜索字段" size="mini" style="flex: 1; margin: 0 10px"></el-input>
            </div>
            <div class="wrapper">
              <div v-for="(item, i) of fieldSearched" :key="i" :title="item.columnName" class="field">
                <div class="name-box">
                  <div class="name one-line">{{ item.columnName }}</div>
                  <div class="comment one-line">{{ item.columnComment }}</div>
                </div>
                <i class="iconfont icon-fuzhi" @click="insertStr(item.columnName)"></i>
              </div>
            </div>
          </div>
        </div>
        <el-form class="my-shadow" label-width="60px" size="mini">
          <!--          <el-form-item label="AI做sql">-->
          <!--            <div class="flex-center">-->
          <!--              <el-input v-model="gptKeyword" @keydown.enter="gptSubmit"></el-input>-->
          <!--              <el-button :loading="gptLoading" class="ml-30" @click="gptSubmit">生成sql</el-button>-->
          <!--            </div>-->
          <!--          </el-form-item>-->
          <el-form-item label="名称">
            <el-input v-model="form.sqlName"></el-input>
          </el-form-item>
          <el-form-item label="视图名">
            <el-input v-model="form.viewName"></el-input>
          </el-form-item>
          <el-form-item label="SQL">
            <b-ace-editor ref="editor" v-model="form.sqlStatement" height="285" lang="sql" snippets style="font-size: 16px" wrap></b-ace-editor>
          </el-form-item>
          <div class="btns">
            <el-button size="small" @click="show = false">取消</el-button>
            <el-button size="small" type="primary" @click="onSave">确定</el-button>
            <el-button plain size="small" type="success" @click="onViewPreview">数据预览</el-button>
          </div>
        </el-form>
      </div>
      <div class="preview-wrapper my-shadow">
        <el-tabs v-model="previewIndex">
          <el-tab-pane label="数据预览" name="preview">
            <el-table
              v-loading="tableLoading"
              :data="tableData"
              border
              element-loading-background="rgba(0, 0, 0, 0.8)"
              element-loading-spinner="el-icon-loading"
              element-loading-text="拼命加载中"
              height="calc(100% - 15px)"
              size="mini"
            >
              <el-table-column v-for="(col, i) of tableColumns" :key="i" :label="col.label" :prop="col.prop"></el-table-column>
            </el-table>
          </el-tab-pane>
          <el-tab-pane label="报错查看" name="error">{{ errorMsg }}</el-tab-pane>
        </el-tabs>
      </div>
    </el-drawer>
  </div>
</template>
<script>
import { viewList, viewSave, tablePreview, tableFieldList, viewPreview } from '@/api/newbi/dataset'
import moment from 'moment'
import ace from 'brace'
import { Base64 } from 'js-base64'
export default {
  props: ['tables', 'datasourceId'],
  data() {
    return {
      nowTable: { fields: [] },
      show: false,
      form: {},
      tableKey: '',
      fieldKey: '',
      tableData: [],
      tableColumns: [],
      tableLoading: false,
      previewIndex: 'preview',
      errorMsg: '',
      gptKeyword: '',
      gptLoading: false
    }
  },
  computed: {
    tableSearched() {
      let { tableKey } = this
      return this.tables.filter((i) => {
        if (i.tableViewName.includes(tableKey) || i.tableViewName.toLowerCase().includes(tableKey)) return true
        return i.tableComments && i.tableComments.includes(tableKey)
      })
    },
    fieldSearched() {
      let { fieldKey } = this
      return this.nowTable.fields.filter((i) => {
        if (i.columnName && i.columnName.toLowerCase().includes(fieldKey)) return true
        return i.columnTitle && i.columnTitle.includes(fieldKey)
      })
    }
  },
  created() {},
  mounted() {
    const that = this
    const completer = {
      getCompletions: function (editors, session, pos, prefix, callback) {
        that.setCompleteData(editors, session, pos, prefix, callback)
      }
    }
    const lnTools = ace.acequire('ace/ext/language_tools')
    lnTools.addCompleter(completer)
  },
  methods: {
    onViewPreview() {
      if (!this.form.sqlStatement) {
        return this.$message({ type: 'warning', message: '请编辑sql语句' })
      }
      this.tableLoading = true
      this.tableData = []
      this.tableColumns = []
      viewPreview(this.datasourceId, Base64.encode(this.form.sqlStatement))
        .then((res) => {
          this.previewIndex = 'preview'
          this.errorMsg = ''
          let data = res.data.data
          if (data.length) {
            this.tableColumns = Object.keys(data[0]).map((i) => ({ label: i, prop: i }))
            this.tableData = data
          }
        })
        .catch((res) => {
          this.previewIndex = 'error'
          this.errorMsg = res.data.data
        })
        .finally(() => (this.tableLoading = false))
    },
    async onTablePreview(table) {
      if (!table.fields.length) {
        await this.getFields(table)
      }
      this.tableLoading = true
      this.tableData = []
      this.tableColumns = []
      tablePreview(this.datasourceId, table.tableViewName)
        .then((res) => {
          this.previewIndex = 'preview'
          this.errorMsg = ''
          this.tableData = res.data.data
          this.tableColumns = table.fields.map((i) => ({ label: i.columnName, prop: i.columnName }))
        })
        .finally(() => (this.tableLoading = false))
    },
    insertStr(str) {
      this.$refs.editor.editor.insert(str)
      this.$refs.editor.editor.focus()
    },
    onEdit(view) {
      this.form = { ...view }
      delete this.form.fields
      this.show = true
    },
    onSave() {
      if (!this.form.sqlName) {
        return this.$message({ type: 'warning', message: '请输入sql名称' })
      }
      if (!this.form.viewName) {
        return this.$message({ type: 'warning', message: '请输入视图名称' })
      }
      if (!this.form.sqlStatement) {
        return this.$message({ type: 'warning', message: '请编辑sql语句' })
      }
      viewSave(Base64.encode(JSON.stringify(this.form))).then((res) => {
        this.$message({ type: 'success', message: '已保存' })
        this.show = false
        this.$emit('getViews')
      })
    },
    async getFields(table) {
      this.nowTable = table
      let data = { dsId: this.datasourceId, tableName: table.tableViewName }
      let res = await tableFieldList(data)
      table.fields = res.data.data
    },
    setCompleteData(editor, session, pos, prefix, callback) {
      let data = this.tables.map((i) => ({
        meta: '数据表',
        caption: i.tableViewName,
        value: i.tableViewName,
        score: 1
      }))
      data = data.concat(
        this.nowTable.fields.map((i) => ({
          meta: '字段' + '：' + i.columnTitle,
          caption: i.columnName,
          value: i.columnName,
          score: 2
        }))
      )
      callback(null, prefix.length === 0 ? [] : data)
    },
    onAdd() {
      this.form = {
        datasourceId: this.datasourceId,
        sqlName: '',
        sqlStatement: '',
        viewName: 'V_SQL_' + moment().format('YYYYMMDDHHmm')
      }
      this.show = true
    },
    async gptSubmit() {
      this.gptLoading = true
      //this.tableData转字符串
      let tableData = JSON.stringify(this.tableData[0])
      let str = ''
      Object.values(this.nowTable.fields).map((item, index) => {
        str += `字段：${item.columnName}名称：${item.columnComment}类型：${item.viewDataType},`
      })
      let prompt = `使用${this.nowTable.tableViewName}表,${str}query sql${this.gptKeyword}的sql语句,谢谢`
      const data = await chat(prompt, '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')
      //去掉\n
      data.choices[0].text = data.choices[0].text.replace(/\n/g, '')
      //去掉尾部的分号
      data.choices[0].text = data.choices[0].text.replace(/;*$/g, '')
      this.form.sqlStatement = data.choices[0].text
      this.gptLoading = false
    }
  }
}
</script>
<style lang="scss">
.newbi-view-tables {
}
.view-tables-dialog {
  height: calc(100% - 50px) !important;
  .el-drawer__header {
    padding: 10px 20px 0;
    margin-bottom: 10px;
    font-size: 16px;
    font-weight: 600;
    color: #333;
  }
  .el-drawer__body {
    background-color: #eee;
    padding-top: 10px;
  }
  .edit-wrapper {
    background-color: #fff;
    display: flex;
    height: 500px;
    overflow-y: hidden;
    margin: 0 10px 10px;
  }
  .table-wrapper {
    flex: 0 0 450px;
    width: 450px;
    padding: 10px;
    margin-right: 10px;
    display: flex;
    .tables {
      height: 100%;
      width: 220px;
      margin-right: 10px;
    }
    .fields {
      height: 100%;
      width: 200px;
    }
    .tables,
    .fields {
      .title1 {
        font-weight: 600;
        color: #777;
        line-height: 40px;
      }
      .wrapper {
        overflow-y: auto;
        height: calc(100% - 40px);
      }
      .table,
      .field {
        display: flex;
        align-items: center;
        margin: 5px 0;
        border: 1px solid #ccc;
        padding: 0 5px;
        cursor: pointer;
        .name-box {
          width: 170px;
          flex: 0 0 170px;
        }
        .comment {
          font-size: 12px;
          color: #777;
        }
        .iconfont {
          font-size: 14px;
        }
        &.active {
          color: #409eff;
          .comment {
            color: #409eff;
          }
        }
      }
    }
  }
  .el-form {
    padding: 10px;
    flex: 1;
    .btns {
      display: flex;
      margin-top: 20px;
      .el-button {
        width: 80px;
        margin-left: 60px;
      }
    }
  }
  .preview-wrapper {
    background-color: #fff;
    height: calc(100% - 520px);
    box-sizing: border-box;
    padding: 0 10px;
    margin: 0 10px 10px;
    .el-tabs {
      height: 100%;
      .el-tabs__content {
        height: calc(100% - 50px);
        .el-tab-pane {
          height: 100%;
        }
      }
    }
  }
}
</style>
