<template>
  <div>
<!--    <el-button @click="addFuncClick">新增自定义事件</el-button>-->
    <el-dialog
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :title="'新增自定义事件'"
      :visible.sync="showEditComputedField"
      append-to-body
      class="dataset-edit-computed-fields"
      width="80%"
    >
      <div class="expressionTop">
        <div>事件名称：<el-input v-model="eventName" clearable placeholder="请输入" size="mini" style="width: 300px"></el-input></div>
        <div>
          <el-radio v-model="executeTiming" :label="2">后置执行</el-radio>
          <el-radio v-model="executeTiming" :label="1">
            前置执行
            <el-tooltip style="cursor: pointer" effect="dark" placement="top">
              <div slot="content">
                注：前置事件必须返回一行一列数据，当返回值为0允许继续执行，非0时终止执行；<br/>
                例句：select count(*) from v_user where username='[username]'
              </div>
              <i class="el-icon-question" />
            </el-tooltip>
          </el-radio>
        </div>
      </div>
      <div class="panels">
        <div class="dbsours">
          <div>
            数据源选择：
            <el-select v-model="datasourceId" size="mini" style="width: 150px" @change="onDataSourceId">
              <el-option v-for="(attr, i) of dbSourceList" :key="i" :label="attr.dsDb" :value="attr.id"></el-option>
            </el-select>
          </div>
          <el-input v-model="tableSearchKey" style="margin-top: 10px" clearable placeholder="搜索数据表" size="mini" @input="onSelectTable"></el-input>
          <!--          <div class="dbsoursTable">-->
          <!--            <div v-for="(table, i) of tableListed" @click="onSearchFields(table.tableViewName)" :key="i" :title="(table.tableComments || '未命名') + ' ' + table.tableViewName" class="item">-->
          <!--              <span>{{ (table.tableComments || '未命名') + ' ' + table.tableViewName }}</span>-->
          <!--            </div>-->
          <!--          </div>-->
          <el-collapse class="dbsoursTable" v-model="activeName" accordion @change="tableListChange" v-loading="dbsoursTableLoading">
            <el-collapse-item v-for="(table, i) of tableListed" :key="i" :name="table.tableViewName">
              <template slot="title">
                <div class="tableListColumns" :title="(table.tableComments || '未命名') + ' ' + table.tableViewName" style="width: 190px">
                  {{ (table.tableComments || '未命名') + ' ' + table.tableViewName }}
                </div>
                <i class="el-icon-document-copy" @click.stop.prevent @click="onSearchFields(table.tableViewName)"></i>
              </template>
              <div v-loading="columnsLoading">
                <div class="tableListColumns tableListchild" v-for="(z, x) in tableListColumns" :key="x">
                  {{ z.columnName }}
                  <i class="el-icon-document-copy" @click="onSearchFields(z.columnName)"></i>
                </div>
              </div>
            </el-collapse-item>
          </el-collapse>
        </div>
        <div class="main">
          <div class="label label-title">
            <aceEditor ref="editor" v-model="nowComputedField.columnFormula" height="529" lang="javascript" snippets wrap />
          </div>
        </div>
        <div class="panel" style="margin-right: 10px">
          <div class="label">点击引用字段</div>
          <div class="search-box">
            <el-input v-model="computedSearchKey" clearable placeholder="输入以搜索" size="mini"></el-input>
          </div>
          <div class="fields" style="height: 462px">
            <div class="tab">维度</div>
            <template v-for="field of tobeChooseWeiduSearched">
              <div v-if="nowComputedField.columnTitle !== field.columnTitle" :key="field.columnTitle" :title="field.columnName" class="weidu" @click="onComputedAddField(field)">
                {{ field.columnTitle + '【' + field.columnName + '】' }}
              </div>
            </template>
            <div class="tab">指标</div>
            <template v-for="field of tobeChooseZhibiaoSearched">
              <div v-if="nowComputedField.columnTitle !== field.columnTitle" :key="field.columnTitle" :title="field.columnName" class="zhibiao" @click="onComputedAddField(field)">
                {{ field.columnTitle + '【' + field.columnName + '】' }}
              </div>
            </template>
          </div>
        </div>
        <div class="panel">
          <el-popover ref="paramSelector" placement="bottom-start" trigger="click">
            <el-cascader-panel v-model="nowParam" :options="paramList" :props="{ expandTrigger: 'click', emitPath: false, value: 'paramKey' }" @change="onSetParam"></el-cascader-panel>
            <span slot="reference" class="label" style="color: #409eff; cursor: pointer"> <i class="el-icon-plus"></i> 添加全局参数 </span>
          </el-popover>
          <div class="label">点击引用函数</div>
          <div class="search-box">
            <el-select v-model="funcAttr" size="mini" style="width: 110px">
              <el-option v-for="(attr, i) of funcAttrList" :key="i" :label="attr.message" :value="attr.value"></el-option>
            </el-select>
            <el-input v-model="funcKey" clearable placeholder="搜索" size="mini" style="width: 90px" @input="onSearchFunc"></el-input>
          </div>
          <div class="functions">
            <div v-for="(func, i) of functionListSearched" :title="func.description" class="func" @click="onComputedAddFunc(func.method)">
              {{ func.name }}
            </div>
          </div>
        </div>
      </div>
      <div class="btns">
        <el-button size="mini" @click="showEditComputedField = false"> 取消</el-button>
        <el-button size="mini" type="primary" @click="onEditComputedFieldConfirm"> 确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { cubeDetail, jsfuncAttrList } from '@/api/newbi/dataset'
