<template>
  <div class="app-container">
    <!-- 筛选 -->
    <div class="filter-card">
      <div class="filter-section">
        <div class="filter-row">
          <div class="filter-item">
            <label>分类：</label>
            <el-select
              v-model="filters.category"
              placeholder="请选择分类（默认全部）"
              clearable
              filterable
              style="width: 280px"
              size="small"
            >
              <el-option
                v-for="category in filterOptions.categories"
                :key="category"
                :label="category"
                :value="category"
              />
            </el-select>
          </div>

          <div class="filter-item">
            <label>日期：</label>
            <el-date-picker
              v-model="dateRange"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              format="yyyy-MM-dd"
              value-format="yyyy-MM-dd"
              @change="handleDateChange"
              style="width: 380px"
              size="small"
            />
          </div>

          <div class="filter-item">
            <el-button type="primary" @click="fetchData" :loading="loading" size="small">
              查询分析
            </el-button>
            <el-button @click="resetFilter" size="small">重置筛选</el-button>
          </div>
        </div>
      </div>
    </div>

    <!-- 图表区域 -->
    <div class="charts-section" v-if="Object.keys(dimensionCharts).length > 0">
      <div
        v-for="(chartData, dimension) in dimensionCharts"
        :key="dimension"
        class="dimension-section"
      >
        <el-row :gutter="10">
          <el-col :span="12">
            <!-- 销售金额占比 -->
            <div class="chart-card">
              <div class="card-header">
                <div class="header-left">
                  <span>{{ currentCategory }} {{ dimension }} 销售金额占比</span>
                </div>
                <div class="header-right">
                  <span class="total-amount"
                    >总计: ￥{{
                      formatNumber(getTotalAmount(chartData.amountData))
                    }}</span
                  >
                </div>
              </div>
              <div class="chart-container">
                <div
                  :id="`${dimension}AmountChart`"
                  style="width: 100%; height: 450px"
                ></div>
              </div>
            </div>
          </el-col>

          <el-col :span="12">
            <!-- 销售数量占比 -->
            <div class="chart-card">
              <div class="card-header">
                <div class="header-left">
                  <span>{{ currentCategory }} {{ dimension }} 销售数量占比</span>
                </div>
                <div class="header-right">
                  <span class="total-quantity"
                    >总计:
                    {{
                      formatNumber(getTotalQuantity(chartData.quantityData))
                    }}</span
                  >
                </div>
              </div>
              <div class="chart-container">
                <div
                  :id="`${dimension}QuantityChart`"
                  style="width: 100%; height: 450px"
                ></div>
              </div>
            </div>
          </el-col>
        </el-row>
      </div>
    </div>

    <!-- 无数据提示 -->
    <div v-else-if="!loading" class="no-data-section">
      <div class="no-data-content">
        <i class="el-icon-warning-outline"></i>
        <p>暂无数据</p>
        <small>请尝试调整筛选条件或检查数据</small>
      </div>
    </div>
  </div>
</template>

<script>
import * as echarts from "echarts";
import { getReportFilterOptions, getCategoryAnalysisReport } from '@/api/sales-analysis'

