import { useEffect, useRef, useImperativeHandle } from 'react'
import * as echarts from 'echarts'
import type { EchartUIProps } from './types'
import { useWidgetRef } from '../../hooks'
import { observeResize } from './shared-resize-observer'

/**
 * Presentational component that initializes and manages an Apache ECharts instance.
 *
 * @remarks
 * Handles chart lifecycle (init, dispose), option updates, resize observation, and event listener management.
 * Uses SVG renderer with a default height of 304px.
 */
export function EchartUI(props: EchartUIProps) {
  const { id, ref, init, option, className, style, onEvents } = props

  const { ref: chartRef, instance: chartInstanceRef } =
    useWidgetRef<HTMLDivElement>(id)
  const chartInstance = useRef<echarts.ECharts>(null)

  useImperativeHandle(ref, () => chartInstance.current!, [])

  useEffect(() => {
    if (!chartRef.current) return

    chartInstance.current = echarts.init(chartRef.current, null, {
      renderer: 'svg',
      height: 304,
      ...init,
    })
    chartInstanceRef.current = chartInstance.current
    // Cleanup function
    return () => {
      chartInstance.current?.dispose()
      chartInstance.current = null
      chartInstanceRef.current = null
    }
  }, [chartInstanceRef, chartRef, init])

  // Update chart when options change
  useEffect(() => {
    chartInstance.current?.setOption(option, {
      lazyUpdate: true,
      notMerge: true,
    })
  }, [option])

  // Handle resize using shared ResizeObserver (single instance for all charts)
  useEffect(() => {
    if (!chartRef.current) return

    return observeResize(chartRef.current, () => {
      chartInstance.current?.resize()
    })
  }, [chartRef])

  useEffect(() => {
    const _onEvents = { ...(onEvents ?? {}) }
    if (!_onEvents.click) {
      _onEvents.mousemove = () => {
        chartInstance.current?.getZr().setCursorStyle('default')
      }
    }

    // Attach event listeners
    Object.entries(_onEvents).forEach(([event, handler]) => {
      chartInstance.current?.on(event, handler)
    })
    // Cleanup function to remove event listeners
    return () => {
      Object.entries(_onEvents).forEach(([event]) => {
        chartInstance.current?.off(event)
      })
    }
  }, [onEvents])

  return <div id={id} ref={chartRef} style={style} className={className} />
}
