<template>
  <div class="pcs-ems-dashboard-editor-container">
    <div class="pcs-tags">
      <el-tag
          size="small"
          :type="selectedPcsId ? 'info' : 'primary'"
          :effect="selectedPcsId ? 'plain' : 'dark'"
          class="pcs-tag-item"
          @click="handleTagClick('')"
      >
        全部
      </el-tag>
      <el-tag
          v-for="(item, index) in pcsDeviceList"
          :key="index + 'pcsTag'"
          size="small"
          :type="selectedPcsId === (item.deviceId || item.id) ? 'primary' : 'info'"
          :effect="selectedPcsId === (item.deviceId || item.id) ? 'dark' : 'plain'"
          class="pcs-tag-item"
          @click="handleTagClick(item.deviceId || item.id || '')"
      >
        {{ item.deviceName || item.deviceId || item.id || 'PCS' }}
      </el-tag>
    </div>
    <div
        v-for="(pcsItem, pcsIndex) in filteredPcsList"
        :key="pcsIndex + 'PcsHome'"
        style="margin-bottom: 25px"
    >
      <el-card
          :class="handleCardClass(pcsItem)"
          class="sbjk-card-container common-card-container-body-no-padding common-card-container-no-title-bg"
          shadow="always"
      >
        <div slot="header">
          <span class="large-title"
          >{{ pcsItem.deviceName }}</span
          >
          <div class="info">
            <div>
              {{ (($store.state.ems && $store.state.ems.communicationStatusOptions) || {})[pcsItem.communicationStatus] || '-' }}
            </div>
            <div>数据更新时间：{{ pcsItem.dataUpdateTime }}</div>
          </div>
          <div class="alarm">
            <el-badge :hidden="!pcsItem.alarmNum" :value="pcsItem.alarmNum || 0" class="item">
              <i
                  class="el-icon-message-solid alarm-icon"
                  @click="pointDetail(pcsItem,'alarmPoint')"
              ></i>
            </el-badge>
          </div>
        </div>
        <div class="descriptions-main">
          <el-descriptions :colon="false" :column="4" direction="vertical">
            <el-descriptions-item
                contentClassName="descriptions-direction work-status"
                :span="1"
                label="工作状态"
                labelClassName="descriptions-label"
            >{{ formatDictValue((PCSWorkStatusOptions || {}), pcsItem.workStatus) }}
            </el-descriptions-item
            >
            <el-descriptions-item
                :span="1"
                contentClassName="descriptions-direction"
                label="并网状态"
                labelClassName="descriptions-label"
            >{{ formatDictValue((($store.state.ems && $store.state.ems.gridStatusOptions) || {}), pcsItem.gridStatus) }}
            </el-descriptions-item
            >
            <el-descriptions-item
                :contentClassName="`descriptions-direction ${
                pcsItem.deviceStatus === '1' ? 'save' : 'danger'
              }`"
                :span="1"
                label="设备状态"
                labelClassName="descriptions-label"
            >{{ formatDictValue((($store.state.ems && $store.state.ems.deviceStatusOptions) || {}), pcsItem.deviceStatus) }}
            </el-descriptions-item
            >
            <el-descriptions-item
                :span="1"
                contentClassName="descriptions-direction"
                label="控制模式"
                labelClassName="descriptions-label"
            >{{ formatDictValue((($store.state.ems && $store.state.ems.controlModeOptions) || {}), pcsItem.controlMode) }}
            </el-descriptions-item
            >
          </el-descriptions>
        </div>
        <div class="descriptions-main descriptions-main-bg-color">
          <el-descriptions
              :colon="false"
              :column="4"
              contentClassName="descriptions-direction"
              direction="vertical"
              labelClassName="descriptions-label"
          >
            <el-descriptions-item
                v-for="(item, index) in infoData"
                :key="index + 'pcsInfoData'"
                :label="item.label"
                :span="1"
            >
              <span
                  class="pointer"
                  @click="
                  showChart(item.pointName || '', pcsItem.deviceId)
                "
              >
                <i v-if="isPointLoading(pcsItem[item.attr])" class="el-icon-loading point-loading-icon"></i>
                <span v-else>{{ displayValue(pcsItem[item.attr]) | formatNumber }}</span>
                <span v-if="item.unit" v-html="item.unit"></span>
              </span>
            </el-descriptions-item>
          </el-descriptions>
        </div>
        <div
            v-for="(item, index) in pcsItem.pcsBranchInfoList"
            :key="index + 'pcsBranchInfoList'"
            class="descriptions-main"
        >
          <el-descriptions
              :colon="false"
              :column="4"
              contentClassName="descriptions-direction keep"
              direction="vertical"
              labelClassName="descriptions-label"
          >
            <el-descriptions-item
                :label="'支路' + (index + 1)"
                :span="4"
                contentClassName="descriptions-direction keep"
                labelClassName="descriptions-label"
            >{{ item.dischargeStatus }}
            </el-descriptions-item
            >
            <el-descriptions-item
                :span="1"
                contentClassName="descriptions-direction"
                label="直流功率"
                labelClassName="descriptions-label"
            >
              <span
                  class="pointer"
                  @click="showChart('直流功率', item.deviceId,true)"
              >{{ item.dcPower }}kW</span
              >
            </el-descriptions-item>
            <el-descriptions-item
                :span="1"
                contentClassName="descriptions-direction"
                label="直流电压"
                labelClassName="descriptions-label"
            >
              <span
                  class="pointer"
                  @click="showChart('直流电压', item.deviceId,true)"
              >{{ item.dcVoltage }}V</span
              >
            </el-descriptions-item>
            <el-descriptions-item
                :span="1"
                contentClassName="descriptions-direction"
                label="直流电流"
                labelClassName="descriptions-label"
            >
              <span
                  class="pointer"
                  @click="showChart('直流电流',  item.deviceId,true)"
              >{{ item.dcCurrent }}A</span
              >
            </el-descriptions-item>
          </el-descriptions>
        </div>
      </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 getQuerySiteId from "@/mixins/ems/getQuerySiteId";
import {getPcsNameList, getProjectDisplayData} from "@/api/ems/dzjk";
import intervalUpdate from "@/mixins/ems/intervalUpdate";
import {mapState} from "vuex";

export default {
  name: "DzjkSbjkPcs",
  components: {pointChart, PointTable},
  mixins: [getQuerySiteId, intervalUpdate],
  computed: {
    ...mapState({
      PCSWorkStatusOptions: state => state?.ems?.PCSWorkStatusOptions || {},
    }),
    filteredPcsList() {
      if (!this.selectedPcsId) {
        return this.pcsList || [];
      }
      return (this.pcsList || []).filter(item => item.deviceId === this.selectedPcsId);
    },
  },
  data() {
    return {
      loading: false,
      displayData: [],
      pcsDeviceList: [],
      selectedPcsId: "",
      pcsList: [{
        deviceId: "",
        deviceName: "PCS",
        dataUpdateTime: "-",
        alarmNum: 0,
        pcsBranchInfoList: [],
      }],
      infoData: [
        {
          label: "总交流有功功率",
          attr: "totalActivePower",
          unit: "kW",
          pointName: "总交流有功功率",
        },
        {
          label: "当天交流充电量",
          attr: "dailyAcChargeEnergy",
          unit: "kWh",
          pointName: "当天交流充电量 (kWh)",
        },
        {label: "A相电压", attr: "aPhaseVoltage", unit: "V", pointName: ""},
        {
          label: "A相电流",
          attr: "aPhaseCurrent",
          unit: "A",
          pointName: "A相电流",
        },
        {
          label: "总交流无功功率",
          attr: "totalReactivePower",
          unit: "kVar",
          pointName: "总交流无功功率",
        },
        {
          label: "当天交流放电量",
          attr: "dailyAcDischargeEnergy",
          unit: "kWh",
          pointName: "当天交流放电量 (kWh)",
        },
        {label: "B相电压", attr: "bPhaseVoltage", unit: "V", pointName: ""},
        {
          label: "B相电流",
          attr: "bPhaseCurrent",
          unit: "A",
          pointName: "B相电流",
        },
        {
          label: "总交流视在功率",
          attr: "totalApparentPower",
          unit: "kVA",
          pointName: "总交流视在功率",
        },
        {
          label: "PCS模块温度",
          attr: "pcsModuleTemperature",
          unit: "&#8451;",
          pointName: "",
        },
        {label: "C相电压", attr: "cPhaseVoltage", unit: "V", pointName: ""},
        {
          label: "C相电流",
          attr: "cPhaseCurrent",
          unit: "A",
          pointName: "C相电流",
        },
        {
          label: "总交流功率因数",
          attr: "totalPowerFactor",
          unit: "",
          pointName: "总交流功率因数",
        },
        {
          label: "PCS环境温度",
          attr: "pcsEnvironmentTemperature",
          unit: "&#8451;",
          pointName: "",
        },
        {
          label: "交流频率",
          attr: "acFrequency",
          unit: "Hz",
          pointName: "交流频率",
        },
      ],
    };
  },
  methods: {
    displayValue(value) {
      return value === undefined || value === null || value === "" ? "-" : value;
    },
    isPointLoading(value) {
      return this.loading && (value === undefined || value === null || value === "" || value === "-");
    },
    normalizeDictKey(value) {
      const raw = String(value == null ? "" : value).trim();
      if (!raw) return "";
      if (/^-?\d+(\.0+)?$/.test(raw)) {
        return String(parseInt(raw, 10));
      }
      return raw;
    },
    formatDictValue(options, value) {
      const dict = (options && typeof options === "object") ? options : {};
      const key = this.normalizeDictKey(value);
      if (!key) return "-";
      return dict[key] || key;
    },
    normalizeDeviceId(value) {
      return String(value == null ? "" : value).trim().toUpperCase();
    },
    handleCardClass(item) {
      const workStatus = this.normalizeDictKey((item && item.workStatus) || "");
      const statusOptions = (this.PCSWorkStatusOptions && typeof this.PCSWorkStatusOptions === 'object')
        ? this.PCSWorkStatusOptions
        : {};
      const hasStatus = Object.prototype.hasOwnProperty.call(statusOptions, workStatus);
      return workStatus === '1' || !hasStatus
        ? "timing-card-container"
        : workStatus === '2'
          ? 'warning-card-container'
          : 'running-card-container';
    },
    // 查看设备电位表格
    pointDetail(row, dataType) {
      const {deviceId} = row
      this.$refs.pointTable.showTable({siteId: this.siteId, deviceId, deviceCategory: 'PCS'}, dataType)
    },
    showChart(pointName, deviceId, isBranch = false) {
      pointName &&
      this.$refs.pointChart.showChart({pointName, deviceCategory: isBranch ? 'BRANCH' : 'PCS', deviceId});
    },
    handleTagClick(deviceId) {
      this.selectedPcsId = deviceId || "";
    },
    getModuleRows(menuCode, sectionName) {
      return (this.displayData || []).filter(item => item.menuCode === menuCode && item.sectionName === sectionName);
    },
    getFieldName(fieldCode) {
      if (!fieldCode) {
        return "";
      }
      const index = fieldCode.lastIndexOf("__");
      return index >= 0 ? fieldCode.slice(index + 2) : fieldCode;
    },
    getFieldMap(rows = [], deviceId = "") {
      const map = {};
      const targetDeviceId = this.normalizeDeviceId(deviceId || "");
      // 设备维度优先：先吃 device_id 对应值，再用默认值(空 device_id)补齐
      rows.forEach(item => {
        if (!item || !item.fieldCode) {
          return;
        }
        const itemDeviceId = this.normalizeDeviceId(item.deviceId || "");
        if (itemDeviceId !== targetDeviceId) {
          return;
        }
        map[this.getFieldName(item.fieldCode)] = item.fieldValue;
      });
      rows.forEach(item => {
        if (!item || !item.fieldCode) {
          return;
        }
        const itemDeviceId = this.normalizeDeviceId(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())}`;
    },
    getPcsDeviceList() {
      return getPcsNameList(this.siteId).then((response) => {
        this.pcsDeviceList = response?.data || [];
      }).catch(() => {
        this.pcsDeviceList = [];
      });
    },
    buildPcsList() {
      const devices = (this.pcsDeviceList && this.pcsDeviceList.length > 0)
        ? this.pcsDeviceList
        : [{deviceId: this.siteId, deviceName: 'PCS'}];
      this.pcsList = devices.map((device) => ({
        ...this.getFieldMap(this.getModuleRows('SBJK_PCS', '电参量'), device.deviceId || device.id || this.siteId),
        deviceId: device.deviceId || device.id || this.siteId,
        deviceName: device.deviceName || device.name || device.deviceId || device.id || 'PCS',
        ...this.getFieldMap(this.getModuleRows('SBJK_PCS', '状态'), device.deviceId || device.id || this.siteId),
        dataUpdateTime: this.getLatestTime('SBJK_PCS'),
        alarmNum: 0,
        pcsBranchInfoList: [],
      }));
    },
    updateData() {
      this.loading = true;
      // 先渲染卡片框架，字段值走单点位 loading
      this.buildPcsList();
      Promise.all([
        getProjectDisplayData(this.siteId),
        this.getPcsDeviceList(),
      ]).then(([displayResponse]) => {
        this.displayData = displayResponse?.data || [];
        this.buildPcsList();
      }).finally(() => (this.loading = false));
    },
    init() {
      this.updateData();
      this.updateInterval(this.updateData);
    },
  },
};
</script>
<style lang="scss" scoped>
.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;
}

.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>
