<template>
  <div>
    <div class="pcs-tags">
      <el-tag
        size="small"
        :type="selectedClusterId ? 'info' : 'primary'"
        :effect="selectedClusterId ? 'plain' : 'dark'"
        class="pcs-tag-item"
        @click="handleTagClick('')"
      >
        全部
      </el-tag>
      <el-tag
        v-for="(item, index) in clusterDeviceList"
        :key="index + 'clusterTag'"
        size="small"
        :type="selectedClusterId === (item.deviceId || item.id) ? 'primary' : 'info'"
        :effect="selectedClusterId === (item.deviceId || item.id) ? 'dark' : 'plain'"
        class="pcs-tag-item"
        @click="handleTagClick(item.deviceId || item.id || '')"
      >
        {{ item.deviceName || item.name || item.deviceId || item.id || 'BMS电池簇' }}
      </el-tag>
    </div>
    <div v-for="(baseInfo,index) in filteredBaseInfoList" :key="index+'bmsdccContainer'" style="margin-bottom:25px;">
      <el-card shadow="always"
               class="sbjk-card-container common-card-container-body-no-padding common-card-container-no-title-bg"
               :class="handleCardClass(baseInfo)">
        <div slot="header">
          <span
              class="large-title">{{
              baseInfo.parentDeviceName ? `${baseInfo.parentDeviceName} -> ` : ''
            }}{{ baseInfo.deviceName }}</span>
          <div class="info">
            <div>数据更新时间：{{ baseInfo.dataUpdateTime || '-' }}</div>
          </div>
          <div class="alarm">
            <el-button type="primary" round size="small" style="margin-right:20px;"
                       @click="pointDetail(baseInfo,'point')">详细
            </el-button>
            <el-badge :hidden="!baseInfo.alarmNum" :value="baseInfo.alarmNum || 0" class="item">
              <i
                  class="el-icon-message-solid alarm-icon"
                  @click="pointDetail(baseInfo,'alarmPoint')"
              ></i>
            </el-badge>
          </div>
        </div>
        <div class="descriptions-main">
          <el-descriptions direction="vertical" :column="3" :colon="false">
            <el-descriptions-item
                contentClassName="descriptions-direction work-status"
                :span="1" label="工作状态">
              {{ CLUSTERWorkStatusOptions[baseInfo.workStatus] || '-' }}
            </el-descriptions-item>
            <el-descriptions-item contentClassName="descriptions-direction"
                                  :span="1" label="与PCS通信">
              {{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[baseInfo.pcsCommunicationStatus] || '-' }}
            </el-descriptions-item>
            <el-descriptions-item contentClassName="descriptions-direction"
                                  :span="1" label="与EMS通信">
              {{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[baseInfo.emsCommunicationStatus] || '-' }}
            </el-descriptions-item>
          </el-descriptions>
        </div>
        <div class="descriptions-main descriptions-main-bg-color">
          <el-descriptions direction="vertical" :column="3" :colon="false">
            <el-descriptions-item labelClassName="descriptions-label" contentClassName="descriptions-direction"
                                  v-for="(item,index) in infoData" :key="index+'pcsInfoData'" :span="1"
                                  :label="item.label">
                <span class="pointer" @click="showChart(item.pointName || '',baseInfo.deviceId)">
                <i v-if="isPointLoading(baseInfo[item.attr])" class="el-icon-loading point-loading-icon"></i>
                <span v-else>{{ displayValue(baseInfo[item.attr]) | formatNumber }}</span>
                <span v-if="item.unit" v-html="item.unit"></span>
              </span>
            </el-descriptions-item>
          </el-descriptions>
          <!--        进度-->
          <div class="process-container">
            <div class="process-line-bg">
              <div class="process-line" :style="{height:baseInfo.currentSoc+'%'}"></div>
            </div>
            <div class="process pointer" @click="showChart( '当前SOC',baseInfo.deviceId)">当前SOC :
              {{ baseInfo.currentSoc }}%
            </div>
          </div>
        </div>
        <el-table
            class="common-table"
            :data="baseInfo.batteryDataList"
            stripe
            style="width: 100%;margin-top:25px;">
          <el-table-column
              prop="dataName"
              label="名称">
            <template slot-scope="scope">
              <span v-html="scope.row.dataName+'（'+unitObj[scope.row.dataName]+'）'"></span>
            </template>
          </el-table-column>
          <el-table-column
              prop="avgData"
              label="单体平均值"
          >
            <template slot-scope="scope">
              <span class="pointer"
                    @click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{
                  scope.row.avgData
                }}</span>
            </template>
          </el-table-column>
          <el-table-column
              prop="minData"
              label="单体最小值">
            <template slot-scope="scope">
              <span class="pointer"
                    @click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{
                  scope.row.minData
                }}</span>
            </template>
          </el-table-column>
          <el-table-column
              prop="minDataID"
              label="单体最小值ID">
          </el-table-column>
          <el-table-column
              prop="maxData"
              label="单体最大值">
            <template slot-scope="scope">
              <span class="pointer "
                    @click="showChart( tablePointNameMap[scope.row.dataName+scope.column.label],baseInfo.deviceId)">{{
                  scope.row.maxData
                }}</span>
            </template>
          </el-table-column>
          <el-table-column
              prop="maxDataID"
              label="单体最大值ID">
          </el-table-column>
        </el-table>
      </el-card>
    </div>
    <point-chart ref="pointChart" :site-id="siteId"/>
    <point-table ref="pointTable"/>
  </div>

