<!--
  漏斗图组件
  用于展示流程、转化率等
-->

<template>
  <BaseChart
    :option="chartOption"
    :height="height"
    :loading="loading"
    @ready="handleReady"
    @click="handleClick"
  />
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import BaseChart from './BaseChart.vue'
import { funnelChartOption, echartsTheme, formatNumber } from '@/utils/echarts'
import type { FunnelChartConfig } from '@/types/charts'

/** Props */
interface Props {
  data: Array<{ name: string; value: number; [key: string]: any }>
  title?: string
  height?: string
  sort?: 'descending' | 'ascending' | 'none'
}

const props = withDefaults(defineProps<Props>(), {
  data: () => [],
  title: '',
  height: '400px',
  sort: 'descending',
})

/** Emits */
interface Emits {
  (e: 'ready', chart: any): void
  (e: 'click', item: any): void
}

const emit = defineEmits<Emits>()

/** 加载状态 */
const loading = ref(false)

/** 图表配置 */
const chartOption = computed(() => {
  // 计算总数
  const total = props.data.reduce((sum, item) => sum + item.value, 0)

  // 处理数据
  const chartData = props.data.map((item, index) => ({
    name: item.name,
    value: item.value,
    itemStyle: {
      color: echartsTheme.color[index % echartsTheme.color.length],
    },
  }))

  return {
    ...funnelChartOption,
    title: {
      ...funnelChartOption.title,
      text: props.title,
    },
    tooltip: {
      ...funnelChartOption.tooltip,
      formatter: (params: any) => {
        const percentage = total > 0 ? ((params.value / total) * 100).toFixed(1) : 0
        return `${params.name}<br/>数量: ${formatNumber(params.value)}<br/>占比: ${percentage}%`
      },
    },
    series: [
      {
        ...funnelChartOption.series![0],
        sort: props.sort,
        data: chartData,
        label: {
          ...funnelChartOption.series![0].label,
          formatter: (params: any) => {
            const percentage = total > 0 ? ((params.value / total) * 100).toFixed(1) : 0
            return `${params.name}\n${formatNumber(params.value)} (${percentage}%)`
          },
        },
      },
    ],
  }
})

/** 处理图表就绪 */
const handleReady = (chart: any) => {
  emit('ready', chart)
}

/** 处理点击事件 */
const handleClick = (params: any) => {
  const item = props.data.find((d) => d.name === params.name)
  if (item) {
    emit('click', { ...item, ...params })
  }
}

/** 暴露方法 */
defineExpose({
  loading,
})
</script>
