<template>
  <div
    ref="chartContainer"
    class="bar-chart-host"
    :style="chartHostStyle"
  />
</template>

<script>
import * as echarts from 'echarts';

export default {
  name: 'AdvancedMixedChart',
  props: {
    title: {
      type: String,
      default: '图表标题'
    },
    chartData: {
      type: [Array, Object],
      default: () => []
    },
    categories: {
      type: Array,
      default: () => []
    },
    chartType: {
      type: String,
      default: 'single', // 'single' | 'multiple' | 'mixed' | 'stacked'
      validator: (value) => ['single', 'multiple', 'mixed', 'stacked'].includes(value)
    },
    colors: {
      type: Array,
      default: () => ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272']
    },
    // 新增：是否显示双Y轴
    dualYAxis: {
      type: Boolean,
      default: false
    },
    /** 双 Y 轴时左侧轴名称 */
    leftAxisName: {
      type: String,
      default: ''
    },
    /** 双 Y 轴时右侧轴名称 */
    rightAxisName: {
      type: String,
      default: ''
    },
    /** 图表区域高度（像素） */
    height: {
      type: Number,
      default: 300
    },
    // 新增：堆叠组名称（用于stacked模式）
    stackName: {
      type: String,
      default: '总量'
    }
  },
  data() {
    return {
      myChart: null
    };
  },
  computed: {
    chartHostStyle() {
      const h = typeof this.height === 'number' ? `${this.height}px` : '300px';
      return { width: '100%', height: h };
    }
  },
  mounted() {
    this.initChart();
  },
  beforeDestroy() {
    if (this.myChart) {
      this.myChart.dispose();
    }
    window.removeEventListener('resize', this.handleResize);
  },
  methods: {
    initChart() {
      this.$nextTick(() => {
        this.myChart = echarts.init(this.$refs.chartContainer);
        this.renderChart();
        window.addEventListener('resize', this.handleResize);
      });
    },

    // 处理数据格式
    processChartData() {
      if (this.chartType === 'single') {
        // 单系列柱状图
        const data = Array.isArray(this.chartData) && this.chartData.length > 0
          ? this.chartData
          : new Array(this.categories.length).fill(0);

        return [{
          name: '数量',
          type: 'bar',
          data: data
        }];
      } else if (this.chartType === 'multiple') {
        // 多系列柱状图
        if (Array.isArray(this.chartData) && this.chartData.every(item => typeof item === 'number')) {
          return [{
            name: '系列1',
            type: 'bar',
            data: this.chartData
          }];
        } else if (Array.isArray(this.chartData)) {
          return this.chartData.map((series, index) => ({
            name: series.name || `系列${index + 1}`,
            type: series.type || 'bar',
            data: series.data || [],
            yAxisIndex: series.yAxisIndex || 0
          }));
        }
      } else if (this.chartType === 'mixed') {
        // 柱状图和折线图组合
        if (Array.isArray(this.chartData)) {
          return this.chartData.map((series, index) => ({
            name: series.name || (series.type === 'line' ? '折线' : '柱状') + (index + 1),
            type: series.type || (index === 0 ? 'bar' : 'line'),
            data: series.data || [],
            yAxisIndex:
              series.yAxisIndex !== undefined && series.yAxisIndex !== null
                ? series.yAxisIndex
                : (this.dualYAxis && index > 0 ? 1 : 0)
          }));
        }
      } else if (this.chartType === 'stacked') {
        // 堆叠柱状图 [2,3](@ref)
        if (Array.isArray(this.chartData) && this.chartData.every(item => typeof item === 'number')) {
          // 如果是数字数组，转换为单个堆叠系列
          return [{
            name: '数量',
            type: 'bar',
            data: this.chartData,
            stack: this.stackName // 设置堆叠属性 [2](@ref)
          }];
        } else if (Array.isArray(this.chartData)) {
          // 处理多系列堆叠柱状图
          return this.chartData.map((series, index) => ({
            name: series.name || `系列${index + 1}`,
            type: 'bar',
            data: series.data || [],
            yAxisIndex: series.yAxisIndex || 0,
            stack: series.stack || this.stackName // 设置堆叠属性，相同stack值的系列会堆叠 [2,3](@ref)
          }));
        }
      }

      return [{
        name: '数据',
        type: 'bar',
        data: new Array(this.categories.length).fill(0)
      }];
    },

    // 获取Y轴配置
    getYAxisConfig() {
      if (!this.dualYAxis) {
        // 单Y轴配置
        return [{
          type: 'value',
          axisLine: {
            show: true,
            lineStyle: {
              color: '#999'
            }
          },
          axisTick: {
            show: false
          },
          axisLabel: {
            color: '#666'
          },
          splitLine: {
            lineStyle: {
              color: '#f0f0f0',
              type: 'solid'
            }
          }
        }];
      }

      // 双Y轴配置
      return [
        {
          type: 'value',
          name: this.leftAxisName || '左轴',
          position: 'left',
          axisLine: {
            show: true,
            lineStyle: {
              color: this.colors[0]
            }
          },
          axisLabel: {
            color: '#666',
            formatter: '{value}'
          },
          splitLine: {
            show: false
          }
        },
        {
          type: 'value',
          name: this.rightAxisName || '右轴',
          position: 'right',
          axisLine: {
            show: true,
            lineStyle: {
              color: this.colors[1]
            }
          },
          axisLabel: {
            color: '#666',
            formatter: '{value}'
          },
          splitLine: {
            show: false
          }
        }
      ];
    },

    // 获取系列配置
    getSeriesConfig(processedSeries) {
      const firstBarIndex = processedSeries.findIndex(s => s.type === 'bar');
      const barSeriesCount = processedSeries.filter(s => s.type === 'bar').length;
      const tightBarGroup =
        this.chartType !== 'stacked' &&
        barSeriesCount >= 2 &&
        (this.chartType === 'mixed' || this.chartType === 'multiple');

      return processedSeries.map((series, index) => {
        const isLine = series.type === 'line';
        const isStacked = this.chartType === 'stacked';

        // 基础配置，包含堆叠属性 [2](@ref)
        const baseConfig = {
          name: series.name,
          type: series.type,
          data: series.data,
          yAxisIndex: series.yAxisIndex || 0,
          stack: series.stack // 保留堆叠属性，如果存在
        };

        if (isLine) {
          // 折线图配置
          return {
            ...baseConfig,
            smooth: true,
            symbol: 'circle',
            symbolSize: 6,
            lineStyle: {
              width: 3,
              color: this.colors[index % this.colors.length]
            },
            itemStyle: {
              color: this.colors[index % this.colors.length]
            }
          };
        } else {
          // 柱状图配置
          const barConfig = {
            ...baseConfig,
            barWidth: this.chartType === 'single' ? '60%' : '40%',
            itemStyle: {
              color: this.colors[index % this.colors.length]
            },
            emphasis: {
              itemStyle: {
                color: this.colors[index % this.colors.length],
                shadowBlur: 10,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          };

          // 为堆叠柱状图调整柱宽和样式 [3](@ref)
          if (isStacked) {
            barConfig.barWidth = '50%';
            barConfig.itemStyle.borderRadius = [2, 2, 0, 0]; // 顶部圆角
          }

          // 同一类目下多根柱（如混合图双柱）：柱间距为 0，使两柱紧贴（barGap 写在首个 bar 系列上）
          if (tightBarGroup && index === firstBarIndex) {
            barConfig.barGap = '0%';
          }

          return barConfig;
        }
      });
    },

    // 渲染图表
    renderChart() {
      const processedSeries = this.processChartData();
      const seriesConfig = this.getSeriesConfig(processedSeries);
      const yAxisConfig = this.getYAxisConfig();

      // 计算图例显示条件：单系列时不显示图例
      const showLegend = this.chartType !== 'single';

      // 堆叠柱状图的tooltip配置 [2](@ref)
      const tooltipFormatter = this.chartType === 'stacked'
        ? this.getStackedTooltipFormatter
        : null;

      const option = {
        title: {
          text: this.title,
          left: 'left',
          top: 10,
          textStyle: {
            color: '#333',
            fontSize: 16,
            fontWeight: 'bold'
          }
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: this.chartType === 'stacked' ? 'shadow' : 'line' // 堆叠模式使用阴影指针 [2](@ref)
          },
          formatter: tooltipFormatter || this.getDefaultTooltipFormatter(),
          backgroundColor: 'rgba(255, 255, 255, 0.95)',
          borderColor: '#ddd',
          borderWidth: 1,
          textStyle: {
            color: '#333'
          }
        },
        legend: {
          show: showLegend,
          data: seriesConfig.map(s => s.name),
          right: 10,
          top: 10,
          orient: 'horizontal',
          type: 'scroll',
          textStyle: {
            color: '#666'
          }
        },
        grid: {
          left: '3%',
          right: this.dualYAxis ? '8%' : '3%',
          bottom: '8%',
          top: showLegend ? 60 : 40,
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: this.categories,
          axisLine: {
            lineStyle: {
              color: '#999'
            }
          },
          axisTick: {
            show: false
          },
          axisLabel: {
            color: '#666',
            interval: 0,
            rotate: this.categories.length > 6 ? 45 : 0,
            margin: 10
          }
        },
        yAxis: yAxisConfig,
        series: seriesConfig
      };

      this.myChart.setOption(option);
    },

    // 默认tooltip格式化器
    getDefaultTooltipFormatter() {
      return (params) => {
        let result = `<div style="font-weight: bold; margin-bottom: 8px; font-size: 14px;">${params[0].name}</div>`;
        params.forEach(param => {
          const color = param.color;
          const seriesName = param.seriesName;
          const value = param.value;
          const marker = `<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${color};"></span>`;

          result += `
            <div style="display: flex; justify-content: space-between; align-items: center; margin: 4px 0; min-width: 120px;">
              <div style="display: flex; align-items: center;">
                ${marker}
                <span style="margin-right: 15px;">${seriesName}</span>
              </div>
              <span style="font-weight: bold; font-size: 13px;">${value}</span>
            </div>
          `;
        });
        return result;
      };
    },

    // 堆叠柱状图tooltip格式化器 [2](@ref)
    getStackedTooltipFormatter(params) {
      let result = `<div style="font-weight: bold; margin-bottom: 8px; font-size: 14px;">${params[0].name}</div>`;
      let total = 0;

      // 计算总和
      params.forEach(param => {
        total += param.value || 0;
      });

      params.forEach(param => {
        const color = param.color;
        const seriesName = param.seriesName;
        const value = param.value;
        const percentage = total > 0 ? ((value / total) * 100).toFixed(1) : 0;
        const marker = `<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${color};"></span>`;

        result += `
          <div style="display: flex; justify-content: space-between; align-items: center; margin: 4px 0; min-width: 150px;">
            <div style="display: flex; align-items: center;">
              ${marker}
              <span style="margin-right: 15px;">${seriesName}</span>
            </div>
            <div style="text-align: right;">
              <span style="font-weight: bold; font-size: 13px;">${value}</span>
            </div>
          </div>
        `;
      });

      return result;
    },

    handleResize() {
      if (this.myChart) {
        this.myChart.resize();
      }
    }
  },
  watch: {
    chartData: {
      handler() {
        if (this.myChart) {
          this.renderChart();
        }
      },
      deep: true
    },
    categories() {
      if (this.myChart) {
        this.renderChart();
      }
    },
    chartType() {
      if (this.myChart) {
        this.renderChart();
      }
    },
    dualYAxis() {
      if (this.myChart) {
        this.renderChart();
      }
    },
    leftAxisName() {
      if (this.myChart) {
        this.renderChart();
      }
    },
    rightAxisName() {
      if (this.myChart) {
        this.renderChart();
      }
    },
    height() {
      this.$nextTick(() => {
        if (this.myChart) {
          this.myChart.resize();
        }
      });
    },
    stackName() {
      if (this.myChart && this.chartType === 'stacked') {
        this.renderChart();
      }
    }
  }
};
</script>