import { getDatasourceDetail, listColumnsByDatasource } from '@/components/Dataset-filter/report'
import aceEditor from '@/components/AceEditor'
import { cubeFieldList, listViewsByDataSource } from '@/api/workFlow/FlowEngine'
import { funcList } from '@/api/newbi/func'
import { reportdatasourcePage } from '@/api/newbi/report'
import { addCustomEvent } from '@/api/onlineDev/visualDev'
import { categoryList, paramList } from '@/api/newbi/globalParams'
export default {
  props: ['dbLinkId', 'modelId', 'dbSourceId'],
  components: { aceEditor },
  name: 'customEventExpression',
  data() {
    return {
      showEditComputedField: false,
      datasource: null,
      functionList: [], // 用于创建计算字段的函数列表
      functionListSearched: [],
      funcAttr: -1,
      funcAttrList: [],
      funcKey: '',
      computedSearchKey: '',
      tobeChooseWeidu: [], // 计算字段编辑框里维度字段
      tobeChooseZhibiao: [], // 计算字段编辑框里指标字段
      nowComputedField: {
        columnFormula: ''
      }, // 当前计算字段
      dbSourceList: [],
      datasourceId: '',
      tableList: [],
      tableListed: [],
      tableSearchKey: '',
      eventName: '',
      executeTiming: '',
      eventType: 0,
      eventStatus: 0,
      id: '',
      paramList: [],
      nowParam: [],
      activeName: '1',
      tableListColumns: [],
      columnsLoading: false,
      dbsoursTableLoading: false
    }
  },
  created() {
    this.fillback(this.dbLinkId)
    this.getInitData()
    this.datasourceId = this.dbSourceId
    this.onDataSourceId(this.dbSourceId)
    this.getGlobalData()
  },
  computed: {
    // 计算字段编辑框里维度字段
    tobeChooseWeiduSearched() {
      let key = this.computedSearchKey
      return this.tobeChooseWeidu.filter((i) => {
        return i.columnName.toUpperCase().includes(key) || i.columnTitle.includes(key)
      })
    },
    // 计算字段编辑框里指标字段
    tobeChooseZhibiaoSearched() {
      let key = this.computedSearchKey
      return this.tobeChooseZhibiao.filter((i) => {
        return i.columnName.toUpperCase().includes(key) || i.columnTitle.includes(key)
      })
    }
  },
  methods: {
    // 获取系统变量
    getGlobalData() {
      categoryList({ size: 10000, current: 1 }).then((res) => {
        let list = res.data.data.records
        let parents = list.filter((i) => !i.parentId)
        let categoryList = []
        list.forEach((i) => {
          i.children = []
          if (i.parentId) {
            let parent = parents.find((j) => j.id == i.parentId)
            parent.hasChild = true
            i.label = parent.typeName + ' / ' + i.typeName
            categoryList.push(i)
          } else {
            i.label = i.typeName
          }
        })
        categoryList = categoryList.concat(parents.filter((i) => !i.hasChild))
        paramList({ size: 10000, current: 1 }).then((res) => {
          let params = res.data.data.records
          params.forEach((i) => {
            i.label = i.paramName
            let parent = categoryList.find((j) => j.id == i.typeId)
            parent.children.push(i)
          })
          this.paramList = categoryList
        })
      })
    },
    addFuncClick(row) {
      this.showEditComputedField = true
      this.datasourceId = this.datasourceId && Number(this.datasourceId)
      this.$nextTick(() => {
        if (row && row.id) {
          this.eventName = row.eventName
          this.executeTiming = row.executeTiming
          this.eventType = row.eventType
          this.eventStatus = row.eventStatus
          this.datasourceId = row.eventDatasourceId
          this.id = row.id
          this.onDataSourceId(row.eventDatasourceId)
          this.$refs.editor.editor.setValue(row.eventSql)
        } else {
          this.eventName = ''
          this.executeTiming = 2
          this.eventType = 0
          this.eventStatus = 0
          this.id = ''
          this.datasourceId = this.dbSourceId
          this.onDataSourceId(this.datasourceId)
          this.$refs.editor.editor.setValue('')
        }
      })
      this.getInitData()
    },
    // 获取初始化数据,
    getInitData() {
      //获取数据集
      cubeFieldList({ cubeDataId: this.dbLinkId }).then((res) => {
        let tableFieldsWeidu = res.data.data.filter((i) => i.dimensionType === 'WEIDU').sort((a, b) => a.sortNum - b.sortNum)
        let tableFieldsZhibiao = res.data.data.filter((i) => i.dimensionType === 'ZHIBIAO').sort((a, b) => a.sortNum - b.sortNum)
        this.tobeChooseWeidu = tableFieldsWeidu.filter((i) => i.columnAttr == 'NORMAL')
        this.tobeChooseZhibiao = tableFieldsZhibiao.filter((i) => i.columnAttr == 'NORMAL')
      })
      jsfuncAttrList().then((res) => {
        let list = res.data.data
        list.unshift({ value: -1, name: '', message: '全部类型' })
        this.funcAttrList = list
      })
    },
    async fillback(id) {
      let cubeRes = await cubeDetail({ cubeDataId: id })
      if (!cubeRes.data.code === 200) return
      let { datasourceId } = cubeRes.data.data
      // 获取数据源详情
      getDatasourceDetail({ id: datasourceId }).then((res) => {
        this.datasource = res.data.data
        this.getFuncList()
      })
      reportdatasourcePage({ current: 1, size: 1000 }).then((res) => {
        this.dbSourceList = res.data.data.records
      })
    },
    // 获取当前数据源类型下计算函数
    getFuncList() {
      funcList({ dsType: 'mysql' }).then((res) => {
        this.functionList = res.data.data
        this.functionListSearched = [...this.functionList]
        this.funcAttr = -1
      })
    },
    onSearchFunc() {
      let { name } = this.funcAttrList.find((i) => i.value == this.funcAttr)
      let funcKey = this.funcKey.toLowerCase()
      let list = []
      if (this.funcAttr == -1) {
        list = [...this.functionList]
      } else {
        list = this.functionList.filter((i) => i.funcAttr == name)
      }
      this.functionListSearched = list.filter((i) => {
        let name = i.name.toLowerCase()
        let description = i.description.toLowerCase()
        return name.includes(funcKey) || description.includes(funcKey)
      })
    },
    onDataSourceId(val) {
      this.tableSearchKey = ''
      this.dbsoursTableLoading = true
      listViewsByDataSource({ datasourceId: val, current: 1, size: 10000 }).then((res) => {
        this.tableList = res.data.data.records
        this.tableListed = res.data.data.records
        this.dbsoursTableLoading = false
      })
    },
    onSelectTable(val) {
      this.tableListed = this.tableList.filter((i) => (i.tableComments && i.tableComments.includes(val)) || i.tableViewName.includes(val))
    },
    // 计算字段拼入物理字段
    onComputedAddField(field) {
      this.$refs.editor.editor.insert(`[${field.columnName}]`)
    },
    // 计算字段拼入函数
    onComputedAddFunc(method) {
      // const beautify_sql = require('js-beautify')
      //
      // let content = beautify_sql(method, {
      //   indent_size: 2,
      //   html: {
      //     end_with_newline: true,
      //     js: {
      //       indent_size: 2
      //     },
      //     css: {
      //       indent_size: 2
      //     }
      //   },
      //   css: {
      //     indent_size: 1
      //   },
      //   js: {
      //     'preserve-newlines': true
      //   }
      // })
      this.$refs.editor.editor.insert(method)
    },
    onSetParam(val) {
      this.$refs.editor.editor.insert(`\${${val}}`)
    },
    onSearchFields(table) {
      this.$refs.editor.editor.insert(table)
    },
    onEditComputedFieldConfirm() {
      let { columnFormula } = this.nowComputedField
      if (!columnFormula) {
        return this.$message({ message: '请补充完整', type: 'warning' })
      }
      let params = {
        id: this.id,
        eventName: this.eventName,
        executeTiming: this.executeTiming,
        eventDatasourceId: this.datasourceId,
        eventType: this.eventType,
        eventStatus: this.eventStatus,
        eventSql: columnFormula
      }
      addCustomEvent(this.modelId, params).then((res) => {
        this.$message({
          message: res.data.msg,
          type: 'success',
          duration: 1500,
          onClose: () => {
            this.$emit('onChangeExp')
            this.showEditComputedField = false
          }
        })
      })
    },
    tableListChange(val) {
      if (val) {
        this.columnsLoading = true
        listColumnsByDatasource({ tableViewName: val, datasourceId: this.datasourceId }).then((res) => {
          this.tableListColumns = res.data.data
          this.columnsLoading = false
        })
      }
    }
  }
}
</script>

