<template>
  <div class="dust-box">
    <div class="top-box">
      <el-form
        :model="form"
        label-width="auto"
        :inline="true"
        class="demo-form-inline"
      >
        <el-form-item label="除尘器名称">
          <el-select
            v-model="form.dusterNo"
            placeholder="请选择除尘器"
            style="width: 240px"
            filterable
          >
            <el-option
              v-for="item in dusterList"
              :key="item.dusterNo"
              :label="item.dusterName"
              :value="item.dusterNo"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="分析时间">
          <el-date-picker
            v-model="form.dateValue"
            type="daterange"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            @calendar-change="calendarChange"
            @visible-change="visibleChange"
            :disabled-date="disabledFn"
          />
        </el-form-item>
      </el-form>
    </div>
    <div class="layout1">
      <div class="left-box">
        <div class="part1 layout3">
          <div class="chart-box" v-for="(item, index) in chartData" :key="item">
            <div :id="'chart' + index" class="chart-item"></div>
          </div>
        </div>
        <div class="warn-info">
          <warnCom
            title="告警"
            :listInfo="warnInfoList"
            @jumpPage="toWarnDetail"
          ></warnCom>
        </div>
      </div>
      <div class="right-box">
        <div class="part1">
          <div class="battery">
            <healthyCom :progress="healthPercent"></healthyCom>
          </div>
        </div>
        <div class="part2">
          <div class="dust-title">{{ dusterName }}</div>
          <div class="dust-info">
            <div class="info-item" v-for="item in dustInfo" :key="item.label">
              <span class="label">{{ item.label }}</span>
              <span class="value"
                >{{ item.value }} （<span class="unit">{{ item.unit }}</span
                >）
              </span>
            </div>
            <div></div>
          </div>
          <div class="indicator-box">
            <div class="indicator-item" id="indicatorOne"></div>
            <div class="indicator-item" id="indicatorTwo"></div>
          </div>
          <div class="position-info">
            <div class="left" v-if="detailObj.compartHealthList.length > 0">
              <div
                class="part"
                v-for="(list, index) in detailObj.compartHealthList"
                :key="index"
              >
                <div
                  class="point"
                  :class="{
                    'status-normal': item.healthStatus === 1,
                    'status-error': item.healthStatus === 2,
                    'status-warning': item.healthStatus === 3,
                  }"
                  v-for="item in detailObj.compartHealthList[index]"
                  :key="item"
                  @click="handleStatusDotClick()"
                ></div>
              </div>
            </div>
            <!-- <div class="right">
              <div class="part">
                <div class="point warn" v-for="item in 6" :key="item"></div>
              </div>
              <div class="part">
                <div class="point warn" v-for="item in 6" :key="item"></div>
              </div>
            </div> -->
          </div>
          <div class="other-info">
            <div class="other-info-item">
              <p class="label">反吹仓室：</p>
              <p>{{ detailObj.bachflushCompart }}</p>
            </div>
            <div class="other-info-item">
              <p class="label">泄露仓室：</p>
              <p>{{ detailObj.leakageCompart }}</p>
            </div>
            <div class="other-info-item">
              <p class="label">故障仓室：</p>
              <p>{{ detailObj.faultCompart }}</p>
            </div>
          </div>
        </div>
        <div class="warn-info">
          <warnCom
            title="闭环"
            :listInfo="closedLoopInfoList"
            @jumpPage="toCircleDetail"
          ></warnCom>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { ref, reactive, onMounted, onUnmounted, watch, computed } from "vue";
import { useRouter, useRoute } from "vue-router";
import * as echarts from "echarts";
import { getDataFun } from "@/request/method.js";
import { useUsersStore } from "@/pinia/user.js";
import moment from "moment";
import warnCom from "./components/warn.vue";
import healthyCom from "./components/healthyProgress.vue";
import { getLineOption2, getGaugeOption } from "@/utils/chart";