export default {
  name: "CategoryAnalysis",
  components: {},
  data() {
    return {
      loading: false,
      dateRange: null,
      filters: {
        category: "",
      },
      filterOptions: {
        categories: [],
      },
      dimensionCharts: {},
      chartInstances: new Map(), // 存储图表实例
      currentCategory: "全部分类",
      resizeTimer: null, // 防抖定时器
      resizeObserver: null, // ResizeObserver 实例
    };
  },
  mounted() {
    this.initDateRange();
    this.fetchFilterOptions();
    // this.fetchData();
    
    // 添加窗口大小变化监听
    window.addEventListener('resize', this.handleResize);
    
    // 使用 ResizeObserver 监听容器尺寸变化
    this.initResizeObserver();
  },
  beforeDestroy() {
    // 移除窗口大小变化监听
    window.removeEventListener('resize', this.handleResize);
    
    // 清除防抖定时器
    if (this.resizeTimer) {
      clearTimeout(this.resizeTimer);
    }
    
    // 断开 ResizeObserver
    if (this.resizeObserver) {
      this.resizeObserver.disconnect();
    }
    
    // 销毁所有图表实例
    this.chartInstances.forEach((chart) => {
      if (chart) {
        chart.dispose();
      }
    });
    this.chartInstances.clear();
  },
  methods: {
    // 初始化日期范围（默认最近30天）
    initDateRange() {
      const endDate = new Date();
      const startDate = new Date();
      startDate.setDate(endDate.getDate() - 30);

      this.dateRange = [
        startDate.toISOString().split("T")[0],
        endDate.toISOString().split("T")[0],
      ];
    },

    // 日期变化处理
    handleDateChange(dates) {
      this.dateRange = dates;
    },

    // 重置筛选
    resetFilter() {
      this.initDateRange();
      this.fetchData();
    },

    // 获取筛选选项
    async fetchFilterOptions() {
      try {
        const response = await getReportFilterOptions();

        if (response.code === 200) {
          this.filterOptions = {
            categories: response.data.categories || [],
          };
        } else {
          console.error("获取筛选选项失败:", response.message);
        }
      } catch (error) {
        console.error("获取筛选选项失败:", error);
      }
    },

    // 获取数据
    async fetchData() {
      if (!this.dateRange || this.dateRange.length !== 2) {
        this.$message.warning("请选择日期范围");
        return;
      }

      try {
        this.loading = true;

        // 构建查询参数
        const params = {
          startDate: this.dateRange[0],
          endDate: this.dateRange[1],
        };

        // 添加分类筛选条件（如果选择了特定分类）
        if (this.filters.category) {
          params.category = this.filters.category;
        }

        const response = await getCategoryAnalysisReport(params);

        if (response.code === 200) {
          this.dimensionCharts = response.data.dimensionCharts || {};
          this.currentCategory = response.data.currentCategory || "全部分类";

          this.$nextTick(() => {
            this.renderAllCharts();
            
            // 数据更新后，确保图表能够响应 resize
            setTimeout(() => {
              this.handleResize();
            }, 200);
          });
        } else {
          this.$message.error(response.message || "获取数据失败");
        }
      } catch (error) {
        console.error("获取数据失败:", error);
        this.$message.error("获取数据失败");
      } finally {
        this.loading = false;
      }
    },

    // 渲染所有图表
    renderAllCharts() {
      // 先销毁所有现有图表
      this.chartInstances.forEach((chart) => {
        if (chart) {
          chart.dispose();
        }
      });
      this.chartInstances.clear();

      // 为每个维度渲染图表
      for (const [dimension, chartData] of Object.entries(
        this.dimensionCharts
      )) {
        this.renderDimensionCharts(dimension, chartData);
      }
    },

    // 渲染单个维度的图表
    renderDimensionCharts(dimension, chartData) {
      // 渲染金额占比图表
      this.renderAmountChart(dimension, chartData.amountData);

      // 渲染数量占比图表
      this.renderQuantityChart(dimension, chartData.quantityData);
    },

    // 渲染金额占比图表
    renderAmountChart(dimension, data) {
      const chartId = `${dimension}AmountChart`;
      const chartDom = document.getElementById(chartId);

      if (!chartDom || !data || data.length === 0) return;

      const chart = echarts.init(chartDom);
      
      // 为图表添加 resize 监听
      chart.resize = chart.resize.bind(chart);
      
      this.chartInstances.set(chartId, chart);
      const totalAmount = this.getTotalAmount(data);
      const processedData = this.processChartData(data);

      const option = {
        tooltip: {
          trigger: "item",
          backgroundColor: "rgba(255, 255, 255, 0.98)",
          borderColor: "#E8E8E8",
          borderWidth: 1,
          textStyle: {
            color: "#333",
            fontSize: 13,
          },
          padding: 12,
          formatter: (params) => {
            const percentage = params.data.percentage;
            const amount = this.formatNumber(params.value);
            return `
              <div style="font-weight: 600; margin-bottom: 8px;">${params.name}</div>
              <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; min-width: 150px; gap: 20px;">
                <span style="color: #666;">销售额</span>
                <span style="font-weight: 600; color: #D9534F;">￥${amount}</span>
              </div>
              <div style="display: flex; justify-content: space-between; align-items: center;">
                <span style="color: #666;">占比</span>
                <span style="font-weight: 600; color: #5B9BD5;">${percentage}%</span>
              </div>
            `;
          },
        },
        legend: {
          type: "scroll",
          orient: "vertical",
          right: 20,
          top: "center",
          data: processedData.map((item) => "" + item.name + ""),
          textStyle: {
            color: "#666",
            fontSize: 14,
          },
          itemWidth: 20,
          itemHeight: 20,
          itemGap: 10,
          formatter: (name) => {
            const item = processedData.find((p) => p.name === name);
            const displayName =
              name.length > 15 ? name.slice(0, 15) + "..." : name;

            if (item && item.percentage !== undefined) {
              return `${displayName}  ${item.percentage}%`;
            }
            return displayName;
          },
        },
        series: [
          {
            name: "销售金额",
            type: "pie",
            radius: ["50%", "75%"],
            center: ["38%", "50%"],
            avoidLabelOverlap: false,
            itemStyle: {
              borderColor: "#fff",
              borderWidth: 2,
            },
            label: {
              show: false,
              position: "center",
              formatter: () => {
                return `{total|￥${this.formatNumber(
                  totalAmount,
                  true
                )}}\n{name|总金额}`;
              },
              rich: {
                total: {
                  fontSize: 22,
                  fontWeight: "bold",
                  color: "#D9534F",
                },
                name: {
                  fontSize: 14,
                  color: "#666",
                  padding: [4, 0, 0, 0],
                },
              },
            },
            emphasis: {
              scale: true,
              scaleSize: 10,
              label: {
                show: true,
                formatter: (params) => {
                  return `{val|${params.percent}%}\n{name|${params.name}}`;
                },
                rich: {
                  val: {
                    fontSize: 22,
                    fontWeight: "bold",
                    color: "#D9534F",
                  },
                  name: {
                    fontSize: 14,
                    color: "#666",
                    padding: [4, 0, 0, 0],
                  },
                },
              },
            },
            labelLine: {
              show: false,
            },
            data: processedData,
            color: [
              "#5B9BD5",
              "#ED7D31",
              "#A5A5A5",
              "#FFC000",
              "#4472C4",
              "#70AD47",
              "#255E91",
              "#9E480E",
              "#636363",
              "#997300",
            ],
          },
        ],
      };

      chart.setOption(option);
    },

    // 渲染数量占比图表
    renderQuantityChart(dimension, data) {
      const chartId = `${dimension}QuantityChart`;
      const chartDom = document.getElementById(chartId);

      if (!chartDom || !data || data.length === 0) return;

      const chart = echarts.init(chartDom);
      
      // 为图表添加 resize 监听
      chart.resize = chart.resize.bind(chart);
      
      this.chartInstances.set(chartId, chart);
      const totalQuantity = this.getTotalQuantity(data);
      const processedData = this.processChartData(data, false);

      const option = {
        tooltip: {
          trigger: "item",
          backgroundColor: "rgba(255, 255, 255, 0.98)",
          borderColor: "#E8E8E8",
          borderWidth: 1,
          textStyle: {
            color: "#333",
            fontSize: 13,
          },
          padding: 12,
          formatter: (params) => {
            const percentage = params.data.percentage;
            const quantity = this.formatNumber(params.value);
            return `
              <div style="font-weight: 600; margin-bottom: 8px;">${params.name}</div>
              <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; min-width: 150px; gap: 20px;">
                <span style="color: #666;">销售数量</span>
                <span style="font-weight: 600; color: #5CB85C;">${quantity}</span>
              </div>
              <div style="display: flex; justify-content: space-between; align-items: center;">
                <span style="color: #666;">占比</span>
                <span style="font-weight: 600; color: #5B9BD5;">${percentage}%</span>
              </div>
            `;
          },
        },
        legend: {
          type: "scroll",
          orient: "vertical",
          right: 20,
          top: "center",
          show: true,
          data: processedData.map((item) => "" + item.name + ""),
          textStyle: {
            color: "#666",
            fontSize: 14,
          },
          itemWidth: 20,
          itemHeight: 20,
          itemGap: 10,
          formatter: (name) => {
            const item = processedData.find((p) => p.name === name);
            const displayName =
              name.length > 30 ? name.slice(0, 30) + "..." : name;

            if (item && item.percentage !== undefined) {
              return `${displayName}  ${item.percentage}%`;
            }
            return displayName;
          },
        },
        series: [
          {
            name: "销售数量",
            type: "pie",
            radius: ["50%", "75%"],
            center: ["38%", "50%"],
            avoidLabelOverlap: false,
            itemStyle: {
              borderRadius: 5,
              borderColor: "#fff",
              borderWidth: 2,
            },
            label: {
              show: false,
              position: "center",
              formatter: () => {
                return `{total|${this.formatNumber(
                  totalQuantity
                )}}\n{name|总数量}`;
              },
              rich: {
                total: {
                  fontSize: 22,
                  fontWeight: "bold",
                  color: "#5CB85C",
                },
                name: {
                  fontSize: 14,
                  color: "#666",
                  padding: [4, 0, 0, 0],
                },
              },
            },
            emphasis: {
              scale: true,
              scaleSize: 10,
              label: {
                show: true,
                formatter: (params) => {
                  return `{val|${params.percent}%}\n{name|${params.name}}`;
                },
                rich: {
                  val: {
                    fontSize: 22,
                    fontWeight: "bold",
                    color: "#5CB85C",
                  },
                  name: {
                    fontSize: 14,
                    color: "#666",
                    padding: [4, 0, 0, 0],
                  },
                },
              },
            },
            labelLine: {
              show: false,
            },
            data: processedData,
            color: [
              "#70AD47",
              "#4472C4",
              "#FFC000",
              "#ED7D31",
              "#5B9BD5",
              "#A5A5A5",
              "#255E91",
              "#9E480E",
              "#636363",
              "#997300",
            ],
          },
        ],
      };

      chart.setOption(option);
    },

    // 格式化数字
    formatNumber(num, isMoney = false) {
      if (!num) return "0";

      if (isMoney && num >= 10000) {
        return (num / 10000).toFixed(1) + "万";
      }

      return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    },

    // 处理图表数据，聚合TopN和'其它'
    processChartData(data, isAmount = true) {
      const legendLimit = 9;
      if (data.length <= legendLimit + 1) {
        return data;
      }

      const topItems = data.slice(0, legendLimit);
      const otherItems = data.slice(legendLimit);

      const otherSum = otherItems.reduce((sum, item) => sum + item.value, 0);
      const totalSum = data.reduce((sum, item) => sum + item.value, 0);

      const otherPercentage =
        totalSum > 0 ? ((otherSum / totalSum) * 100).toFixed(2) : 0;

      const otherItem = {
        name: "其它",
        value: otherSum,
        percentage: otherPercentage,
      };

      if (isAmount) {
        otherItem.amount = otherSum;
      } else {
        otherItem.quantity = otherSum;
      }

      return [...topItems, otherItem];
    },

    // 获取总图表数量
    getTotalChartsCount() {
      return Object.keys(this.dimensionCharts).length * 2;
    },

    // 获取总数据项数量
    getTotalDataItems() {
      let total = 0;
      for (const chartData of Object.values(this.dimensionCharts)) {
        total += chartData.amountData.length + chartData.quantityData.length;
      }
      return total;
    },

    // 获取主要维度
    getMainDimension() {
      if (Object.keys(this.dimensionCharts).length === 0) return "-";

      let maxItems = 0;
      let mainDimension = "";

      for (const [dimension, chartData] of Object.entries(
        this.dimensionCharts
      )) {
        const totalItems =
          chartData.amountData.length + chartData.quantityData.length;
        if (totalItems > maxItems) {
          maxItems = totalItems;
          mainDimension = dimension;
        }
      }

      return mainDimension;
    },

    // 获取总金额
    getTotalAmount(data) {
      return data.reduce((sum, item) => sum + (item.value || 0), 0);
    },

    // 获取总数量
    getTotalQuantity(data) {
      return data.reduce((sum, item) => sum + (item.value || 0), 0);
    },

    // 处理窗口大小变化
    handleResize() {
      console.log('窗口大小变化，触发 resize 处理');
      
      // 使用防抖处理，避免频繁调用
      if (this.resizeTimer) {
        clearTimeout(this.resizeTimer);
      }
      
      this.resizeTimer = setTimeout(() => {
        console.log('执行图表 resize');
        
        // 强制触发 DOM 重新计算
        this.$forceUpdate();
        
        // 遍历所有图表实例并执行 resize
        this.chartInstances.forEach((chart, chartId) => {
          if (chart && chart.getDom()) {
            console.log(`resize 图表: ${chartId}`);
            chart.resize();
          }
        });
      }, 100);
    },

    // 初始化 ResizeObserver
    initResizeObserver() {
      if (window.ResizeObserver) {
        this.resizeObserver = new ResizeObserver((entries) => {
          console.log('容器尺寸变化检测到');
          this.handleResize();
        });
        
        // 监听图表容器
        this.$nextTick(() => {
          const chartContainers = document.querySelectorAll('.chart-container');
          chartContainers.forEach(container => {
            this.resizeObserver.observe(container);
          });
        });
      }
    },
  },
};
</script>

