<template>
  <div class="dataset-filter-item" v-if="nowFilter">
    <el-form size="mini" label-width="60px">
      <el-form-item label="名称">
        <el-input v-model="nowFilter.cubePermName"></el-input>
      </el-form-item>
      <el-form-item label="权限组">
        <auth-group-selector v-model="nowFilter.dataPermId"></auth-group-selector>
      </el-form-item>
    </el-form>
    <el-tabs v-model="activeType">
      <el-tab-pane label="行过滤" name="row">
        <el-dropdown @command="onAddFilter" trigger="click">
          <el-button type="success" size="mini" plain icon="el-icon-plus" style="margin: 0 10px">添加</el-button>
          <el-dropdown-menu slot="dropdown" class="newbi-dataset-filter-drop">
            <el-input v-model="searchKey" placeholder="筛选" clearable></el-input>
            <div class="fields">
              <el-dropdown-item v-for="(field, i) of searchedFields" :key="i" :command="field" :class="[field.dimensionType]">
                {{ field.columnTitle }}
              </el-dropdown-item>
            </div>
          </el-dropdown-menu>
        </el-dropdown>
        <dataset-filter-node :node="nowFilter.filterRelation.where" :level="1"></dataset-filter-node>
      </el-tab-pane>
      <el-tab-pane label="列过滤" name="column">
        <el-dropdown @command="onAddColumn" trigger="click">
          <el-button type="success" size="mini" plain icon="el-icon-plus" style="margin: 0 10px">添加</el-button>
          <el-dropdown-menu slot="dropdown" class="newbi-dataset-filter-drop">
            <el-input v-model="searchKey" placeholder="筛选" clearable></el-input>
            <div class="fields">
              <el-dropdown-item v-for="(field, i) of availableFields" :key="i" :command="field" :class="[field.dimensionType, field.select ? 'select' : '']">
                {{ field.columnTitle }}
              </el-dropdown-item>
            </div>
          </el-dropdown-menu>
        </el-dropdown>
        <div v-for="(column, i) of nowFilter.excludeColumn" :key="i" :class="['column', column.dimensionType]">
          <span class="one-line">{{ column.columnTitle }}</span>
          <i class="el-icon-close close" @click="nowFilter.excludeColumn.splice(i, 1)"></i>
        </div>
      </el-tab-pane>
    </el-tabs>
    <div class="btns">
      <el-button size="small" :type="nowFilter.id ? 'primary' : 'success'" @click="onSave" plain>
        {{ nowFilter.id ? '更新' : '添加' }}
      </el-button>
      <el-button v-show="nowFilter.id && isAdmin" size="small" @click="onDel" plain type="danger">删除</el-button>
    </div>
    <!-- 过滤器编辑框 -->
    <el-dialog append-to-body :visible.sync="showCondition" title="编辑过滤器" custom-class="bigdata-filter" width="560px">
      <div v-if="nowCondition">
        <el-form size="mini" label-width="80px">
          <el-form-item label="当前字段">
            <div :class="['now-filter', nowCondition.column.dimensionType]">
              <div class="name">{{ nowCondition.column.columnTitle + ' ' + nowCondition.column.columnName }}</div>
              <div style="color: #999">{{ datatypeMap[nowCondition.column.viewDataType] }}</div>
            </div>
          </el-form-item>
          <el-form-item label="连接方式">
            <el-radio-group v-model="nowCondition.connectType">
              <el-radio label="and">且</el-radio>
              <el-radio label="or">或</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="枚举来源" v-show="countEnumShow()">
            <el-radio-group v-model="nowCondition.enumSource" @change="nowCondition.enumId == ''">
              <el-radio label="1">原始数据聚合</el-radio>
              <el-radio label="2">api</el-radio>
              <el-radio label="3">自定义字典</el-radio>
            </el-radio-group>
            <el-button size="mini" type="primary" @click="onGetEnumData" style="margin-left: 20px"> 获取 </el-button>
          </el-form-item>
          <el-form-item label="选择api" v-if="countEnumShow() && nowCondition.enumSource === '2'">
            <el-cascader
              v-model="nowCondition.enumId"
              :options="apiList"
              :props="{ expandTrigger: 'hover', emitPath: false }"
              filterable
              popper-class="bigdata-data-selector"
              :show-all-levels="false"
            ></el-cascader>
          </el-form-item>
          <el-form-item label="选择字典" v-if="countEnumShow() && nowCondition.enumSource === '3'">
            <el-select v-model="nowCondition.enumId">
              <el-option v-for="(item, i) of dictList" :key="i" :value="item.id" :label="item.keyCode"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="过滤条件">
            <div class="filter-item" v-for="(condition, i) of nowCondition.conditions" :key="i">
              <el-select size="mini" v-model="condition.function" style="width: 100px; margin-right: 10px" placeholder="选择条件" @change="onFunctionChange">
                <el-option v-for="func of functions[nowCondition.column.viewDataType]" :key="func.function" :value="func.function" :label="func.label"></el-option>
              </el-select>
              <!-- 日期类型 -->
              <template v-if="nowCondition.column.viewDataType === 'DATETIME'">
                <el-select v-model="condition.timeType" style="width: 95px; margin-right: 5px" @change="onTimeTypeChange(condition)">
                  <el-option label="绝对时间" value="absolute"></el-option>
                  <el-option label="相对时间" value="relative"></el-option>
                </el-select>
                <template v-if="condition.timeType === 'relative'">
                  <el-input style="width: 120px; margin-right: 5px" v-model="condition.values[0]">
                    <template slot="append"> {{ timeTypeMap[nowCondition.column.timeDataFormat] }}</template>
                  </el-input>
                  <el-select v-model="condition.countType" style="width: 60px">
                    <el-option label="前" value="left"></el-option>
                    <el-option label="后" value="right"></el-option>
                  </el-select>
                </template>
                <template v-else>
                  <template v-if="nowCondition.dateType === 'time'">
                    <el-date-picker style="width: 200px" v-model="condition.values[0]" type="datetime" placeholder="选择日期时间" :value-format="nowCondition.dateFormat"></el-date-picker>
                    <el-date-picker
                      v-if="condition.function === 'between'"
                      style="width: 200px"
                      v-model="condition.values[1]"
                      type="datetime"
                      placeholder="选择日期时间"
                      :value-format="nowCondition.dateFormat"
                    ></el-date-picker>
                  </template>
                  <template v-else-if="['year', 'month', 'date'].includes(nowCondition.dateType)">
                    <el-date-picker style="width: 200px" v-model="condition.values[0]" :type="nowCondition.dateType" placeholder="选择日期" :value-format="nowCondition.dateFormat"></el-date-picker>
                    <el-date-picker
                      v-if="condition.function === 'between'"
                      style="width: 200px"
                      v-model="condition.values[1]"
                      :type="nowCondition.dateType"
                      placeholder="选择日期"
                      :value-format="nowCondition.dateFormat"
                    ></el-date-picker>
                  </template>
                  <template v-else>
                    <el-time-select style="width: 200px" v-model="condition.values[0]" placeholder="选择时间" :value-format="nowCondition.dateFormat"></el-time-select>
                    <el-time-select
                      v-if="condition.function === 'between'"
                      style="width: 200px"
                      v-model="condition.values[1]"
                      placeholder="选择时间"
                      :value-format="nowCondition.dateFormat"
                    ></el-time-select>
                  </template>
                </template>
              </template>
              <template v-else>
                <template v-if="['in', 'notIn'].includes(condition.function)">
                  <el-cascader
                    v-model="condition.values"
                    :options="nowCondition.options"
                    :props="{ expandTrigger: 'hover', emitPath: false, multiple: true, label: 'VALUE', value: 'KEY' }"
                    filterable
                    :show-all-levels="false"
                    collapse-tags
                    clearable
                  ></el-cascader>
                  <el-button size="mini" @click="onEnumSelectAll(nowCondition)" type="primary"> 全选</el-button>
                </template>
                <template v-else-if="['indexIn'].includes(condition.function)">
                  <el-input style="width: 200px" size="mini" v-model="condition.values[0]" placeholder="默认使用第几条"> </el-input>
                </template>
                <span v-else-if="['isnull', 'notnull'].includes(condition.function)"></span>
                <el-input v-else style="width: 200px" size="mini" v-model="condition.values[0]" placeholder="输入值"> </el-input>
              </template>
              <i class="el-icon-delete" v-show="nowCondition.conditions.length > 1" @click="onConditionDel(i)"></i>
            </div>
            <el-button size="mini" type="success" plain @click="onConditionAdd" v-show="canAddCondition"> 添加条件 </el-button>
          </el-form-item>
          <div class="btns" style="display: flex; justify-content: end; margin-top: 30px">
            <el-button type="primary" size="small" @click="showCondition = false" style="width: 100px"> 确定</el-button>
            <el-button size="small" @click="showCondition = false" style="width: 100px"> 取消</el-button>
          </div>
        </el-form>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import authGroupSelector from '../auth-group-selector'