</template>

<script>
import pointChart from "./../PointChart.vue";
import PointTable from "@/views/ems/site/sblb/PointTable.vue";
import {getProjectDisplayData, getStackNameList, getClusterNameList} from '@/api/ems/dzjk'
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
import intervalUpdate from "@/mixins/ems/intervalUpdate";
import {mapState} from "vuex";

export default {
  name: 'DzjkSbjkBmsdcc',
  mixins: [getQuerySiteId, intervalUpdate],
  components: {PointTable, pointChart},
  computed: {
    ...mapState({
      CLUSTERWorkStatusOptions: state => state?.ems?.CLUSTERWorkStatusOptions || {},
    }),
    filteredBaseInfoList() {
      if (!this.selectedClusterId) {
        return this.baseInfoList || [];
      }
      return (this.baseInfoList || []).filter(item => item.deviceId === this.selectedClusterId);
    },
  },
  data() {
    return {
      loading: false,
      displayData: [],
      clusterDeviceList: [],
      selectedClusterId: "",
      unitObj: {
        '电压': 'V',
        '温度': '&#8451;',
        'SOC': '%'
      },
      tablePointNameMap: {
        '电压单体最小值': '最低单体电压',
        '电压单体平均值': '电压平均值',
        '电压单体最大值': '最高单体电压',
        '温度单体最小值': '最低单体温度',
        '温度单体平均值': '平均单体温度',
        '温度单体最大值': '最高单体温度',
        'SOC单体最小值': '最低单体SOC',
        'SOC单体平均值': '当前SOC',
        'SOC单体最大值': '最高单体SOC',
      },
      baseInfoList: [{
        siteId: "",
        deviceId: "",
        parentDeviceName: "",
        deviceName: "BMS电池簇",
        dataUpdateTime: "-",
        alarmNum: 0,
        batteryDataList: [],
      }],
      infoData: [
        {label: '簇电压', attr: 'clusterVoltage', unit: 'V', pointName: '簇电压'},
        {label: '可充电量', attr: 'chargeableCapacity', unit: 'kWh', pointName: '可充电量'},
        {label: '累计充电量', attr: 'totalChargedCapacity', unit: 'kWh', pointName: '累计充电量'},
        {label: '簇电流', attr: 'clusterCurrent', unit: 'A', pointName: '簇电流'},
        {label: '可放电量', attr: 'dischargeableCapacity', unit: 'kWh', pointName: '可放电量'},
        {label: '累计放电量', attr: 'totalDischargedCapacity', unit: 'kWh', pointName: '累计放电量'},
        {label: 'SOH', attr: 'soh', unit: '%', pointName: 'SOH'},
        {label: '平均温度', attr: 'averageTemperature', unit: '&#8451;', pointName: '平均温度'},
        {label: '绝缘电阻', attr: 'insulationResistance', unit: '&Omega;', pointName: '绝缘电阻'},
      ],
    }
  },
  methods: {
    displayValue(value) {
      return value === undefined || value === null || value === "" ? "-" : value;
    },
    isPointLoading(value) {
      return this.loading && (value === undefined || value === null || value === "" || value === "-");
    },
    handleCardClass(item) {
      const {workStatus = ''} = item
      return !(Object.keys(this.CLUSTERWorkStatusOptions).includes(item.workStatus)) ? "timing-card-container" : workStatus === '9' ? 'warning-card-container' : 'running-card-container'
    },
    // 查看设备电位表格
    pointDetail(row, dataType) {
      const {siteId, deviceId} = row
      this.$refs.pointTable.showTable({siteId, deviceId, deviceCategory: 'CLUSTER'}, dataType)
    },
    showChart(pointName, deviceId) {
      pointName && this.$refs.pointChart.showChart({pointName, deviceCategory: 'CLUSTER', deviceId})
    },
    handleTagClick(deviceId) {
      this.selectedClusterId = deviceId || "";
    },
    init() {
      this.updateData()
      this.updateInterval(this.updateData)
    },
    getModuleRows(menuCode, sectionName) {
      return (this.displayData || []).filter(item => item.menuCode === menuCode && item.sectionName === sectionName);
    },
    getFieldName(fieldCode) {
      const raw = String(fieldCode || "").trim();
      if (!raw) return "";
      const index = raw.lastIndexOf("__");
      return index >= 0 ? raw.slice(index + 2) : raw;
    },
    getFieldMap(rows = [], deviceId = "") {
      const map = {};
      const targetDeviceId = String(deviceId || "");
      rows.forEach(item => {
        if (!item || !item.fieldCode) return;
        const itemDeviceId = String(item.deviceId || "");
        if (itemDeviceId !== targetDeviceId) return;
        map[this.getFieldName(item.fieldCode)] = item.fieldValue;
      });
      rows.forEach(item => {
        if (!item || !item.fieldCode) return;
        const itemDeviceId = String(item.deviceId || "");
        if (itemDeviceId !== "") return;
        const fieldName = this.getFieldName(item.fieldCode);
        if (map[fieldName] === undefined || map[fieldName] === null || map[fieldName] === "") {
          map[fieldName] = item.fieldValue;
        }
      });
      return map;
    },
    getLatestTime(menuCode) {
      const times = (this.displayData || [])
        .filter(item => item.menuCode === menuCode && item.valueTime)
        .map(item => new Date(item.valueTime).getTime())
        .filter(ts => !isNaN(ts));
      if (times.length === 0) {
        return '-';
      }
      const date = new Date(Math.max(...times));
      const p = (n) => String(n).padStart(2, '0');
      return `${date.getFullYear()}-${p(date.getMonth() + 1)}-${p(date.getDate())} ${p(date.getHours())}:${p(date.getMinutes())}:${p(date.getSeconds())}`;
    },
    getClusterDeviceList() {
      return getStackNameList(this.siteId)
        .then(response => {
          const stackList = response?.data || [];
          if (!stackList.length) {
            this.clusterDeviceList = [];
            return;
          }
          const requests = stackList.map(stack => {
            const stackDeviceId = stack.deviceId || stack.id || '';
            return getClusterNameList({stackDeviceId, siteId: this.siteId})
              .then(clusterResponse => {
                const clusterList = clusterResponse?.data || [];
                return clusterList.map(cluster => ({
                  ...cluster,
                  parentDeviceName: stack.deviceName || stack.name || stackDeviceId || '',
                }));
              })
              .catch(() => []);
          });
          return Promise.all(requests).then(results => {
            this.clusterDeviceList = results.flat();
          });
        })
        .catch(() => {
          this.clusterDeviceList = [];
        });
    },
    buildBaseInfoList() {
      const devices = (this.clusterDeviceList && this.clusterDeviceList.length > 0)
        ? this.clusterDeviceList
        : [{deviceId: this.siteId, deviceName: 'BMS电池簇', parentDeviceName: ''}];
      this.baseInfoList = devices.map(device => ({
        ...(() => {
          const id = device.deviceId || device.id || this.siteId;
          const infoMap = this.getFieldMap(this.getModuleRows('SBJK_BMSDCC', '簇信息'), id);
          const statusMap = this.getFieldMap(this.getModuleRows('SBJK_BMSDCC', '状态'), id);
          const currentSoc = Number(infoMap.currentSoc);
          return {
            ...infoMap,
            workStatus: statusMap.workStatus,
            pcsCommunicationStatus: statusMap.pcsCommunicationStatus,
            emsCommunicationStatus: statusMap.emsCommunicationStatus,
            currentSoc: isNaN(currentSoc) ? 0 : currentSoc,
          };
        })(),
        siteId: this.siteId,
        deviceId: device.deviceId || device.id || this.siteId,
        parentDeviceName: device.parentDeviceName || '',
        deviceName: device.deviceName || device.name || device.deviceId || device.id || 'BMS电池簇',
        dataUpdateTime: this.getLatestTime('SBJK_BMSDCC'),
        alarmNum: 0,
        batteryDataList: [],
      }));
    },
    updateData() {
      this.loading = true
      // 先渲染卡片框架，字段值走单点位 loading
      this.buildBaseInfoList();
      Promise.all([
        getProjectDisplayData(this.siteId),
        this.getClusterDeviceList(),
      ]).then(([response]) => {
        this.displayData = response?.data || [];
        this.buildBaseInfoList();
      }).finally(() => {
        this.loading = false
      })
    }
  }
}
</script>

