<template>
  <div id="newbi-bigdata-preview">
    <div class="top-wrapper">
      <div class="toggle-btn" @click="topSwitch = !topSwitch">
        <i class="el-icon-arrow-down" v-show="!topSwitch"></i>
        <i class="el-icon-arrow-up" v-show="topSwitch"></i>
        {{ topSwitch ? "收起" : "展开" }}
      </div>
      <div class="btns" v-show="!topSwitch">
        <el-button
          v-for="(item, i) of bigdataList"
          :key="item.id"
          size="mini"
          type="primary"
          :plain="index != item.id"
          @click="index = item.id"
        >
          {{ i + 1 }}
        </el-button>
      </div>
      <div
        v-show="!topSwitch && nowBigdata && nowBigdata.content.editSwitch"
        class="goedit"
      >
        <el-button
          size="mini"
          icon="el-icon-edit"
          type="success"
          plain
          @click="goEdit"
        >
          编辑
        </el-button>
      </div>
      <div class="grids" v-show="topSwitch">
        <div
          class="item"
          v-for="item of bigdataList"
          :key="item.id"
          :class="{ active: index == item.id }"
          @click="index = item.id"
        >
          <img :src="baseUrl + '/' + item.backgroundUrl" alt="" class="bg" />
          <div class="name">{{ item.title }}</div>
        </div>
      </div>
    </div>
    <div class="main-wrapper">
      <div class="wrapper-arrow left-arrow" title="上一页" @click="goPrev">
        <i class="el-icon-arrow-left"></i>
      </div>
      <div class="wrapper-arrow right-arrow" title="下一页" @click="goNext">
        <i class="el-icon-arrow-right"></i>
      </div>
      <div id="bigdata-wrapper">
        <div id="wrapper">
          <div
            class="bigdata"
            v-for="item of bigdataList"
            :key="item.id"
            :style="countStyle(item)"
          >
            <preview-chart
              v-for="chart of item.chartList"
              v-bind="chart"
              :key="chart.key"
              @click.native.stop="onSelectChart(chart)"
              :ref="chart.key"
              :config="chart.dataconfig"
              :index="chart.key"
              :nowChart="nowChart"
              :scale="item.scale * 100"
              :isEdit="false"
              :now="index == item.id"
              :charts="item.chartList"
            ></preview-chart>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import {
  bigdataList,
  bigdataDetail,
  chartDetail,
  optionList,
} from "../../../api/newbi/bigdata";
import website from "../../../config/website";
import chartLib from "../../../newCharts/loadCharts";
import { fieldDateFormats, dateTypeMap, defaultFieldExtJson } from "../dict";
import util from "../../../util/wey";
import previewChart from "../comps/previewChart.vue";
export default {
  components: { previewChart },
  data() {
    return {
      bigdataList: [],
      index: 0,
      showLeft: true,
      baseUrl: website.url.replace("/dev", ""),
      chartLib,
      fieldDateFormats,
      dateTypeMap,
      nowChart: null,
      topSwitch: false,
    };
  },
  computed: {
    nowBigdata() {
      return this.bigdataList.find((i) => i.id == this.index);
    },
  },
  watch: {
    index(id) {
      localStorage.setItem("pastPreviewId", id);
      if (!id) return;
      let nowBigdata = this.bigdataList.find((i) => i.id == id);
      if (!nowBigdata) return;
      if (nowBigdata.done) return;
      bigdataDetail({ id }).then((res) => {
        let tasks = res.data.data.componentIds.map((id) =>
          this.chartBackfill(id, nowBigdata.chartList)
        );
        Promise.all(tasks).then((_) => {
          nowBigdata.done = true;
          this.initPreview();
        });
      });
    },
    showLeft() {
      this.$nextTick(this.resize);
    },
  },
  created() {
    window.addEventListener("resize", this.resize);
    let { category, id } = this.$route.query;
    bigdataList({ category }).then((res) => {
      this.bigdataList = res.data.data.map((i) => ({
        ...i,
        chartList: [],
        content: JSON.parse(i.content),
        scale: 1,
        done: false,
      }));
      this.resize();
      let flag = localStorage.getItem("bigdataPreviewFlag");
      localStorage.setItem("bigdataPreviewFlag", "");
      if (flag) {
        this.index = id;
        return;
      }
      let pastPreviewId = localStorage.getItem("pastPreviewId");
      if (
        !pastPreviewId ||
        !this.bigdataList.find((i) => i.id == pastPreviewId)
      ) {
        this.index = id;
      } else {
        this.index = pastPreviewId;
      }
    });
  },
  mounted() {
    this.$bus.$on("previewAll", this.previewAll);
  },
  destroyed() {
    window.removeEventListener("resize", this.resize);
  },
  methods: {
    initPreview() {
      this.nowBigdata.chartList.forEach((i) => {
        if (!this.$refs[i.key]) return;
        this.$refs[i.key][0].initPreview();
      });
    },
    goEdit() {
      let routeUrl = this.$router.resolve({
        path: "/newbi/bigdata/edit?id=" + this.index,
      });
      window.open(routeUrl.href, "_blank");
    },
    // 全部组件预览
    previewAll(list) {
      this.nowBigdata.chartList.forEach((i) => {
        let has = list.find((j) =>
          j.chartList.find((k) => k.chartKey == i.key)
        );
        if (has) {
          if (!this.$refs[i.key]) return;
          this.$refs[i.key][0].preview(true, false, list);
        }
      });
    },
    goPrev() {
      let nowSort = this.bigdataList.findIndex((i) => i.id == this.index);
      if (nowSort > 0) {
        this.index = this.bigdataList[nowSort - 1].id;
      }
    },
    goNext() {
      let nowSort = this.bigdataList.findIndex((i) => i.id == this.index);
      if (nowSort < this.bigdataList.length - 1) {
        this.index = this.bigdataList[nowSort + 1].id;
      }
    },
    // 选中某个组件时
    onSelectChart(chart) {
      this.nowBigdata.chartList.forEach((i) => {
        i.select = false;
      });
      this.nowChart = chart;
      chart.select = true;
    },
    // 组件配置回填
    chartBackfill(id, chartList) {
      return new Promise((resolve, reject) => {
        chartDetail({ id }).then((res) => {
          let {
            columnJson,
            filterJson,
            sortJson,
            limitVal,
            content,
            id,
            name,
            title,
            cubeDataId,
            useType,
            extJson,
          } = res.data.data;
          let { option, site, params, key } = JSON.parse(content);
          site.hiddened = site.hiddened || false;
          let charts = this.chartLib.reduce((r, i) => r.concat(i.charts), []);
          let chartSet = charts.find((i) => i.name == name);
          let nowChart = {
            name,
            title: title || chartSet.title,
            option,
            site,
            id,
            select: false,
            key: key || util.getRandomStr(10),
            ext: JSON.parse(extJson || "{}"),
          };
          if (chartSet.dataconfig) {
            let { modalSet } = chartSet;
            nowChart.dataconfig = {
              dataType: useType,
              category: "",
              dataId: cubeDataId,
              limit: limitVal,
              params: params || [],
              zuanFlag: nowChart.ext.zuanFlag || false,
              zuan: nowChart.ext.zuanList || [],
              zuanLevel: 0,
              zuanStack: [],
            };
            nowChart.modalSet = modalSet;
            columnJson = JSON.parse(columnJson);
            columnJson.forEach((i) => {
              i.zuan = i.zuan || false;
              let ext = JSON.parse(i.extJson || "{}");
              i.extJson = Object.assign({}, defaultFieldExtJson, ext);
            });
            modalSet.forEach((set) => {
              nowChart.dataconfig[set.key] = columnJson.filter(
                (i) => i.type == set.key
              );
            });
            nowChart.dataconfig.filter = JSON.parse(filterJson).map((field) => {
              let {
                column,
                conditions,
                connectTime,
                connectType,
                asFilter,
                enumSource,
                enumId,
              } = field;
              let r = {
                conditions,
                connectTime,
                connectType,
                ...column,
                options: [],
                asFilter: asFilter === undefined ? true : asFilter,
                enumSource,
                enumId,
                loading: false,
              };
              if (r.viewDataType == "DATETIME") {
                r.dateType = this.dateTypeMap[r.timeDataFormat];
                r.dateFormat = this.fieldDateFormats.find(
                  (i) => i.value == r.timeDataFormat
                ).label;
              }
              if (["in", "notIn"].includes(r.conditions[0].function)) {
                let { tableName, columnName } = r;
                optionList({
                  tableName,
                  columnName,
                  cubeDataId: nowChart.dataconfig.dataId,
                }).then((res) => {
                  r.options = res.data.data.map((i) => i[columnName]);
                });
              }
              return r;
            });
            nowChart.dataconfig.sort = JSON.parse(sortJson).map((i) => {
              return {
                orderType: i.orderType,
                ...i.column,
              };
            });
          }
          chartList.push(nowChart);
          resolve();
        });
      });
    },
    countStyle(bigdata) {
      let { bgColor, bgImg, width, height } = bigdata.content;
      let flag = this.index == bigdata.id;
      return {
        backgroundColor: bgColor,
        width: width + "px",
        height: height + "px",
        transform: `scale(${bigdata.scale}) translateX(-50%)`,
        backgroundImage: bgImg ? `url(${bgImg})` : "none",
        top: flag ? "0" : "-100%",
        zIndex: flag ? 1 : 0,
        opacity: flag ? 1 : 0,
      };
    },
    resize() {
      let domWidth = document.getElementById("bigdata-wrapper").clientWidth;
      this.bigdataList.forEach((item) => {
        let scale = domWidth / parseInt(item.content.width);
        item.scale = Math.floor(scale * 100) / 100;
      });
    },
  },
};
</script>
<style lang="scss">
#newbi-bigdata-preview {
  padding: 0 !important;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  .top-wrapper {
    display: flex;
    overflow-x: auto;
    border-bottom: 1px solid #ccc;
    .toggle-btn {
      flex: 0 0 80px;
      text-align: center;
      line-height: 50px;
      font-size: 14px;
      cursor: pointer;
      color: #666;
      transition: all 0.2s;
      &:hover {
        color: #409eff;
      }
    }
    .btns,
    .grids {
      flex: 1;
      display: flex;
      flex-wrap: nowrap;
      overflow-x: auto;
      overflow-y: hidden;
      padding: 10px;
      align-items: center;
      &::-webkit-scrollbar {
        height: 3px;
      }
    }
    .goedit {
      padding: 10px;
    }
    .grids {
      .item {
        width: 220px;
        margin: 0 5px;
        cursor: pointer;
        border: 1px solid #ccc;
        .bg {
          width: 220px;
          height: 130px;
          display: block;
        }
        .name {
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
          height: 30px;
          line-height: 30px;
          text-align: center;
          padding: 0 5px;
          font-size: 14px;
          background-color: #fff;
          color: #999;
        }
        &.active {
          .name {
            background-color: #409eff;
            color: #fff;
          }
        }
      }
    }
  }
  .main-wrapper {
    flex: 1;
    box-sizing: border-box;
    padding: 16px 30px 20px;
    position: relative;
    .wrapper-arrow {
      width: 24px;
      height: 100px;
      line-height: 100px;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      font-size: 34px;
      font-weight: 600;
      cursor: pointer;
      transition: all 0.2s;
      color: #409eff;
      background-color: #ecf5ff;
      border-radius: 4px;
      i {
        margin-left: -5px;
      }
      &:hover {
        color: #fff;
        background-color: #409eff;
      }
      &.left-arrow {
        left: 3px;
      }
      &.right-arrow {
        right: 3px;
      }
    }
    #bigdata-wrapper {
      height: 100%;
      position: relative;
      overflow-y: auto;
      .bigdata {
        position: absolute;
        left: 50%;
        transform-origin: 0 0;
        background-size: cover;
        background-position: center center;
      }
    }
  }
}
</style>