<style scoped>
.app-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px;
  width: 100%;
  min-height: 100vh;
  box-sizing: border-box;
}

.filter-card {
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  border: 1px solid #e8e8e8;
}

.filter-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.filter-row {
  display: flex;
  align-items: center;
  gap: 15px;
}

.filter-item {
  display: flex;
  align-items: center;
  gap: 6px;
}

.filter-item label {
  font-weight: 500;
  color: #333;
  white-space: nowrap;
}

.filter-item .el-select {
  width: 180px;
}

.filter-item .el-input {
  width: 180px;
}

.stats-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px;
}

.stat-card {
  background: #fff;
  padding: 20px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid #e8e8e8;
  transition: background-color 0.2s ease;
}

.stat-card:hover {
  background-color: #f8f9fa;
}

.stat-card-1 {
  border-left: 4px solid #5b9bd5;
}
.stat-card-2 {
  border-left: 4px solid #ed7d31;
}
.stat-card-3 {
  border-left: 4px solid #70ad47;
}
.stat-card-4 {
  border-left: 4px solid #ffc000;
}

.stat-card-1 .stat-icon {
  background-color: #5b9bd5;
}
.stat-card-2 .stat-icon {
  background-color: #ed7d31;
}
.stat-card-3 .stat-icon {
  background-color: #70ad47;
}
.stat-card-4 .stat-icon {
  background-color: #ffc000;
}

