"use client"

import React, {useEffect, useRef} from "react"
import {
  type ECharts,
  type EChartsCoreOption,
  getInstanceByDom,
  init as echartsInit,
  type SetOptionOpts,
  use as echartsUse
} from "echarts/core"
import {BarChart, GaugeChart, LineChart, PieChart, RadarChart, ScatterChart} from "echarts/charts"
import {
  DatasetComponent,
  GraphicComponent,
  GridComponent,
  LegendComponent,
  TitleComponent,
  ToolboxComponent,
  TooltipComponent,
  VisualMapComponent,
} from "echarts/components"
import {CanvasRenderer} from "echarts/renderers"

echartsUse([
  BarChart,
  LineChart,
  PieChart,
  GaugeChart,
  RadarChart,
  ScatterChart,
  GridComponent,
  TooltipComponent,
  LegendComponent,
  TitleComponent,
  ToolboxComponent,
  VisualMapComponent,
  DatasetComponent,
  GraphicComponent,
  CanvasRenderer,
])

export type EChartProps = {
  option: EChartsCoreOption
  className?: string
  style?: React.CSSProperties
  theme?: "light" | "dark"
  opts?: SetOptionOpts
}

export default function EChart({ option, className, style, theme = "light", opts }: EChartProps) {
  const ref = useRef<HTMLDivElement | null>(null)
  const chartRef = useRef<ECharts | null>(null)

  useEffect(() => {
    if (!ref.current) return
    const el = ref.current

    let chart = getInstanceByDom(el)
    if (!chart) {
      chart = echartsInit(el, theme, { renderer: "canvas", locale: "ZH" })
    }
    chartRef.current = chart

    // Apply option
    chart.setOption(option, opts)

    const resize = () => chart && chart.resize()
    window.addEventListener("resize", resize)

    // Resize observer for container changes
    const ro = new ResizeObserver(() => resize())
    ro.observe(el)

    return () => {
      window.removeEventListener("resize", resize)
      ro.disconnect()
      // dispose only if element is being removed to avoid issues in fast refresh
      if (chart && !el.isConnected) {
        chart.dispose()
        chartRef.current = null
      }
    }
  }, [option, theme, opts])

  return <div ref={ref} className={className} style={{ width: "100%", height: 320, ...style }} />
}
