"use client"
import React, { useCallback, useMemo, useState } from "react"
import { createContext } from "use-context-selector"

type Range = [number | undefined, number | undefined]

type ChartContextType = {
  isZoomed: boolean
  isPanning: boolean
  hoveredPoint: Highcharts.Point | undefined
  resetZoom: () => void
  reflow: () => void
  redraw: () => void
  setChart: React.Dispatch<React.SetStateAction<Highcharts.Chart | undefined>>
  setIsZoomed: React.Dispatch<React.SetStateAction<boolean>>
  setIsPanning: React.Dispatch<React.SetStateAction<boolean>>
  setXAxisRange: React.Dispatch<React.SetStateAction<Range | undefined>>
  setHoveredPoint: React.Dispatch<
    React.SetStateAction<Highcharts.Point | undefined>
  >
}

export const ChartContext = createContext<ChartContextType>({
  isZoomed: false,
  isPanning: false,
  hoveredPoint: undefined,
  resetZoom: () => {},
  reflow: () => {},
  redraw: () => {},
  setChart: () => {},
  setIsZoomed: () => {},
  setIsPanning: () => {},
  setXAxisRange: () => {},
  setHoveredPoint: () => {},
})

type ChartContextProviderProps = {
  children: React.ReactNode
}

export const ChartContextProvider = ({
  children,
}: ChartContextProviderProps) => {
  const [chart, setChart] = useState<Highcharts.Chart>()
  const [isZoomed, setIsZoomed] = useState(false)
  const [isPanning, setIsPanning] = useState(false)
  const [xAxisRange, setXAxisRange] = useState<Range>()
  const [hoveredPoint, setHoveredPoint] = useState<
    Highcharts.Point | undefined
  >(undefined)

  const resetZoom = useCallback(() => {
    if (xAxisRange) {
      chart?.xAxis[0].setExtremes(...xAxisRange)
      // reset to default y-axis range since we only support fixed ranges for x-axis
      chart?.yAxis[0].setExtremes(undefined, undefined)
    } else {
      chart?.zoomOut()
    }
  }, [chart, xAxisRange])

  const reflow = useCallback(() => {
    chart?.reflow()
  }, [chart])

  const redraw = useCallback(() => {
    chart?.redraw()
  }, [chart])

  const value = useMemo(
    () => ({
      isZoomed,
      isPanning,
      hoveredPoint,
      resetZoom,
      reflow,
      redraw,
      setChart,
      setIsZoomed,
      setIsPanning,
      setXAxisRange,
      setHoveredPoint,
    }),
    [hoveredPoint, isPanning, isZoomed, reflow, resetZoom, redraw],
  )

  return <ChartContext.Provider value={value}>{children}</ChartContext.Provider>
}