.stat-icon {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  color: white;
  flex-shrink: 0;
}

.stat-content {
  flex: 1;
}

.stat-title {
  font-size: 14px;
  color: #666;
  margin-bottom: 4px;
}

.stat-value {
  font-size: 28px;
  font-weight: 600;
  color: #333;
  margin-bottom: 4px;
}

.stat-desc {
  font-size: 12px;
  color: #999;
}

.charts-section {
  width: 100%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.dimension-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow: hidden;
}

.dimension-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 0;
}

.dimension-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 18px;
  color: #333;
}

.dimension-title i {
  font-size: 20px;
  color: #5b9bd5;
}

.dimension-stats {
  display: flex;
  gap: 10px;
}

.stat-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: #666;
}

.category-stat {
  background-color: #e9ecef;
  padding: 4px 8px;
  border-radius: 4px;
}

.category-stat strong {
  color: #0056b3;
}

.chart-card {
  background-color: #fff;
  border-radius: 8px;
  border: 1px solid #e8e8e8;
  overflow: hidden;
}

.chart-container {
  padding: 15px 0;
  width: 100%;
  height: auto;
  min-height: 0;
  overflow: hidden;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 20px;
  background: #fff;
  border-bottom: 1px solid #e8e8e8;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  color: #333;
}

.header-left i {
  font-size: 18px;
}

.header-icon-amount {
  color: #d9534f;
}

.header-icon-quantity {
  color: #5cb85c;
}

.header-right {
  font-size: 14px;
  font-weight: 600;
}

.total-amount {
  color: #d9534f;
}

.total-quantity {
  color: #5cb85c;
}

.no-data-section {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 400px;
}

.no-data-content {
  text-align: center;
  color: #999;
}

.no-data-content i {
  font-size: 48px;
  margin-bottom: 20px;
  display: block;
  color: #ccc;
}

.no-data-content p {
  font-size: 16px;
  margin: 0 0 10px 0;
  color: #666;
}

.no-data-content small {
  font-size: 14px;
  color: #aaa;
}
</style>