const userStore = useUsersStore();
const form = reactive({
  dusterNo: "",
  dateValue: [
    moment(new Date(new Date().getTime() - 24 * 60 * 60 * 1000 * 10)).format(
      "YYYY-MM-DD"
    ) + " 00:00:00",
    moment(new Date()).format("YYYY-MM-DD") + " 23:59:59",
  ],
});
const startVal = ref(null);
const calendarChange = (e) => {
  if (e[0] && !e[1]) {
    startVal.value = e[0];
  }
};
const visibleChange = (e) => {
  if (e) {
    startVal.value = null;
  }
};
const disabledFn = (current) => {
  if (!startVal.value) return false;
  let range = [
    new Date(startVal.value).getTime() - 24 * 60 * 60 * 1000 * 30,
    new Date(startVal.value).getTime() + 24 * 60 * 60 * 1000 * 30,
  ];
  let cur = new Date(current).getTime();
  return cur < range[0] || cur > range[1];
};
const option = {
  xAxis: {
    type: "category",
    data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
  },
  yAxis: {
    type: "value",
  },
  series: [
    {
      data: [820, 932, 901, 934, 1290, 1330, 1320],
      type: "line",
      smooth: true,
    },
  ],
};
const router = useRouter();
const route = useRoute();
const chartInstance = reactive({});
const chartData = reactive([{}, {}, {}]);
const initChart = (instance, option, domEl) => {
  if (instance && instance.dispose) {
    instance.dispose();
  }
  instance = echarts.init(document.getElementById(domEl));
  instance.setOption(option);
  chartInstance[domEl] = instance;
  // instance.on("showTip", (params) => {
  //   console.log(params);
  // })
  chartLinkageFun();
};
let instanceList = reactive([])
// 图表联动
const chartLinkageFun = (target) => {
  instanceList = []
  Object.keys(chartInstance).forEach((key) => {
    instanceList.push(chartInstance[key]);
  });
  if (instanceList.length < 3) return;
  instanceList.forEach((item) => {
    item.off("showTip");
    item.off("globalout");
    item.on("globalout", function () {
      instanceList.forEach((item_, index) => {
        item_.dispatchAction({
          type: "hideTip",
        });
      });
    });
    item.on("showTip", function (e) {
      bindToolTip(this, e);
    });
  });
};
const bindToolTip = (that, e) => {
  const connectCharts = instanceList
  if (window.echartTimer) {
    clearTimeout(window.echartTimer);
  }
  window.echartTimer = setTimeout(() => {
    if (!e.dataIndex && e.dataIndex !== 0) {
      connectCharts.forEach((item_) => {
        item_.dispatchAction({
          type: "hideTip",
        });
      });
      return;
    }
    connectCharts.forEach((item_) => {
      if (item_.id != that.id) {
        let option = item_.getOption();
        let xAxisList = option.xAxis[0].data;
        let tmpIndex = e.dataIndex;
        item_.off("showTip");
        if (
          option.yAxis &&
          option.yAxis[0] &&
          option.yAxis[0]["data"] &&
          option.yAxis[0]["data"].length == 2 &&
          option.yAxis[0]["data"][0] === 0 &&
          option.yAxis[0]["data"][1] === 1
        ) {
          item_.dispatchAction({
            type: "showTip",
            seriesIndex: 0,
            dataIndex: tmpIndex,
          });
          item_.dispatchAction({
            type: "showTip",
            seriesIndex: 1,
            dataIndex: tmpIndex,
          });
        } else {
          item_.dispatchAction({
            type: "showTip",
            seriesIndex: 0,
            dataIndex: tmpIndex,
          });
          item_.dispatchAction({
            type: "showTip",
            seriesIndex: 1,
            dataIndex: tmpIndex,
          });
          item_.dispatchAction({
            type: "showTip",
            seriesIndex: 2,
            dataIndex: tmpIndex,
          });
        }

        item_.on("showTip", function (e) {
          bindToolTip(this, e);
        });
      }
    });
  }, 50);
};
// 移出图表事件
const chartRemoveEvent = () => {
  Object.keys(chartInstance).forEach((key) => {
    chartInstance[key].off();
  });
};
const dustInfo = reactive([
  {
    label: "压差",
    value: "0.0",
    unit: "",
    key: "pressureDiff",
    unitKey: "pressureDiffUnit",
  },
  {
    label: "粉尘浓度",
    value: "0.0",
    unit: "",
    key: "dustConcentration",
    unitKey: "dustConcentrationUnit",
  },
  { label: "电磁阀数量", value: "0.0", unit: "", key: "valveNum" },
  { label: "仓室数量", value: "0.0", unit: "", key: "compartNum" },
  { label: "布袋检测仪数量", value: "0.0", unit: "", key: "bagDetectorNum" },
  {
    label: "脉冲检测仪数量",
    value: "0.0",
    unit: "",
    key: "pulseDetectorNum",
  },
]);
const option2 = {
  series: [
    {
      type: "gauge",
      startAngle: 260,
      endAngle: 300,
      center: ["50%", "75%"],
      radius: "90%",
      min: 0,
      max: 1,
      splitNumber: 8,
      axisLine: {
        lineStyle: {
          width: 3,
          color: [
            [0.25, "#FF6E76"],
            [0.8, "#67c23a"],
            [1, "#FF6E76"],
          ],
        },
      },
      pointer: {
        icon: "path://M12.8,0.7l12,40.1H0.7L12.8,0.7z",
        length: "12%",
        width: 20,
        offsetCenter: [0, "-60%"],
        itemStyle: {
          color: "auto",
        },
      },
      axisTick: {
        length: 0,
        lineStyle: {
          color: "auto",
          width: 2,
        },
      },
      splitLine: {
        length: 0,
        lineStyle: {
          color: "auto",
          width: 5,
        },
      },
      axisLabel: {
        color: "#464646",
        fontSize: 20,
        distance: -60,
        rotate: "tangential",
        show: false,
      },
      title: {
        offsetCenter: [0, "50%"],
        fontSize: 12,
      },
      detail: {
        fontSize: 20,
        offsetCenter: [0, 0],
        valueAnimation: true,
        formatter: function (value) {
          return Math.round(value * 100) + "";
        },
        color: "inherit",
      },
      data: [
        {
          value: 0.7,
          name: "压差",
        },
      ],
    },
  ],
};
const indicatorOneInstance = ref();
const indicatorTwoInstance = ref();
const indicatorFun = (target, domId, option) => {
  if (target.value && target.dispose) {
    target.value.dispose();
  }
  target.value = echarts.init(document.getElementById(domId));
  target.value.setOption(option);
};
const dusterList = ref([]);
// 获取除尘器名称枚举值
const getDusterNameEnum = () => {
  const url = "/bag/cycle/getDusterList";
  getDataFun(url, {})
    .then((res) => {
      dusterList.value = (res && res.data) || [];
      // 判断除尘器名称是否有值
      form.dusterNo = route.query.dusterNo || dusterList.value[0].dusterNo;
    })
    .catch(() => {
      dusterList.value = [];
    });
};
// 获取健康度指数
const getHealthIndex = () => {
  if (!form.dusterNo) {
    return;
  }
  const url = "/dusterStatusMonitor/healthIndexCurve";
  const params = {
    customerId: userStore.customerId,
    deviceNo: form.dusterNo,
    startTime: moment(form.dateValue[0]).format("YYYY-MM-DD") + " 00:00:00",
    endTime: moment(form.dateValue[1]).format("YYYY-MM-DD") + " 23:59:59",
  };
  getDataFun(url, params).then((res) => {
    if (res && res.data) {
      const xData = [];
      const seriesData = [];
      res.data.forEach((item) => {
        xData.push(item.time);
        seriesData.push(item.healthIndex);
      });
      const option = getLineOption2(xData, seriesData, "健康度指数（%）");
      initChart(chartData[0], option, "chart0");
    }
  });
};
// 获取压力差
const getPressure = () => {
  if (!form.dusterNo) {
    return;
  }
  const url = "/dusterStatusMonitor/pressureDiffCurve";
  const params = {
    customerId: userStore.customerId,
    deviceNo: form.dusterNo,
    startTime: moment(form.dateValue[0]).format("YYYY-MM-DD") + " 00:00:00",
    endTime: moment(form.dateValue[1]).format("YYYY-MM-DD") + " 23:59:59",
  };
  getDataFun(url, params).then((res) => {
    if (res && res.data) {
      const xData = [];
      const seriesData = [];
      res.data.forEach((item) => {
        xData.push(item.time);
        seriesData.push(item.pressureDiff);
      });
      const option = getLineOption2(xData, seriesData, "压力差（kpa）");
      initChart(chartData[1], option, "chart1");
    }
  });
};
// 获取能耗
const getEnergy = () => {
  if (!form.dusterNo) {
    return;
  }
  const url = "/dusterStatusMonitor/energyConsumptionCurve";
  const params = {
    customerId: userStore.customerId,
    deviceNo: form.dusterNo,
    startTime: moment(form.dateValue[0]).format("YYYY-MM-DD") + " 00:00:00",
    endTime: moment(form.dateValue[1]).format("YYYY-MM-DD") + " 23:59:59",
  };
  getDataFun(url, params).then((res) => {
    if (res && res.data) {
      const xData = [];
      const seriesData = [];
      res.data.forEach((item) => {
        xData.push(item.time);
        seriesData.push(item.energyConsumption);
      });
      const option = getLineOption2(xData, seriesData, "能耗（kwh）");
      initChart(chartData[2], option, "chart2");
    }
  });
};
const detailObj = reactive({
  bachflushCompart: "",
  leakageCompart: "",
  faultCompart: "",
  compartHealthList: [],
});
const healthPercent = ref();
// 获取除尘器详情
const getDustDetail = () => {
  if (!form.dusterNo) {
    return;
  }
  const url = "/dusterStatusMonitor/dusterDetail";
  const params = {
    customerId: userStore.customerId,
    deviceNo: form.dusterNo,
    startTime: moment(form.dateValue[0]).format("YYYY-MM-DD") + " 00:00:00",
    endTime: moment(form.dateValue[1]).format("YYYY-MM-DD") + " 23:59:59",
  };
  getDataFun(url, params)
    .then((res) => {
      if (res && res.data) {
        for (let i = 0; i < dustInfo.length; i++) {
          dustInfo[i].value = res.data[dustInfo[i].key] || 0;
          dustInfo[i].unit = "个";
          (dustInfo[i].unitKey &&
            (dustInfo[i].unit = res.data[dustInfo[i].unitKey])) ||
            "个";
        }
      } else {
        dustInfo.forEach((item) => {
          item.value = 0;
        });
      }
      detailObj.bachflushCompart =
        (res.data && res.data.bachflushCompart) || "";
      detailObj.leakageCompart = (res.data && res.data.leakageCompart) || "";
      detailObj.faultCompart = (res.data && res.data.faultCompart) || "";
      detailObj.compartHealthList = (res.data &&
        res.data.compartHealthList) || [
        [
          {
            compartNo: "1",
            healthStatus: 1,
            sort: 1,
          },
          {
            compartNo: "2",
            healthStatus: 1,
            sort: 2,
          },
          {
            compartNo: null,
            healthStatus: 1,
            sort: 3,
          },
          {
            compartNo: null,
            healthStatus: 1,
            sort: 4,
          },
          {
            compartNo: null,
            healthStatus: 1,
            sort: 5,
          },
          {
            compartNo: null,
            healthStatus: 1,
            sort: 6,
          },
          {
            compartNo: null,
            healthStatus: 1,
            sort: 7,
          },
          {
            compartNo: null,
            healthStatus: 1,
            sort: 8,
          },
          {
            compartNo: null,
            healthStatus: 1,
            sort: 9,
          },
          {
            compartNo: null,
            healthStatus: 1,
            sort: 10,
          },
          {
            compartNo: null,
            healthStatus: 1,
            sort: 11,
          },
          {
            compartNo: null,
            healthStatus: 1,
            sort: 12,
          },
        ],
      ];
      indicatorFun(
        indicatorOneInstance,
        "indicatorOne",
        getGaugeOption({
          value: dustInfo[0].value.toFixed(2),
          chartName: "压差",
          min: parseInt(res.data.pressureDiffLow),
          max: parseInt(res.data.pressureDiffHigh),
          formatter:
            parseInt(res.data.pressureDiffHigh) > 10
              ? function (value) {
                  return parseInt(value);
                }
              : "",
        })
      );
      indicatorFun(
        indicatorTwoInstance,
        "indicatorTwo",
        getGaugeOption({
          value: parseInt(dustInfo[1].value),
          chartName: "粉尘浓度",
          min: 5,
          max: 50,
          formatter: function (value) {
            return parseInt(value);
          },
        })
      );
      healthPercent.value = parseFloat(res.data.healthPercent);
    })
    .catch(() => {
      dustInfo.forEach((item) => {
        item.value = 0;
      });
      healthPercent.value = 0;
    });
};
const closedLoopInfoList = ref([]);
const warnInfoList = ref([]);
const toWarnDetail = () => {
  router.push({
    path: "/alerts",
    query: {
      dusterNo: form.dusterNo,
      deviceName: dusterName.value,
      suspendStartTime: form.dateValue[0],
      suspendEndTime: form.dateValue[1],
    },
  });
};
const toCircleDetail = () => {
  router.push({
    path: "/my-loop/myAgency",
    query: {
      dusterNo: form.dusterNo,
      deviceName: dusterName.value,
      suspendStartTime: form.dateValue[0],
      suspendEndTime: form.dateValue[1],
    },
  });
};
// 获取告警信息
const getAlarmInfo = () => {
  if (!form.dusterNo) {
    return;
  }
  const url = "/dusterStatusMonitor/warnAndClosedLoopInfo";
  const params = {
    customerId: userStore.customerId,
    deviceNo: form.dusterNo,
    startTime: moment(form.dateValue[0]).format("YYYY-MM-DD") + " 00:00:00",
    endTime: moment(form.dateValue[1]).format("YYYY-MM-DD") + " 23:59:59",
  };
  getDataFun(url, params)
    .then((res) => {
      closedLoopInfoList.value =
        (res && res.data && res.data.closedLoopInfoList) || [];
      warnInfoList.value = (res && res.data && res.data.warnInfoList) || [];
    })
    .catch(() => {
      closedLoopInfoList.value = [];
      warnInfoList.value = [];
    });
};
const resizeFun = () => {
  indicatorOneInstance && indicatorOneInstance.value.resize();
  indicatorTwoInstance && indicatorTwoInstance.value.resize();
  Object.keys(chartInstance).forEach((key) => {
    chartInstance[key] && chartInstance[key].resize();
  });
};
onMounted(() => {
  getDusterNameEnum();
  window.addEventListener("resize", resizeFun);
});
onUnmounted(() => {
  window.removeEventListener("resize", resizeFun);
  chartRemoveEvent();
});
watch(
  () => form.dusterNo,
  () => {
    getHealthIndex();
    getPressure();
    getEnergy();
    getDustDetail();
    getAlarmInfo();
  }
);
watch(
  () => form.dateValue,
  () => {
    getHealthIndex();
    getPressure();
    getEnergy();
    getDustDetail();
    getAlarmInfo();
  }
);
const dusterName = computed(() => {
  return dusterList.value.find((item) => item.dusterNo == form.dusterNo)
    ?.dusterName;
});
const handleStatusDotClick = () => {
  router.push({
    path: "/bag-monitor",
    query: {
      dusterNo: form.dusterNo,
      dusterName: dusterName.value,
    },
  });
};
</script>
<style lang="scss" scoped>
$borderColor: #bbbdc391;
.dust-box {
  width: 100%;
  height: calc(100% - 14px);
  box-sizing: border-box;
  padding: 1rem;
  overflow: hidden;
  overflow: auto;
  display: flex;
  flex-direction: column;
}
.top-box {
  padding-top: 18px;
  padding-left: 10px;
  background: #fff;
  border-radius: 6px;
  box-shadow: 0px 3px 6px 0px rgba(13, 15, 18, 0.1);
  margin-bottom: 1rem;
}
.left-box {
  width: 50%;
  .part1 {
    border-radius: 6px;
    border: 1px solid rgba(13, 15, 18, 0.1);
    box-shadow: 0px 3px 6px 0px rgba(13, 15, 18, 0.1);
    width: 100%;
    height: 63vh;
    background: #fff;
    .chart-box {
      width: 100%;
      height: 31%;
      .chart-item {
        width: 100%;
        height: 100%;
      }
    }
  }
}
.right-box {
  width: 50%;

  .part1 {
    width: 100%;
    height: 5vh;
    border-radius: 6px;
    border: 1px solid rgba(13, 15, 18, 0.1);
    box-shadow: 0px 3px 6px 0px rgba(13, 15, 18, 0.1);
    background: #fff;
    padding: 1%;
    box-sizing: border-box;
    .battery {
      width: 100%;
      height: calc(100%);
    }
  }
  .part2 {
    margin-top: 10px;
    width: 100%;
    height: calc(58vh - 10px);
    border-radius: 6px;
    border: 1px solid rgba(13, 15, 18, 0.1);
    box-shadow: 0px 3px 6px 0px rgba(13, 15, 18, 0.1);
    overflow: hidden;
    overflow-y: auto;
    padding: 20px;
    box-sizing: border-box;
    background: #fff;
    position: relative;
    .dust-title {
      text-align: center;
      font-size: 20px;
      font-weight: 600;
      padding-bottom: 20px;
      border-bottom: 1px solid $borderColor;
      width: 100%;
    }
    .dust-info {
      padding: 0.5rem 1rem;
      background: #e7eef5;
      border-radius: 8px;
      margin: 20px 0;
      display: flex;
      flex-wrap: wrap;
      gap: 0 10px;
    }
    .info-item {
      padding: 3px 0;
      width: calc(50% - 5px);
      box-sizing: border-box;
      margin: 0.5rem 0;
      padding: 0.4rem 0.6rem;
      background: white;
      border-radius: 6px;
      height: 35px;
      font-size: 14px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      .label {
        color: #4e5058;
      }
    }
    .indicator-box {
      display: flex;
      align-items: center;
      justify-content: space-between;
      .indicator-item {
        width: 50%;
        height: 200px;
      }
    }
    .position-info {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 40px 20px 20px 20px;
      .left,
      .right {
        padding: 5px;
        width: 100%;
        flex-wrap: wrap;
        // box-shadow: 0 9px 20px 0 rgba(164, 162, 171, 0.842);
        box-shadow: color(srgb 0.360784 0.788235 0.654902 / 0.5) 0px 0px 20px
          0px;
        // box-shadow: 0px 0px 10px 0px rgba(164, 162, 171, 0.842);
      }
      .part {
        display: flex;
        align-items: center;
        justify-content: space-around;
      }
      .point {
        width: 20px;
        margin: 10px;
        border-radius: 50%;
        display: inline-block;
        cursor: pointer;
      }
      .point::after {
        content: "";
        display: block;
        padding-bottom: 100%; /* 9/16 * 100% = 56.25% */
      }
      .status-normal {
        background-color: #67c23a; // 绿色
      }

      .status-warning {
        background-color: #e6a23c; // 橙色
      }

      .status-error {
        background-color: #f56c6c; // 红色
      }
    }
    .other-info {
      padding: 20px;
      border-top: 1px solid $borderColor;
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 10px;
      &-item {
        padding: 10px;
        height: 70px;
        background: #e7eef5;
        border-radius: 6px;
        flex: 1;
        overflow-y: auto;
      }
      &-item::-webkit-scrollbar {
        width: 0;
      }
      .label {
        color: #4e5058;
      }
      .value {
      }
    }
  }
  .part2::-webkit-scrollbar {
    width: 2px;
    background-color: rgba(13, 15, 18, 0.1);
  }
}
.warn-info {
  margin-top: 20px;
  height: 17vh;
  border-radius: 6px;
  box-shadow: 0px 3px 6px 0px rgba(13, 15, 18, 0.1);
  padding: 10px 30px;
  background: #fff;
}
.layout1 {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex: 1;
}
.layout2 {
  display: flex;
  justify-content: space-between;
  flex-direction: column;
}
.layout3 {
  display: flex;
  align-items: center;
  justify-content: space-around;
  flex-direction: column;
}
</style>
