<template>
  <div ref="chartRef" :class="className" :style="{ height: height, width: width }" />
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import * as echarts from 'echarts'

const props = defineProps({
  className: { type: String, default: 'chart' },
  width: { type: String, default: '100%' },
  height: { type: String, default: '300px' },
  chartData: {
    type: Array,
    default: () => [
      { value: 1048, name: 'Search Engine' },
      { value: 735, name: 'Direct' },
      { value: 580, name: 'Email' },
      { value: 484, name: 'Union Ads' },
      { value: 300, name: 'Video Ads' }
    ]
  }
})

const chartRef = ref(null)
let chartInstance = null
let resizeObserver = null
let resizeTimer = null

const handleResize = () => {
  if (resizeTimer) clearTimeout(resizeTimer)
  resizeTimer = setTimeout(() => {
    if (chartInstance) chartInstance.resize()
  }, 200)
}

const initResizeListener = () => {
  window.addEventListener('resize', handleResize)
  if (typeof ResizeObserver !== 'undefined' && chartRef.value) {
    resizeObserver = new ResizeObserver(handleResize)
    resizeObserver.observe(chartRef.value)
  }
}

const removeResizeListener = () => {
  if (resizeTimer) clearTimeout(resizeTimer)
  window.removeEventListener('resize', handleResize)
  if (resizeObserver) {
    resizeObserver.disconnect()
    resizeObserver = null
  }
}

const initChart = () => {
  if (!chartRef.value) return
  if (chartInstance) chartInstance.dispose()
  chartInstance = echarts.init(chartRef.value, 'macarons')
  setOptions(props.chartData)
  nextTick(() => chartInstance.resize())
}

const setOptions = (data) => {
  if (!chartInstance) return
  chartInstance.setOption({
    tooltip: { trigger: 'item', axisPointer: { type: 'shadow' } },
    legend: { orient: 'horizontal', left: 'right' },
    series: [
      {
        name: '订单来源',
        type: 'pie',
        radius: '50%',
        data: data,
        labelLine: { show: false },
        label: { show: false },
        animationEasing: 'cubicInOut',
        animationDuration: 2600,
        emphasis: {
          itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' }
        }
      }
    ]
  })
}

watch(
    () => props.chartData,
    (newVal) => setOptions(newVal),
    { deep: true }
)

onMounted(() => {
  nextTick(() => {
    initChart()
    initResizeListener()
  })
})

onBeforeUnmount(() => {
  removeResizeListener()
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
})

defineExpose({ resizeChart: handleResize })
</script>