import { onMounted, onUnmounted, watch, ref, nextTick, type Ref } from 'vue'
import * as echarts from 'echarts'

export function useSafeChart(
  chartRef: Ref<HTMLDivElement | null>,
  option: Ref<echarts.EChartsOption>
) {
  const chartInstance = ref<echarts.ECharts | null>(null)
  let isAlive = true

  const shouldInjectGraphic = (opt: echarts.EChartsOption): boolean => {
    const series = opt?.series
    if (!Array.isArray(series) || series.length === 0) return true

    const firstSeries = series[0]
    const data = firstSeries?.data

    return !Array.isArray(data) || data.length === 0
  }

  const getEmptyGraphic = (): echarts.EChartsOption['graphic'] => [
    {
      type: 'text',
      left: 'center',
      top: 'middle',
      style: {
        text: '暂无数据',
        fontSize: 16,
        fill: '#9cc5e0',
      },
    },
  ]

  const applyOption = (opt: echarts.EChartsOption) => {
    if (!chartInstance.value) return

    const enhancedOption = {
      ...opt,
      graphic: shouldInjectGraphic(opt)
        ? getEmptyGraphic()
        : Array.isArray(opt.graphic)
          ? opt.graphic
          : [],
    }

    chartInstance.value.setOption(enhancedOption, true)
  }

  const initChart = () => {
    const dom = chartRef.value
    if (!dom || dom.offsetWidth === 0) return

    const existing = echarts.getInstanceByDom(dom)
    if (existing) echarts.dispose(dom)

    chartInstance.value = echarts.init(dom)
    applyOption(option.value)
  }

  const resizeChart = () => {
    const chart = chartInstance.value
    const dom = chart?.getDom()

    if (!isAlive || !chart || !dom || dom.offsetWidth === 0) return

    try {
      chart.resize()
    } catch (error) {
      console.warn('Chart resize failed, attempting recovery:', error)

      try {
        echarts.dispose(dom)
        const newChart = echarts.init(dom)
        chartInstance.value = newChart
        applyOption(option.value)
      } catch (retryError) {
        console.error('Chart recovery failed:', retryError)
      }
    }
  }

  onMounted(() => {
    nextTick(() => {
      initChart()
      window.addEventListener('resize', resizeChart)
    })
  })

  onUnmounted(() => {
    isAlive = false
    window.removeEventListener('resize', resizeChart)
    if (chartInstance.value) {
      try {
        chartInstance.value.dispose()
      } catch (error) {
        console.warn('Chart dispose failed:', error)
      }
      chartInstance.value = null
    }
  })

  watch(
    option,
    (newOption) => {
      applyOption(newOption)
    },
    { deep: true }
  )

  return {
    chartInstance,
  }
}
