<template>
  <el-dialog :visible.sync="visible" width="80%" @close="handleClose" title-class="dialog-title">
    <small-title slot="title" :no-padding="true">
      {{ dataForm.lineId + '·' + dataForm.equipmentName }}
    </small-title>
    <search-bar removeBlue :formConfigs="formConfig" ref="searchBarForm" @headBtnClick="buttonClick" />
    <el-tabs class="custom-tabs" v-model="activeLabel" :stretch="true" @tab-click="handleTabClick">
      <el-tab-pane :label="'\u3000报警时长\u3000'" name="duration"></el-tab-pane>
      <el-tab-pane :label="'\u3000报警次数\u3000'" name="times"></el-tab-pane>
    </el-tabs>
    <div class="content">
      <div class="visual-part">
        <div v-if="hasData" style="display: flex; justify-content: space-around; gap: 20px; padding: 10px 0;">
          <!-- 移除 v-if，始终渲染两个图表容器 -->
          <div id="barChart" style="width: 48%; height: 400px;"></div>
          <div id="pieChart" style="width: 48%; height: 400px;"></div>
        </div>
        <div v-if="!hasData" class="no-data">
          <el-empty description="暂无相关报警数据"></el-empty>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script>
import { getAlarmDet } from '@/api/base/equipment';
import * as echarts from 'echarts';
import SmallTitle from './SmallTitle';

const CHART_CONFIG = {
  barColor: '#288AFF',
  pieColors: [
    '#288AFF', '#4096FF', '#69B1FF', '#91CFFF', '#B8E0FF',
    '#E0F2FF', '#1890FF', '#096DD9', '#0050B3', '#003A8C'
  ],
  fontColor: '#333',
  lightFontColor: '#666',
  borderRadius: 4
};

