<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'
  },
  autoResize: {
    type: Boolean,
    default: true
  },
  chartData: {
    type: Object,
    required: true
  }
})

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

onMounted(() => {
  nextTick(() => {
    initChart()
    if (props.autoResize) {
      initResizeListener()
    }
  })
})

onBeforeUnmount(() => {
  // 清理定时器
  if (resizeTimer) {
    clearTimeout(resizeTimer)
    resizeTimer = null
  }

  // 清理 ResizeObserver
  if (resizeObserver && chartRef.value) {
    resizeObserver.unobserve(chartRef.value)
    resizeObserver.disconnect()
    resizeObserver = null
  }

  // 销毁图表实例
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
})

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

// 监听窗口大小变化
const handleResize = () => {
  if (resizeTimer) {
    clearTimeout(resizeTimer)
  }

  // 使用防抖，避免频繁重绘
  resizeTimer = setTimeout(() => {
    if (chartInstance) {
      try {
        chartInstance.resize()
      } catch (error) {
        console.error('图表重绘失败:', error)
      }
    }
  }, 200)
}

// 初始化 ResizeObserver 监听容器大小变化
const initResizeListener = () => {
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize)

  // 如果浏览器支持 ResizeObserver，监听容器自身的大小变化
  if (typeof ResizeObserver !== 'undefined' && chartRef.value) {
    resizeObserver = new ResizeObserver((entries) => {
      for (let entry of entries) {
        if (entry.target === chartRef.value) {
          handleResize()
        }
      }
    })
    resizeObserver.observe(chartRef.value)
  }
}

const initChart = () => {
  if (!chartRef.value) return

  // 如果已有实例，先销毁
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }

  try {
    chartInstance = echarts.init(chartRef.value, 'macarons')
    setOptions(props.chartData)

    // 添加图表渲染完成后的重绘，确保初始尺寸正确
    nextTick(() => {
      if (chartInstance) {
        chartInstance.resize()
      }
    })
  } catch (error) {
    console.error('图表初始化失败:', error)
  }
}

const setOptions = ({ expectedData, actualData } = {}) => {
  if (!chartInstance) return

  try {
    chartInstance.setOption({
      tooltip: {
        trigger: 'axis',
        z: 30,
        show: true,
        showContent: true
      },
      xAxis: {
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        boundaryGap: false,
        axisTick: {
          show: false
        }
      },
      grid: {
        left: "5%",
        right: "5%",
        bottom: "5%",
        containLabel: true
      },
      yAxis: {
        axisTick: {
          show: false
        }
      },
      legend: {
        data: ['expected', 'actual'],
        top: "2%",
        textStyle: {
          color: '#666'
        }
      },
      series: [
        {
          name: 'expected',
          itemStyle: {
            color: '#FF005A'
          },
          lineStyle: {
            color: '#FF005A',
            width: 2
          },
          smooth: true,
          type: 'line',
          data: expectedData || [],
          animationDuration: 2800,
          animationEasing: 'cubicInOut'
        },
        {
          name: 'actual',
          smooth: true,
          type: 'line',
          itemStyle: {
            color: '#3888fa'
          },
          lineStyle: {
            color: '#3888fa',
            width: 2
          },
          areaStyle: {
            color: '#f3f8ff'
          },
          data: actualData || [],
          animationDuration: 2800,
          animationEasing: 'quadraticOut'
        }
      ]
    })
  } catch (error) {
    console.error('设置图表选项失败:', error)
  }
}

// 添加一个手动调整大小的方法，可以在父组件中调用
const resizeChart = () => {
  if (chartInstance) {
    chartInstance.resize()
  }
}

// 暴露方法给父组件
defineExpose({
  resizeChart
})
</script>