<template>
  <div class="bigdata-data-setting">
    <div class="form-wrapper">
      <el-form size="mini" label-width="60px">
        <el-form-item label="数据来源">
          <el-select v-model="config.dataType" @change="onDataTypeChange">
            <el-option label="数据集" value="CUBE"></el-option>
            <el-option label="API" value="API"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="数据集" v-if="config.dataType == 'CUBE'">
          <el-cascader
            v-model="config.dataId"
            :options="cubeList"
            :props="{ expandTrigger: 'hover', emitPath: false }"
            filterable
            @change="onDataIdChange"
            popper-class="bigdata-data-selector"
            :show-all-levels="false"
          ></el-cascader>
        </el-form-item>
        <el-form-item label="API" v-if="config.dataType == 'API'">
          <el-cascader
            v-model="config.dataId"
            :options="apiList"
            :props="{ expandTrigger: 'hover', emitPath: false }"
            filterable
            @change="onDataIdChange"
            popper-class="bigdata-data-selector"
            :show-all-levels="false"
          ></el-cascader>
        </el-form-item>
      </el-form>
      <div class="btns">
        <el-button
          size="mini"
          type="success"
          plain
          icon="el-icon-refresh"
          @click="getDataSource"
        >
          刷新
        </el-button>
        <el-button
          size="mini"
          type="primary"
          plain
          icon="el-icon-edit"
          v-show="config.dataId"
          @click="onGoEditData"
        >
          编辑
        </el-button>
      </div>
    </div>
    <div class="right-center-panel" v-show="!config.dataType"></div>
    <div class="right-center-panel" v-show="config.dataType == 'CUBE'">
      <!-- 已选字段列表 -->
      <div class="chart-fields">
        <div class="line" v-show="showFields"></div>
        <div class="group" v-show="config.zuanFlag">
          <div class="name">钻取/维度</div>
          <div
            :class="{ btn: 1, active: fieldSet.zuan }"
            @click="onFieldSetSwitch('zuan')"
          >
            选择字段 <i class="el-icon-d-arrow-right"></i>
          </div>
        </div>
        <div
          :class="{ 'item-box': 1, active: fieldSet.zuan, zuan: 1 }"
          v-show="config.zuanFlag"
        >
          <i class="el-icon-sort-down"></i>
          <draggable
            v-model="config.zuan"
            :animation="150"
            :class="{ 'item-box': 1, active: fieldSet.zuan }"
          >
            <div
              :class="['item', field.dimensionType]"
              v-for="(field, i) of config.zuan"
              :key="i"
            >
              <div class="name">{{ field.columnTitle }}</div>
              <i class="el-icon-close" @click="onFieldDel('zuan', i)"></i>
            </div>
          </draggable>
        </div>
        <div v-for="modal of modalSet" :key="modal.name">
          <div class="group">
            <div class="name">
              {{ modal.name + "/" + typeMap[modal.type] }}
            </div>
            <div style="margin-right: 5px">
              {{ config[modal.key].length + "/" + modal.length }}
            </div>
            <div
              :class="{ btn: 1, active: fieldSet[modal.key] }"
              @click="onFieldSetSwitch(modal.key)"
            >
              选择字段 <i class="el-icon-d-arrow-right"></i>
            </div>
          </div>
          <draggable
            v-model="config[modal.key]"
            :animation="150"
            :class="{ 'item-box': 1, active: fieldSet[modal.key] }"
          >
            <div
              :class="['item', field.dimensionType]"
              v-for="(field, i) of config[modal.key]"
              :key="i"
            >
              <div class="name">{{ field.columnTitle }}</div>
              <el-tooltip
                effect="dark"
                content="钻取"
                placement="left"
                v-show="modal.zuan"
              >
                <i
                  class="el-icon-caret-bottom"
                  :class="{ active: field.zuan }"
                  @click="onFieldZuan(field)"
                ></i>
              </el-tooltip>
              <field-setting
                v-if="config.dataType == 'CUBE'"
                :field="field"
              ></field-setting>
              <i class="el-icon-close" @click="onFieldDel(modal.key, i)"></i>
            </div>
          </draggable>
        </div>
        <filter-setting
          :config="config"
          :active="fieldSet.filter"
          :modalSet="modalSet"
          @onFieldSetSwitch="onFieldSetSwitch"
          :apiList="apiList"
        ></filter-setting>
        <div class="group">
          <div class="name">排序</div>
          <div
            :class="{ btn: 1, active: fieldSet.sort }"
            @click="onFieldSetSwitch('sort')"
          >
            选择字段 <i class="el-icon-d-arrow-right"></i>
          </div>
        </div>
        <draggable
          v-model="config.sort"
          :animation="150"
          :class="{ 'item-box': 1, active: fieldSet.sort }"
        >
          <div
            :class="['item', field.dimensionType]"
            v-for="(field, i) of config.sort"
            :key="i"
          >
            <div class="name">{{ field.columnTitle }}</div>
            <i
              class="el-icon-top"
              style="margin-right: 5px; cursor: pointer"
              v-if="field.orderType == 'ASC'"
              @click="field.orderType = 'DESC'"
            ></i>
            <i
              class="el-icon-bottom"
              style="margin-right: 5px; cursor: pointer"
              v-else
              @click="field.orderType = 'ASC'"
            ></i>
            <i class="el-icon-close" @click="onFieldDel('sort', i)"></i>
          </div>
        </draggable>
      </div>
      <!-- 待选字段列表 -->
      <div class="cube-fields" v-show="showFields">
        <el-input
          size="mini"
          v-model="searckKey"
          @input="onFieldSearch"
          placeholder="搜索字段"
          style="width: 189px"
        ></el-input>
        <div class="btns">
          <div class="btn" @click="onFieldSetAddAll">
            <i class="el-icon-plus"></i> 添加全部
          </div>
          <div class="btn" @click="onFieldSetClear">
            <i class="el-icon-delete"></i> 清空
          </div>
        </div>
        <div class="items">
          <div
            :class="['item', field.dimensionType, field.select ? 'unuse' : '']"
            v-for="(field, i) of fieldListSearched"
            :key="i"
            @click="onFieldAdd(field)"
          >
            <div
              :class="[
                'type',
                field.dimensionType,
                field.select ? 'unuse' : '',
              ]"
            >
              {{ field.dimensionType == "WEIDU" ? "维度" : "指标" }}
            </div>
            <div
              class="name"
              :title="field.columnTitle + ' ' + field.columnName"
            >
              {{ field.columnTitle + " " + field.columnName }}
            </div>
            <i class="add el-icon-plus" v-show="!field.select"></i>
          </div>
        </div>
      </div>
    </div>
    <div class="right-center-panel" v-show="config.dataType == 'API'">
      <div class="chart-fields">
        <div class="line" v-show="showFields"></div>
        <div v-for="modal of modalSet" :key="modal.name">
          <div class="group">
            <div class="name">
              {{ modal.name + "/" + typeMap[modal.type] }}
            </div>
            <div style="margin-right: 5px">
              {{ config[modal.key].length + "/" + modal.length }}
            </div>
            <div
              :class="{ btn: 1, active: fieldSet[modal.key] }"
              @click="onFieldSetSwitch(modal.key)"
            >
              选择字段 <i class="el-icon-d-arrow-right"></i>
            </div>
          </div>
          <draggable
            v-model="config[modal.key]"
            :animation="150"
            :class="{ 'item-box': 1, active: fieldSet[modal.key] }"
          >
            <div
              :class="['item', field.dimensionType]"
              v-for="(field, i) of config[modal.key]"
              :key="i"
            >
              <div class="name">{{ field.columnTitle }}</div>
              <i class="el-icon-close" @click="onFieldDel(modal.key, i)"></i>
            </div>
          </draggable>
        </div>
        <div class="group">
          <div class="name">参数设置</div>
        </div>
        <el-form size="mini" label-width="80px" class="params-form">
          <el-form-item
            v-for="(param, i) of config.params"
            :key="i"
            :label="param.key"
          >
            <el-input
              v-if="param.datatype == 'string'"
              v-model="param.def"
            ></el-input>
            <el-input
              v-if="param.datatype == 'number'"
              type="number"
              v-model="param.def"
            ></el-input>
            <el-date-picker
              v-if="param.datatype == 'date'"
              v-model="param.def"
              type="date"
              placeholder="选择日期"
              value-format="yyyyMMdd"
            >
            </el-date-picker>
            <el-date-picker
              v-if="param.datatype == 'month'"
              v-model="param.def"
              type="month"
              placeholder="选择月"
              value-format="yyyyMM"
            >
            </el-date-picker>
            <el-time-picker
              v-if="param.datatype == 'time'"
              v-model="param.def"
              placeholder="选择时间"
              value-format="HH:mm:ss"
            >
            </el-time-picker>
            <el-date-picker
              v-if="param.datatype == 'timestamp'"
              v-model="param.def"
              type="date"
              placeholder="选择日期"
              value-format="timestamp"
            >
            </el-date-picker>
            <el-time-picker
              v-if="param.datatype == 'timestamp'"
              v-model="param.def"
              placeholder="选择时间"
              value-format="timestamp"
            >
            </el-time-picker>
          </el-form-item>
        </el-form>
      </div>
      <div class="cube-fields" v-show="showFields">
        <el-input
          size="mini"
          v-model="searckKey"
          @input="onFieldSearch"
          placeholder="搜索字段"
          style="width: 189px"
        ></el-input>
        <div class="btns">
          <div class="btn" @click="onFieldSetAddAll">
            <i class="el-icon-plus"></i> 添加全部
          </div>
          <div class="btn" @click="onFieldSetClear">
            <i class="el-icon-delete"></i> 清空
          </div>
        </div>
        <div class="items">
          <div
            :class="['item', field.dimensionType, field.select ? 'unuse' : '']"
            v-for="(field, i) of fieldListSearched"
            :key="i"
            @click="onFieldAdd(field)"
          >
            <div
              :class="[
                'type',
                field.dimensionType,
                field.select ? 'unuse' : '',
              ]"
            >
              {{ field.dimensionType == "WEIDU" ? "维度" : "指标" }}
            </div>
            <div class="name" :title="field.columnTitle">
              {{ field.columnTitle }}
            </div>
            <i class="add el-icon-plus" v-show="!field.select"></i>
          </div>
        </div>
      </div>
    </div>
    <div class="bottom-panel">
      <el-form size="mini" label-width="70px">
        <el-form-item label="定时请求">
          <el-switch v-model="option.intervalSwitch"></el-switch>
        </el-form-item>
        <el-form-item label="请求间隔">
          <el-input v-model="option.intervalTime" type="number"></el-input>
        </el-form-item>
        <el-form-item label="结果展示">
          <el-input v-model="config.limit" type="number">
            <span slot="suffix">条</span>
          </el-input>
        </el-form-item>
      </el-form>
      <div class="btns">
        <el-button
          size="mini"
          type="success"
          plain
          icon="el-icon-refresh"
          @click="onPreview"
        >
          预览
        </el-button>
      </div>
    </div>
  </div>