export default {
  components: { SmallTitle },
  data() {
    return {
      visible: false,
      hasData: false,
      listQuery: {
        pageNo: 1,
        pageSize: 100,
        equipmentId: undefined,
        startTime: undefined,
        endTime: undefined
      },
      formConfig: [
        {
          type: 'datePicker',
          label: '时间段',
          dateType: 'daterange',
          format: 'yyyy-MM-dd',
          valueFormat: 'timestamp',
          rangeSeparator: '-',
          startPlaceholder: '开始时间',
          endPlaceholder: '结束时间',
          param: 'timeVal',
          defaultTime: ['00:00:00', '23:59:59'],
          defaultSelect: []
        },
        {
          type: 'button',
          btnName: '查询',
          name: 'search',
          color: 'primary'
        }
      ],
      activeLabel: 'duration', // 默认选中「报警时长」
      dataForm: {
        equipmentId: undefined,
        equipmentName: undefined,
        lineId: undefined
      },
      chartInstances: {
        bar: null,
        pie: null
      },
      isDomReady: false,
      originData: null // 存储原始数据
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.isDomReady = true;
      if (this.listQuery.equipmentId) {
        this.getDataList();
      }
    });
  },
  watch: {
    // Tab 切换时自动刷新图表（无需额外操作，依赖 handleTabClick 触发查询）
    activeLabel() {
      if (this.isDomReady && this.originData) {
        this.$nextTick(() => {
          this.renderBothCharts(); // 切换 Tab 后重新渲染两个图表
        });
      }
    }
  },
  methods: {
    initDefaultDate() {
      const today = new Date();
      const start = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0, 0).getTime();
      const end = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59, 0).getTime();

      this.formConfig[0].defaultSelect = [start, end];
      this.listQuery.startTime = start;
      this.listQuery.endTime = end;

      // 修复点1：增加多层判断，确保对象存在后再赋值
      if (this.$refs.searchBarForm && this.$refs.searchBarForm.form) {
        this.$refs.searchBarForm.form.timeVal = [start, end];
      }
    },

    handleTabClick() {
      // 切换 Tab 时重新查询数据（或直接复用已有数据渲染）
      this.getDataList();
    },

    buttonClick(val) {
      switch (val.btnName) {
        case 'search':
          this.listQuery.startTime = val.timeVal?.[0];
          this.listQuery.endTime = val.timeVal?.[1];
          this.getDataList();
          break;
        default:
      }
    },

    async getDataList() {
      try {
        if (!this.listQuery.equipmentId) {
          console.warn('设备ID不能为空');
          this.hasData = false;
          return;
        }

        const queryParams = {
          equipmentId: this.listQuery.equipmentId,
          startTime: this.listQuery.startTime,
          endTime: this.listQuery.endTime,
        };

        const res = await getAlarmDet(queryParams);
        const originData = res.data || [];
        this.originData = originData;
        this.hasData = originData.length > 0;

        if (this.hasData && this.isDomReady) {
          this.$nextTick(() => {
            this.renderBothCharts(); // 数据查询成功后，同时渲染两个图表
          });
        } else {
          this.destroyAllCharts();
        }
      } catch (error) {
        console.error('获取报警数据失败：', error);
        this.hasData = false;
        this.destroyAllCharts();
      }
    },

    // 核心方法：同时渲染柱状图和饼图（根据当前 Tab 类型）
    renderBothCharts() {
      if (this.activeLabel === 'duration') {
        // 报警时长：柱状图（时长排序）+ 饼图（时长占比）
        this.renderBarChart('duration');
        this.renderPieChart('duration');
      } else {
        // 报警次数：柱状图（次数排序）+ 饼图（次数占比）
        this.renderBarChart('times');
        this.renderPieChart('times');
      }
    },

    // 渲染柱状图（支持两种数据类型）
    renderBarChart(type) {
      this.destroyChart('bar');
      const chartDom = document.getElementById('barChart');
      if (!chartDom || !this.originData.length) return;

      // 根据类型排序和提取数据
      let sortedData, xData, seriesData, yAxisName;
      if (type === 'duration') {
        // 报警时长：按时长降序
        sortedData = [...this.originData].sort((a, b) => b.alarmDuration - a.alarmDuration);
        seriesData = sortedData.map(item => item.alarmDuration);
        yAxisName = '报警时长';
      } else {
        // 报警次数：按次数降序
        sortedData = [...this.originData].sort((a, b) => b.alarmCount - a.alarmCount);
        seriesData = sortedData.map(item => item.alarmCount);
        yAxisName = '报警次数';
      }

      xData = sortedData.map(item => this.truncateText(item.alarmContent, 8));

      try {
        this.chartInstances.bar = echarts.init(chartDom);
        const option = {
          title: {
            text: `${yAxisName}统计（柱状图）`,
            left: 'center',
            textStyle: { fontSize: 14, color: CHART_CONFIG.fontColor }
          },
          tooltip: {
            trigger: 'axis',
            axisPointer: { type: 'shadow' },
            padding: 10,
            textStyle: { fontSize: 11 },
            formatter: (params) => {
              const index = params[0].dataIndex;
              const item = sortedData[index];
              return `
                <div style="text-align: left;">
                  <div>${item.alarmContent}</div>
                  <div>${yAxisName}：${type === 'duration' ? item.alarmDuration : item.alarmCount}</div>
                  <div>占比：${type === 'duration' ? item.alarmDurationRatio.toFixed(2) : item.alarmCountRatio.toFixed(2)}%</div>
                </div>
              `;
            }
          },
          grid: {
            left: '5%',
            right: '5%',
            bottom: '18%',
            top: '15%',
            containLabel: true
          },
          xAxis: [
            {
              type: 'category',
              data: xData,
              axisTick: { alignWithLabel: true },
              axisLabel: {
                interval: 0,
                fontSize: 12,
                color: CHART_CONFIG.lightFontColor
              },
              axisLine: { lineStyle: { color: '#e8e8e8' } }
            }
          ],
          yAxis: [
            {
              type: 'value',
              name: yAxisName,
              nameTextStyle: { fontSize: 11, color: CHART_CONFIG.lightFontColor },
              axisLabel: {
                fontSize: 11,
                color: CHART_CONFIG.lightFontColor,
              },
              axisLine: { lineStyle: { color: '#e8e8e8' } },
              splitLine: { lineStyle: { color: '#f5f5f5' } },
              max: (value) => value.max * 1.2
            }
          ],
          series: [
            {
              name: yAxisName,
              type: 'bar',
              itemStyle: {
                color: CHART_CONFIG.barColor,
                borderRadius: [CHART_CONFIG.borderRadius, CHART_CONFIG.borderRadius, 0, 0],
                shadowBlur: 3,
                shadowColor: 'rgba(40, 138, 255, 0.2)',
                shadowOffsetY: 2
              },
              barWidth: '16',
              data: seriesData,
              label: {
                show: true,
                position: 'top',
                distance: 6,
                fontSize: 11,
                color: CHART_CONFIG.fontColor,
                formatter: (params) => `${params.value}`
              }
            }
          ]
        };

        this.chartInstances.bar.setOption(option);
        this.addResizeListener('bar');
      } catch (error) {
        console.error(`${yAxisName}柱状图初始化失败：`, error);
        setTimeout(() => this.renderBarChart(type), 200);
      }
    },

    // 渲染饼图（支持两种数据类型）
    renderPieChart(type) {
      this.destroyChart('pie');
      const chartDom = document.getElementById('pieChart');
      if (!chartDom || !this.originData.length) return;

      // 根据类型处理饼图数据
      let pieData, seriesName;
      if (type === 'duration') {
        // 报警时长：按时长占比处理
        seriesName = '报警时长';
        pieData = this.handlePieData(this.originData, 'alarmDuration', 'alarmDurationRatio');
      } else {
        // 报警次数：按次数占比处理
        seriesName = '报警次数';
        pieData = this.handlePieData(this.originData, 'alarmCount', 'alarmCountRatio');
      }

      try {
        this.chartInstances.pie = echarts.init(chartDom);
        const option = {
          title: {
            text: `${seriesName}统计（饼图）`,
            left: 'center',
            textStyle: { fontSize: 14, color: CHART_CONFIG.fontColor }
          },
          tooltip: {
            trigger: 'item',
            padding: 10,
            textStyle: { fontSize: 11 },
            formatter: (params) => {
              return `
                <div style="text-align: left;">
                  <div>${params.name}</div>
                  <div>${seriesName}：${params.value}${type === 'duration' ? '' : '次'}</div>
                  <div>占比：${params.percent.toFixed(2)}%</div>
                </div>
              `;
            }
          },
          series: [
            {
              name: seriesName,
              type: 'pie',
              radius: ['50%', '70%'],
              center: ['50%', '55%'],
              color: CHART_CONFIG.pieColors,
              label: {
                show: true,
                position: 'outside',
                distance: 15,
                fontSize: 11,
                color: CHART_CONFIG.lightFontColor,
                formatter: (params) => {
                  const truncatedName = this.truncateText(params.name, 8);
                  return `${truncatedName}(${params.value}${type === 'duration' ? '' : '次'}, ${params.percent.toFixed(1)}%)`;
                },
                align: 'center',
                baseline: 'middle'
              },
              labelLine: {
                show: true,
                length: 15,
                length2: 20,
                lineStyle: {
                  color: '#ccc',
                  width: 1,
                  type: 'solid'
                },
                smooth: 0.2
              },
              data: pieData,
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowColor: 'rgba(0, 0, 0, 0.1)'
                },
                label: {
                  color: CHART_CONFIG.fontColor,
                  fontSize: 12,
                  fontWeight: 500
                },
                labelLine: {
                  lineStyle: {
                    color: CHART_CONFIG.barColor,
                    width: 1.5
                  }
                }
              }
            }
          ]
        };

        this.chartInstances.pie.setOption(option);
        this.addResizeListener('pie');
      } catch (error) {
        console.error(`${seriesName}饼图初始化失败：`, error);
        setTimeout(() => this.renderPieChart(type), 200);
      }
    },

    // 通用饼图数据处理（支持动态字段）
    handlePieData(data, valueKey, ratioKey) {
      const threshold = 5; // 占比低于5%合并为「其他」
      let otherCount = 0;
      const mainData = data.filter(item => {
        if (item[ratioKey] >= threshold) {
          return true;
        } else {
          otherCount += item[valueKey];
          return false;
        }
      }).map(item => ({
        name: item.alarmContent,
        value: item[valueKey],
        ratio: item[ratioKey]
      }));

      if (otherCount > 0) {
        mainData.push({
          name: '其他',
          value: otherCount,
          ratio: 100 - mainData.reduce((sum, item) => sum + item.ratio, 0)
        });
      }

      return mainData;
    },

    truncateText(text, maxLength) {
      if (!text) return '';
      return text.length > maxLength ? text.slice(0, maxLength) + '...' : text;
    },

    addResizeListener(type) {
      const chart = this.chartInstances[type];
      if (chart) {
        const resizeHandler = () => chart.resize();
        window.addEventListener('resize', resizeHandler);
        chart.resizeHandler = resizeHandler;
      }
    },

    destroyChart(type) {
      const chart = this.chartInstances[type];
      if (chart) {
        window.removeEventListener('resize', chart.resizeHandler);
        chart.dispose();
        this.chartInstances[type] = null;
      }
    },

    destroyAllCharts() {
      Object.keys(this.chartInstances).forEach(type => {
        this.destroyChart(type);
      });
    },

    handleClose() {
      this.destroyAllCharts();
      this.formConfig[0].defaultSelect = [];
      this.listQuery.startTime = undefined;
      this.listQuery.endTime = undefined;
      this.originData = null;
      this.hasData = true;
      // 修复点2：增加多层判断，确保对象存在后再赋值
      if (this.$refs.searchBarForm && this.$refs.searchBarForm.form) {
        this.$refs.searchBarForm.form.timeVal = [];
      }
    },

    init(data) {
      this.dataForm = {
        equipmentId: data.equipmentId || '',
        equipmentName: data.equipmentName || '',
        lineId: data.lineId || ''
      };
      this.activeLabel = 'duration'
      this.listQuery.equipmentId = data.equipmentId || undefined;
      this.visible = true;
      this.originData = null;
      this.hasData = false;

      this.initDefaultDate();

      this.$nextTick(() => {
        this.$nextTick(() => {
          this.isDomReady = true;
          this.getDataList();
        });
      });
    }
  },

  beforeDestroy() {
    this.destroyAllCharts();
  }
};
</script>

<style scoped>
/* 保持原有样式，优化图表容器布局 */
.drawer>>>.el-drawer {
  border-radius: 8px 0 0 8px;
  display: flex;
  flex-direction: column;
}

.drawer>>>.el-form-item__label {
  padding: 0;
}

.drawer>>>.el-drawer__header {
  margin: 0;
  padding: 32px 32px 24px;
  border-bottom: 1px solid #dcdfe6;
}

.drawer>>>.el-drawer__body {
  flex: 1;
  height: 1px;
  display: flex;
  flex-direction: column;
}

.drawer>>>.content {
  padding: 30px 24px;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.drawer>>>.visual-part {
  flex: 1 auto;
  max-height: 76vh;
  overflow: hidden;
  padding: 10px 0;
}

/* 优化图表容器响应式布局 */
@media (max-width: 1200px) {
  .visual-part>div {
    flex-direction: column;
  }

  #barChart,
  #pieChart {
    width: 100% !important;
    height: 350px !important;
    margin-bottom: 20px;
  }
}

.drawer>>>.el-form,
.drawer>>>.attr-list {
  padding: 0 16px;
}

.drawer-body__footer {
  display: flex;
  justify-content: flex-end;
  padding: 18px;
}
</style>
