<script setup lang="ts">
/**
 * @Name: IndicatorHeatmap.vue
 * @Description: 搜索词-分析页-热力图
 * @Author: Cheney
 */

import * as echarts from 'echarts';
import { inject, onBeforeUnmount, Ref, ref } from 'vue';
import * as api from './api';
import emitter from '/@/utils/emitter';

const filter = inject<Ref>('filter');
const hasData = ref(true);
const heatmapLoading = ref(false);
const chartRef = ref<HTMLElement | null>(null);
let chart: echarts.ECharts | null = null;
let resizeObserver: ResizeObserver | null = null;

onBeforeUnmount(() => {
  emitter.all.clear();
  // 清理 ResizeObserver
  if (resizeObserver) {
    resizeObserver.disconnect();
  }
  if (chart) {
    chart.dispose();
    chart = null;
  }
});

emitter.on('QueryCondition-sendRequest', () => {
  fetchHeatmapData();
});

async function fetchHeatmapData() {
  heatmapLoading.value = true;
  const query = {
    date_start: filter.value.reportDate[0],
    date_end: filter.value.reportDate[1],
    layer_type: filter.value.layerType,
    search_term: filter.value.searchTerm,
    report_range: filter.value.reportType,
    [filter.value.layerType.split('_')[0]]: filter.value.variable,
    metric: filter.value.metric,
  };
  try {
    const responseData = await api.getHeatmapData(query);
    if (!responseData.data || responseData.data.length === 0) {
      // 处理空数据的情况
      hasData.value = false;
      if (chart) {
        chart.clear();
      }
      return;
    }
    hasData.value = true;
    const days = responseData.data.map((item) => item.Reporting_Date); // y轴数据
    const keywords = Object.keys(responseData.data[0]).filter((key) => key !== 'Reporting_Date').slice(0, 10); // x轴数据
    const data = [];

    // 找出所有数值的最大值，用于设置 visualMap 的 max 值
    const maxValue = Math.max(
      ...responseData.data.flatMap((item) =>
        Object.entries(item)
          .filter(([key]) => key !== 'Reporting_Date')
          .map(([, value]) => value as number)
      )
    );

    responseData.data.forEach((item, yIndex) => {
      keywords.forEach((keyword, xIndex) => {
        if (item[keyword] !== undefined && item[keyword] !== null) {
          data.push([xIndex, yIndex, item[keyword]]); // 只添加非空值
        }
      });
    });

    const option = {
      tooltip: {
        position: 'top',
      },
      grid: {
        height: '65%',
        top: '15%',
      },
      position: 'top',
      xAxis: {
        type: 'category',
        name: '日期',
        nameGap: 20,
        nameLocation: 'start',
        nameTextStyle: {
          fontWeight: 'bold',
          fontSize: 14,
          color: '#333',
        },
        axisLabel: {
          formatter: function (value) {
            if (value.length > 10) {
              return value.substring(0, 10) + '...';
            }
            return value;
          },
        },
        data: keywords,
        splitArea: {
          show: true,
        },
      },
      yAxis: {
        type: 'category',
        name: '搜索词',
        nameGap: 20,
        nameTextStyle: {
          fontWeight: 'bold',
          fontSize: 14,
          color: '#333',
        },
        // nameTruncate: {
        //   maxWidth: 20,
        //   ellipsis: '...'
        // },
        data: days,
        splitArea: {
          show: true,
        },
      },
      visualMap: {
        min: 0,
        max: maxValue, // 使用计算出的最大值
        calculable: true,
        orient: 'horizontal',
        left: 'center',
        bottom: '2%',
      },
      series: [
        {
          name: 'Punch Card',
          type: 'heatmap',
          data: data,
          label: {
            show: true,
          },
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowColor: 'rgba(0, 0, 0, 0.5)',
            },
          },
        },
      ],
    };

    if (!chart) {
      chart = echarts.init(chartRef.value);
    }
    chart.setOption(option);

    // 添加 ResizeObserver 以处理图表大小变化
    if (!resizeObserver) {
      resizeObserver = new ResizeObserver(() => {
        chart?.resize();
      });
      resizeObserver.observe(chartRef.value);
    }
  } catch (error) {
    hasData.value = false;
    console.error('==Error==', error);
  } finally {
    heatmapLoading.value = false;
  }
}
</script>

<template>
  <el-card shadow="never" v-loading="heatmapLoading" class="flex flex-col" body-class="w-full">
    <div class="font-bold text-xl mb-4 text-center" style="color: #464646">搜索词时间段对比热力图</div>
    <div class="text-center">
      <el-radio-group v-model="filter.metric" @change="fetchHeatmapData">
        <el-radio-button label="Search_Query_Score" value="Search_Query_Score" />
        <el-radio-button label="Search_Query_Volume" value="Search_Query_Volume" />
        <el-radio-button label="Impressions_Total_Count" value="Impressions_Total_Count" />
        <el-radio-button label="Impressions_A_B_Count" value="Impressions_A_B_Count" />
        <el-radio-button label="Clicks_Total_Count" value="Clicks_Total_Count" />
        <el-radio-button label="Clicks_Price_Median" value="Clicks_Price_Median" />
        <el-radio-button label="Cart_Adds_Total_Count" value="Cart_Adds_Total_Count" />
        <el-radio-button label="Purchases_Total_Count" value="Purchases_Total_Count" />
      </el-radio-group>
    </div>

    <div class="w-full">
      <div v-show="!heatmapLoading && !hasData" class="no-data-message" style="min-height: 500px">
        <el-empty />
      </div>
      <div v-show="hasData" ref="chartRef" style="width: 100%; height: 500px"></div>
    </div>
  </el-card>
</template>

<style scoped></style>