<style scoped lang="scss">
.expressionTop {
  padding: 0px 10px 10px 0;
  display: flex;
  align-items: center;
  div + div {
    margin-left: 10px;
  }
}
.dbsoursTable {
  width: 238px;
  height: 463px;
  overflow-y: auto;
  padding-top: 10px;
  cursor: pointer;
  font-size: 12px;
  .tableListColumns {
    padding-left: 10px;
    line-height: 27px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    //使i图标居中靠右
    i {
      float: right;
      margin-top: 7px;
      margin-right: 8px;
    }
  }
  .tableListchild {
    background-color: #efefef;
    padding-left: 20px;
    margin-bottom: 5px;
  }
}
.panels {
  display: flex;
  .main {
    flex: 1;
    margin-right: 10px;
    .label-title {
      width: 100%;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
  }
  .panel {
    flex: 0 0 200px;
    width: 200px;
    font-size: 12px;
    .tab {
      line-height: 30px;
    }
    .functions,
    .fields {
      height: 430px;
      overflow-y: auto;
      padding: 0 10px 10px;
      background-color: #fff;
    }
    .search-box {
      height: 35px;
    }
    .weidu {
      line-height: 24px;
      box-sizing: border-box;
      border: 1px solid #1d54d5;
      background-color: #e4eafa;
      padding: 0 10px;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      margin: 3px 0;
      cursor: pointer;
    }
    .zhibiao {
      line-height: 24px;
      box-sizing: border-box;
      border: 1px solid #00b375;
      background-color: #d4f2e8;
      padding: 0 10px;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      margin: 3px 0;
      cursor: pointer;
    }
    .func {
      line-height: 24px;
      box-sizing: border-box;
      border: 1px solid #ccc;
      padding: 0 10px;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      margin: 3px 0;
      cursor: pointer;
    }
  }
}
.btns {
  text-align: right;
  margin-top: 10px;
  .el-button {
    width: 100px;
  }
}
</style>