</template>
<script>
import { cubeFieldList } from "../../../api/newbi/dataset";
import { dataapiDetail } from "../../../api/report/report";
import {
  fieldAggregates,
  fieldNumberFormats,
  fieldDateFormats,
  dateTypeMap,
  defaultFieldExtJson,
} from "../dict";
import fieldSetting from "./fieldSetting.vue";
import filterSetting from "./filterSetting.vue";
import { VueDraggableNext as draggable} from "vue-draggable-next";
export default {
  components: { fieldSetting, filterSetting, draggable },
  props: [
    "config",
    "option",
    "modalSet",
    "cubeList",
    "apiList",
    "rightPanelIndex",
    "showRightPanel",
  ],
  data() {
    return {
      fieldAggregates,
      fieldNumberFormats,
      fieldDateFormats,
      dimensionField: [],
      measureField: [],
      showFields: false,
      searckKey: "",
      fieldList: [],
      fieldListSearched: [],
      fieldSet: {
        dimension: false,
        measure: false,
        serie: false,
        filter: false,
        sort: false,
      },
      dateTypeMap,
      typeMap: { measure: "指标", dimension: "维度" },
    };
  },
  computed: {
    fieldAggregatesMap() {
      return this.fieldAggregates.reduce(
        (r, i) => ({ ...r, [i.value]: i.label }),
        {}
      );
    },
  },
  watch: {
    showFields(flag) {
      this.$emit("toggleHigh", flag);
    },
    rightPanelIndex() {
      this.onFieldSetClose();
    },
    showRightPanel() {
      this.onFieldSetClose();
    },
    config() {
      this.onFieldSetClose();
      let { dataId } = this.config;
      if (!dataId) return;
      if (this.config.dataType == "CUBE") {
        this.getDataDetail(dataId);
      } else if (this.config.dataType == "API") {
        this.getApiDetail(dataId, true);
      }
    },
  },
  created() {
    let { dataId } = this.config;
    if (!dataId) return;
    if (this.config.dataType == "CUBE") {
      this.getDataDetail(dataId);
    } else if (this.config.dataType == "API") {
      this.getApiDetail(dataId, true);
    }
  },
  methods: {
    // 刷新数据来源
    getDataSource() {
      this.$emit("refresh");
      if (this.config.dataId) {
        let id = this.config.dataId;
        if (this.config.dataType == "CUBE") {
          this.getDataDetail(id);
        } else if (this.config.dataType == "API") {
          this.getApiDetail(id);
        }
      }
    },
    // 获取可钻取配置块的key
    getZuanModal() {
      return this.modalSet.find((i) => i.zuan).key;
    },
    cancelZuan() {
      let key = this.getZuanModal();
      this.config[key].forEach((i) => (i.zuan = false));
      this.config.zuanFlag = false;
      this.config.zuanLevel = 0;
      this.config.zuanStack = [];
      this.config.zuan = [];
    },
    // 设置钻取字段时
    onFieldZuan(field) {
      if (field.zuan) {
        this.cancelZuan();
        return;
      }
      this.config.zuanFlag = true;
      // 设置其他字段非钻取
      let key = this.getZuanModal();
      this.config[key].forEach((i) => (i.zuan = false));
      field.zuan = true;
      // 清空钻取配置块，添加本字段
      this.config.zuan = [{ ...field }];
    },
    // 跳转编辑数据来源
    onGoEditData() {
      let routeUrl = "";
      if (this.config.dataType == "CUBE") {
        routeUrl = this.$router.resolve({
          path: "/newbi/dataset/edit?id=" + this.config.dataId,
        });
      } else if (this.config.dataType == "API") {
        routeUrl = this.$router.resolve({
          path: "/apiedit?id=" + this.config.dataId,
        });
      }
      if (routeUrl) {
        window.open(routeUrl.href, "_blank");
      }
    },
    // 数据来源id变化时动态获取详情
    onDataIdChange(id) {
      this.modalSet.forEach((set) => {
        this.config[set.key] = [];
      });
      this.config.filter = [];
      this.config.sort = [];
      if (!id) return;
      if (this.config.dataType == "CUBE") {
        this.getDataDetail(id);
      } else if (this.config.dataType == "API") {
        this.getApiDetail(id);
      }
    },
    // 获取api详情，flag标志是否是回填，如果是回填，保存原先params配置
    getApiDetail(id, flag) {
      dataapiDetail(id).then((res) => {
        let resJson = JSON.parse(res.data.data.note || "{}");
        let fields = resJson.showFields || [];
        let params = resJson.params || [];
        if (!flag) {
          this.config.params = params;
        }
        this.dimensionField = fields
          .filter((i) => i.dataType == 0)
          .map((i) => ({
            columnName: i.columnName,
            columnTitle: i.columnComments,
            dimensionType: "WEIDU",
            extJson: { hidden: false },
          }));
        this.measureField = fields
          .filter((i) => i.dataType == 1)
          .map((i) => ({
            columnName: i.columnName,
            columnTitle: i.columnComments,
            dimensionType: "ZHIBIAO",
            extJson: { hidden: false },
          }));
        this.searckKey = "";
        this.filterFields();
      });
    },
    // 数据来源变化时
    onDataTypeChange() {
      this.config.dataId = "";
      this.modalSet.forEach((set) => {
        this.config[set.key] = [];
      });
      this.config.filter = [];
      this.config.sort = [];
      this.config.zuan = [];
    },
    onPreview() {
      this.$emit("preview");
    },
    // 检查排序字段状态，去除掉未选字段
    setSortFields() {
      let list = [];
      this.modalSet.forEach((set) => {
        list = list.concat(this.config[set.key]);
      });
      this.config.sort = this.config.sort.filter((i) =>
        list.find((j) => j.cubeColumnId == i.cubeColumnId)
      );
    },
    // 删除某字段
    onFieldDel(activeKey, index) {
      let field = this.config[activeKey][index];
      this.config[activeKey].splice(index, 1);
      this.filterFields();
      this.setSortFields();
      let key = this.getZuanModal();
      // 如果删除钻取配置块第一项，则取消钻取配置
      if (activeKey == "zuan" && index == 0) {
        this.cancelZuan();
      }
      // 如果删除已钻取字段，则取消钻取配置
      if (activeKey == key) {
        if (field.zuan) {
          this.cancelZuan();
        }
      }
    },
    // 选中所有待选字段
    onFieldSetAddAll() {
      let activeKey = Object.keys(this.fieldSet).find((k) => this.fieldSet[k]);
      if (!activeKey) return;
      if (activeKey == "filter") return;
      if (activeKey == "sort") return;
      if (activeKey == "zuan") return;
      let set = this.modalSet.find((i) => i.key == activeKey);
      let list = this.fieldListSearched
        .filter((i) => !i.select)
        .slice(0, set.length - this.config[activeKey].length);
      list.forEach((field) => {
        field.select = true;
        let nowField = { ...field };
        nowField.cubeColumnId = field.id;
        delete nowField.id;
        this.config[activeKey].push(nowField);
      });
    },
    // 清空所有已选字段
    onFieldSetClear() {
      let activeKey = Object.keys(this.fieldSet).find((k) => this.fieldSet[k]);
      if (!activeKey) return;
      this.config[activeKey] = [];
      this.fieldList.forEach((i) => (i.select = false));
      this.setSortFields();
      let key = this.getZuanModal();
      if (key == activeKey) {
        this.cancelZuan();
      }
      if (activeKey == "zuan") {
        this.cancelZuan();
      }
    },
    // 给某个配置项添加字段
    onFieldAdd(field) {
      if (field.select) return;
      let activeKey = Object.keys(this.fieldSet).find((k) => this.fieldSet[k]);
      if (!activeKey) return;
      let set = this.modalSet.find((i) => i.key == activeKey);
      if (set && this.config[activeKey].length >= set.length) return;
      let nowField = { ...field };
      nowField.cubeColumnId = field.id;
      delete nowField.id;
      if (activeKey == "filter") {
        nowField.connectTime = "where"; // 过滤时机 where having
        nowField.connectType = "and"; // 连接方式 or and
        nowField.conditions = [
          {
            function: "eq",
            values: ["", ""],
            timeType: "absolute",
            countType: "left",
          },
        ]; // 条件列表
        nowField.asFilter = true;
        nowField.options = []; // 枚举值列表
        nowField.enumSource = "1";
        nowField.enumId = "";
        nowField.loading = false;
        if (nowField.viewDataType == "DATETIME") {
          nowField.dateType = this.dateTypeMap[field.timeDataFormat];
          nowField.dateFormat = this.fieldDateFormats.find(
            (i) => i.value == field.timeDataFormat
          ).label;
        }
      } else {
        field.select = true;
      }
      if (activeKey == "sort") {
        nowField.cubeColumnId = field.cubeColumnId;
        nowField.orderType = "ASC";
      }
      this.config[activeKey].push(nowField);
    },
    // 根据配置项不同，分别设置待操作字段列表
    filterFields() {
      let activeKey = Object.keys(this.fieldSet).find((k) => this.fieldSet[k]);
      if (!activeKey) return;
      // 如果数据来源是数据集
      if (this.config.dataType == "CUBE") {
        if (activeKey == "filter") {
          this.fieldList = [...this.dimensionField, ...this.measureField];
          this.fieldListSearched = [...this.fieldList];
          return;
        }
        if (activeKey == "sort") {
          let list = [];
          this.modalSet.forEach((set) => {
            list = list.concat(this.config[set.key]);
          });
          this.fieldList = JSON.parse(JSON.stringify(list));
          this.fieldList.forEach((i) => {
            i.select = !!this.config.sort.find(
              (j) => j.cubeColumnId == i.cubeColumnId
            );
          });
          this.fieldListSearched = [...this.fieldList];
          return;
        }
        if (activeKey == "zuan") {
          let selected = this.modalSet.reduce((r, i) => {
            if (i.type == "dimension") {
              r = r.concat(this.config[i.key]);
            }
            return r;
          }, []);
          selected = selected.concat(this.config.zuan);
          this.fieldList = [...this.dimensionField].map((i) => ({
            ...i,
            select: selected.find((j) => j.cubeColumnId == i.id),
          }));
          this.fieldListSearched = [...this.fieldList];
          return;
        }
        let set = this.modalSet.find((i) => i.key == activeKey);
        let selected = this.modalSet.reduce((r, i) => {
          if (i.type == set.type) {
            r = r.concat(this.config[i.key]);
          }
          return r;
        }, []);
        if (set.type == "dimension") {
          this.fieldList = [...this.dimensionField].map((i) => ({
            ...i,
            select: selected.find((j) => j.cubeColumnId == i.id),
          }));
          this.fieldListSearched = [...this.fieldList];
        }
        if (set.type == "measure") {
          this.fieldList = [...this.measureField].map((i) => ({
            ...i,
            select: selected.find((j) => j.cubeColumnId == i.id),
          }));
          this.fieldListSearched = [...this.fieldList];
        }
        // 如果数据来源是api
      } else if (this.config.dataType == "API") {
        let set = this.modalSet.find((i) => i.key == activeKey);
        let selected = this.modalSet.reduce((r, i) => {
          if (i.type == set.type) {
            r = r.concat(this.config[i.key]);
          }
          return r;
        }, []);
        if (set.type == "dimension") {
          this.fieldList = [...this.dimensionField].map((i) => ({
            ...i,
            select: selected.find((j) => j.columnTitle == i.columnTitle),
          }));
          this.fieldListSearched = [...this.fieldList];
        }
        if (set.type == "measure") {
          this.fieldList = [...this.measureField].map((i) => ({
            ...i,
            select: selected.find((j) => j.columnTitle == i.columnTitle),
          }));
          this.fieldListSearched = [...this.fieldList];
        }
      }
    },
    // 搜索字段
    onFieldSearch(key) {
      this.fieldListSearched = this.fieldList.filter(
        (i) =>
          i.columnTitle.includes(key) ||
          i.columnName.includes(key) ||
          i.columnName.toLowerCase().includes(key)
      );
    },
    // 打开某个配置项的字段选择时
    onFieldSetSwitch(activeKey) {
      let flag = this.fieldSet[activeKey];
      Object.keys(this.fieldSet).forEach((k) => (this.fieldSet[k] = false));
      this.fieldSet[activeKey] = !flag;
      this.showFields = !flag;
      this.searckKey = "";
      this.filterFields();
    },
    // 关闭待选字段列表
    onFieldSetClose() {
      Object.keys(this.fieldSet).forEach((k) => (this.fieldSet[k] = false));
      this.showFields = false;
    },
    // 获取数据集下字段列表
    getDataDetail(id) {
      cubeFieldList({ cubeDataId: id }).then((res) => {
        let list = res.data.data.filter((i) => !i.hiddenStatus);
        list.forEach((i) => {
          i.zuan = false;
          i.extJson = { ...defaultFieldExtJson };
        });
        this.dimensionField = list
          .filter((i) => i.dimensionType == "WEIDU")
          .sort((a, b) => a.sortNum - b.sortNum);
        this.measureField = list
          .filter((i) => i.dimensionType == "ZHIBIAO")
          .sort((a, b) => a.sortNum - b.sortNum);
        this.searckKey = "";
        this.filterFields();
      });
    },
  },
};
</script>
<style lang="scss">
@import "./dataSetting.scss";
</style>