<style scoped lang="scss">
.pcs-tags {
  margin: 0 0 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-start;
  align-items: center;
}

.pcs-tag-item {
  cursor: pointer;
}

::v-deep {
  //描述列表样式
  .descriptions-main {
    padding: 24px 300px 24px 24px;
  }

  .descriptions-main-bottom {
    padding: 14px 300px 14px 24px;
  }
}

//  进度条样式
.process-container {
  width: 100px;
  position: absolute;
  right: 70px;
  top: 50%;
  transform: translateY(-50%);

  .process-line-bg {
    position: relative;
    width: 100%;
    height: 110px;
    background-color: #fff2cb;
    border-radius: 6px;
    box-shadow: 0 0 10px #fff2cb, 0 0 0 rgba(255, 242, 203, 0.5);

    .process-line {
      position: absolute;
      left: 0;
      bottom: 0;
      width: 100%;
      height: 25%;
      background-color: #ffbf14;
      border-radius: 0 0 6px 6px;
      box-shadow: 0 0 10px #ffbf14, 0 0 0 rgba(255, 191, 20, 0.5);
    }
  }

  .process {
    margin-top: 15px;
    color: #666666;
  }
}

.point-loading-icon {
  color: #409eff;
  display: inline-block;
  transform-origin: center;
  animation: pointLoadingSpinPulse 1.1s linear infinite;
}
@keyframes pointLoadingSpinPulse {
  0% { opacity: 0.45; transform: rotate(0deg) scale(0.9); }
  50% { opacity: 1; transform: rotate(180deg) scale(1.08); }
  100% { opacity: 0.45; transform: rotate(360deg) scale(0.9); }
}

</style>