import datasetFilterNode from '@/views/dataset/comps/datasetFilterNode'
import util from '../wey'
import { dateTypeMap, fieldDateFormats, functions, timeTypeMap, columnKeys } from '@/utils/dict'
import { cubePremSave, cubePremSDel } from '@/api/newbi/dataset'
import { Base64 } from 'js-base64'
import { getEnumData, onEnumSelectAll } from '@/utils/util'
import { dataapicategoryList, dataapiList } from '@/api/newbi/report'
import { dictList } from '@/api/newbi/dict'

export default {
  components: { authGroupSelector, datasetFilterNode },
  props: ['nowFilter', 'fields', 'isAdmin'],
  data() {
    return {
      activeType: 'row',
      dateTypeMap,
      fieldDateFormats,
      columnKeys,
      timeTypeMap,
      functions,
      searchKey: '',
      showCondition: false,
      nowCondition: null,
      datatypeMap: { NUMBER: '数字', STRING: '字符串', DATETIME: '时间' },
      apiList: [],
      dictList: [],
      draggingNode: null,
      draggingIndex: 0
    }
  },
  computed: {
    searchedFields() {
      return this.fields.filter((i) => i.columnTitle.includes(this.searchKey))
    },
    availableFields() {
      return this.searchedFields.map((i) => ({ ...i, select: !!this.nowFilter.excludeColumn.find((j) => j.id == i.id) }))
    },
    // 能否添加过滤条件
    canAddCondition() {
      if (!this.nowCondition) return false
      let func = this.nowCondition.conditions[0].function
      return !(func === 'in' || func === 'notIn' || func === 'indexIn')
    }
  },
  provide() {
    return {
      editFilterByUniqId: this.editFilterByUniqId,
      onNodeDrag: this.onNodeDrag,
      onNodeDrop: this.onNodeDrop,
      onDelFilter: this.onDelFilter
    }
  },
  created() {
    this.getInitData()
  },
  methods: {
    // 清除空节点
    clearNullNode(parent, item, index) {
      item.filters.forEach((node, i) => {
        this.clearNullNode(item, node, i)
      })
      if (!item.filters.length && !item.conditions.length) {
        parent.filters.splice(index, 1)
      }
    },
    // 过滤器添加条件
    onConditionAdd() {
      this.nowCondition.conditions.push({
        function: 'eq',
        values: ['', ''],
        timeType: 'absolute',
        countType: 'left'
      })
    },
    // 过滤器删除条件
    onConditionDel(i) {
      this.nowCondition.conditions.splice(i, 1)
    },
    // 条件时间类型变化时
    onTimeTypeChange(condition) {
      if (condition.timeType === 'relative') {
        condition.values = [1]
      } else {
        condition.values = ['']
      }
    },
    onEnumSelectAll(filter) {
      onEnumSelectAll(filter)
    },
    // 计算函数变化时
    async onFunctionChange(func) {
      if (['in', 'notIn', 'indexIn'].includes(func)) {
        this.nowCondition.conditions = [
          {
            function: func,
            values: [],
            timeType: 'absolute',
            countType: 'left'
          }
        ]
      }
    },
    // 获取初始化工具数据
    getInitData() {
      // 获取api列表
      dataapicategoryList().then((res) => {
        let category = res.data.data
        dataapiList({ apiFormal: 1, apiTypes: '1,2' }).then((res) => {
          let list = res.data.data
          this.apiList = category
            .map((i) => {
              return {
                label: i.categoryName,
                value: i.id,
                children: list
                  .filter((j) => j.categoryId === i.id)
                  .map((k) => ({
                    label: k.apiName,
                    value: k.id,
                    key: k.apiKey
                  }))
              }
            })
            .filter((i) => i.children.length)
        })
      })
      dictList({ current: 1, size: 10000 }).then((res) => {
        this.dictList = res.data.data.records
      })
    },
    // 获取枚举值列表
    onGetEnumData() {
      if (!this.nowCondition.options.length) {
        getEnumData(this.nowCondition, this.nowFilter.cubeDataId, '', '', true)
      }
    },
    // 判断是否展示枚举选项
    countEnumShow() {
      let func = this.nowCondition.conditions[0].function
      return func === 'in' || func === 'notIn' || func === 'indexIn'
    },
    // 编辑某个条件
    editFilterByUniqId({ uniqId }) {
      this.nowCondition = this.nowFilter.filterList.find((i) => i.uniqId == uniqId)
      this.showCondition = true
      let func = this.nowCondition.conditions[0].function
      if (func === 'in' || func === 'notIn' || func === 'indexIn') {
        this.onGetEnumData()
      }
    },
    // 开始拖拽某节点
    onNodeDrag(node, index) {
      this.draggingNode = node
      this.draggingIndex = index
    },
    // 节点拖拽完成时
    onNodeDrop(node) {
      let item = this.draggingNode.conditions.splice(this.draggingIndex, 1)[0]
      node.conditions.push(item)
      let rootNode = this.nowFilter.filterRelation.where
      rootNode.filters.forEach((node, index) => {
        this.clearNullNode(rootNode, node, index)
      })
    },
    // 删除条件时
    onDelFilter(item, node, i) {
      node.conditions.splice(i, 1)
      let index = this.nowFilter.filterList.findIndex((i) => i.uniqId == item.uniqId)
      this.nowFilter.filterList.splice(index, 1)
      let rootNode = this.nowFilter.filterRelation.where
      rootNode.filters.forEach((node, index) => {
        this.clearNullNode(rootNode, node, index)
      })
    },
    onDel() {
      this.$confirm('确定删除?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
        .then(() => {
          cubePremSDel({ cubePermId: this.nowFilter.id }).then((res) => {
            this.$message({ type: 'success', message: '已删除' })
            this.$emit('done')
          })
        })
        .catch(() => {})
    },
    onSave() {
      let { cubeDataId, dataPermId, cubePermName, filterList, filterRelation, id, excludeColumn } = this.nowFilter
      filterList.forEach((item) => (item.options = []))
      let data = {
        cubeDataId,
        dataPermId,
        cubePermName,
        filterJson: JSON.stringify({ filterList, filterRelation }),
        excludeColumnIds: excludeColumn.map((i) => i.id).join(',')
      }
      id && (data.id = id)
      cubePremSave(Base64.encode(JSON.stringify(data))).then((res) => {
        this.$message({ type: 'success', message: '已提交' })
        this.$emit('done')
      })
    },
    onAddColumn(field) {
      if (this.nowFilter.excludeColumn.find((i) => i.id == field.id)) return
      this.nowFilter.excludeColumn.push(field)
    },
    // 添加条件时
    onAddFilter(field) {
      let column = util.filterFields([field], this.columnKeys)[0]
      let nowField = { column }
      nowField.uniqId = util.getRandomStr(7)
      nowField.cubeColumnId = field.id
      nowField.connectType = 'and'
      nowField.conditions = [
        {
          function: 'eq',
          values: ['', ''],
          timeType: 'absolute',
          countType: 'left'
        }
      ]
      nowField.asFilter = true
      nowField.options = []
      nowField.enumSource = '1'
      nowField.enumId = ''
      if (nowField.viewDataType === 'DATETIME') {
        nowField.dateType = this.dateTypeMap[field.timeDataFormat]
        nowField.dateFormat = this.fieldDateFormats.find((i) => i.value === field.timeDataFormat).label
      }
      this.nowFilter.filterList.push(nowField)
      this.nowFilter.filterRelation.where.conditions.push({
        uniqId: nowField.uniqId,
        columnTitle: column.columnTitle
      })
    }
  }
}
</script>
<style lang="scss">
.dataset-filter-item {
  flex: 1;
  height: 600px;
  overflow-y: auto;
  .btns {
    margin-top: 20px;
    text-align: center;
    .el-button {
      width: 80px;
    }
  }
  .filter-item {
    width: 300px;
    display: flex;
    height: 30px;
    line-height: 30px;
    align-items: center;
    padding: 0 10px;
    margin: 10px;
    border: 1px solid #ccc;
    .title {
      flex: 1;
      &.WEIDU {
        color: #468cff;
      }
      &.ZHIBIAO {
        color: #00c13a;
      }
    }
    .type {
      color: #777;
    }
  }
  .column {
    padding: 0 8px;
    margin: 8px 4px;
    width: 200px;
    height: 26px;
    line-height: 26px;
    font-size: 14px;
    box-sizing: border-box;
    display: flex;
    justify-content: space-between;
    align-items: center;
    &.WEIDU {
      border: 1px solid #468cff;
    }
    &.ZHIBIAO {
      border: 1px solid #00c13a;
    }
    .close {
      color: #f56c6c;
      cursor: pointer;
      margin-left: 5px;
    }
  }
  .el-tabs {
    margin-left: 10px;
  }
  .el-tab-pane {
    height: 400px;
    overflow-y: auto;
  }
}
</style>
