<script setup lang="ts">
/**
 * @Name: IndicatorFunnel.vue
 * @Description: 搜索词-分析页-漏斗图
 * @Author: Cheney
 */
import { Search } from '@element-plus/icons-vue';
import { inject, onBeforeUnmount, reactive, ref, Ref, watch } from 'vue';
import * as api from './api';
import * as echarts from 'echarts';
import emitter from '/@/utils/emitter';

const filter = inject<Ref>('filter');
const funnelFilter = reactive({
  layerSelect: 'all_asin',
  searchTermInp: '',
});

const funnelLoading = ref(false);
const chartRef = ref<HTMLElement | null>(null);
let chart: echarts.ECharts | null = null;
let resizeObserver: ResizeObserver | null = null;
const hasData = ref(true);

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

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

watch(filter.value, () => {
  funnelFilter.layerSelect = filter.value.layerType;
});

async function fetchFunnelData() {
  funnelLoading.value = true;
  const query = {
    date_start: filter.value.reportDate[0],
    date_end: filter.value.reportDate[1],
    report_range: filter.value.reportType,
    layer_type: funnelFilter.layerSelect,
  };
  // 根据条件有选择性地添加 [filter.value.layerType.split('_')[0]]: filter.value.variable
  if (funnelFilter.layerSelect === 'asin_view' || funnelFilter.layerSelect === 'brand_view') {
    query[funnelFilter.layerSelect.split('_')[0]] = filter.value.variable;
  }

  try {
    const response = await api.getFunnelData(query);
    if (!response.data || Object.keys(response.data).length === 0) {
      hasData.value = false;
      if (chart) {
        chart.clear();
      }
      return;
    }

    hasData.value = true;

    // 转换数据
    const rawData = response.data;
    const funnelData = Object.entries(rawData)
      .filter(([key]) => key.endsWith('log2'))
      .map(([key, value]) => {
        const name =
          key.replace('_Total_Countlog2', '').charAt(0).toUpperCase() +
          key.replace('_Total_Countlog2', '').slice(1).toLowerCase();
        const originalKey = key.replace('log2', '');
        return {
          value: value,
          name: name,
          originalValue: rawData[originalKey],
        };
      });

    const option = {
      title: {
        text: '购买旅程漏斗图',
      },
      tooltip: {
        trigger: 'item',
        formatter: function (params) {
          return `${params.name}: ${params.data.originalValue.toLocaleString()}`;
        },
      },
      // toolbox: {
      //   feature: {
      //     dataView: { readOnly: false },
      //   },
      // },
      series: [
        {
          type: 'funnel',
          left: '10%',
          top: 50,
          bottom: 0,
          width: '80%',
          min: 0,
          max: 100,
          minSize: '0%',
          maxSize: '100%',
          sort: 'descending',
          gap: 2,
          labelLine: {
            length: 10,
            lineStyle: {
              width: 1,
              type: 'solid',
            },
          },
          itemStyle: {
            borderColor: '#fff',
            borderWidth: 1,
          },
          emphasis: {
            label: {
              fontSize: 20,
            },
          },
          data: funnelData,
        },
      ],
    };

    initChart(option);
  } catch (error) {
    console.error('==Error==', error);
  } finally {
    funnelLoading.value = false;
  }
}

function initChart(opt) {
  if (!chart) {
    chart = echarts.init(chartRef.value);
  }
  chart.setOption(opt);

  // 添加 ResizeObserver 以处理图表大小变化
  if (!resizeObserver) {
    resizeObserver = new ResizeObserver(() => {
      chart?.resize();
    });
    resizeObserver.observe(chartRef.value);
  }
}
</script>

<template>
  <el-card shadow="never" v-loading="funnelLoading" class="mt-5">
    <div class="flex gap-5 mb-4 justify-center">
      <div>
        <span class="font-medium mr-0.5">层级 </span>
        <el-select v-model="funnelFilter.layerSelect" @change="fetchFunnelData" style="width: 130px">
          <el-option label="Asin View" value="asin_view" />
          <el-option label="Brand View" value="brand_view" />
          <el-option label="All Asin" value="all_asin" />
          <el-option label="All Brand" value="all_brand" />
        </el-select>
      </div>
      <div>
        <span class="font-medium mr-0.5">搜索词 </span>
        <el-input v-model="funnelFilter.searchTermInp" :prefix-icon="Search" @change="fetchFunnelData" style="width: 200px" />
      </div>
    </div>
    <div class="w-full" style="min-height: 500px">
      <div v-show="!funnelLoading && !hasData" class="no-data-message" style="min-height: 500px">
        <el-empty :image-size="300" />
      </div>
      <div v-show="hasData" ref="chartRef" style="width: 100%; height: 500px"></div>
    </div>

  </el-card>
</template>

<style scoped></style>
