import { useEffect } from 'react'
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { act, render } from '@testing-library/react'
import type { ECharts } from 'echarts'
import { useEchartInstance } from './use-echart-instance'
import {
  clearAllWidgetStores,
  setEchartInstance,
} from './widget-store-registry'

const captured: { value: ECharts | null; renders: number } = {
  value: null,
  renders: 0,
}

function Probe({ id }: { id: string }) {
  const chart = useEchartInstance(id)
  // Capture in an effect so the React Compiler doesn't flag the
  // outside-component mutations during render.
  useEffect(() => {
    captured.value = chart
    captured.renders += 1
  })
  return null
}

beforeEach(() => {
  clearAllWidgetStores()
  captured.value = null
  captured.renders = 0
})
afterEach(() => clearAllWidgetStores())

function makeChart(): ECharts {
  return {} as unknown as ECharts
}

describe('useEchartInstance', () => {
  it('returns null when no instance is registered', () => {
    render(<Probe id='h1' />)
    expect(captured.value).toBeNull()
  })

  it('re-renders the consumer when the instance arrives', () => {
    render(<Probe id='h2' />)
    const initialRenders = captured.renders
    const chart = makeChart()
    act(() => setEchartInstance('h2', chart))
    expect(captured.value).toBe(chart)
    expect(captured.renders).toBeGreaterThan(initialRenders)
  })

  it('re-renders again when the instance changes', () => {
    render(<Probe id='h3' />)
    const a = makeChart()
    const b = makeChart()
    act(() => setEchartInstance('h3', a))
    expect(captured.value).toBe(a)
    act(() => setEchartInstance('h3', b))
    expect(captured.value).toBe(b)
  })

  it('re-renders with null when the instance is cleared', () => {
    render(<Probe id='h4' />)
    act(() => setEchartInstance('h4', makeChart()))
    expect(captured.value).not.toBeNull()
    act(() => setEchartInstance('h4', null))
    expect(captured.value).toBeNull()
  })

  it('isolates ids', () => {
    const latest: { a: ECharts | null; b: ECharts | null } = {
      a: null,
      b: null,
    }
    function ProbeMulti() {
      const a = useEchartInstance('h5-a')
      const b = useEchartInstance('h5-b')
      useEffect(() => {
        latest.a = a
        latest.b = b
      })
      return null
    }
    render(<ProbeMulti />)
    const aChart = makeChart()
    act(() => setEchartInstance('h5-a', aChart))
    expect(latest.a).toBe(aChart)
    expect(latest.b).toBeNull()
  })
})
