'use client'

import type { ApexOptions } from 'apexcharts'
import React from 'react'
import { cn } from '../../utils/cn'
import {
  useChartOptions,
  createChartTooltip,
  mergeChartOptions,
} from './chart.config'
import { useChartTicks } from './useChartTicks'

export type AxisChartSeries = Array<{
  name: string
  color?: string
  type?: 'area' | 'line' | 'bar'
  data: Array<{
    x: string
    y: number | null
  }>
}>

export type NonAxisChartSeries = number[]

export type ChartProps = {
  series: AxisChartSeries | NonAxisChartSeries
  type?: 'area' | 'line' | 'bar' | 'pie' | 'donut' | 'radialBar'
  options?: ApexOptions
  width?: string | number
  height?: string | number
  formatX?: (value: string) => string
  formatY?: (value: number) => string
  formatTooltipX?: (value: string) => string
  formatTooltipY?: (value: number) => string
  xAxisLabel?: string
  yAxisLabel?: string
  showLegend?: boolean
}

export const Chart = ({
  series,
  type,
  options: customChartOptions = {},
  width = '100%',
  height = '100%',
  formatX = (value) => `${value}`,
  formatY = (value) => `${value}`,
  formatTooltipX = (value) => `${value}`,
  formatTooltipY = (value) => `${value}`,
  xAxisLabel,
  yAxisLabel,
  showLegend = false,
}: ChartProps) => {
  const [ReactApexChart, setReactApexChart] = React.useState<any>(null)
  const chartRef = React.useRef<HTMLDivElement | null>(null)

  const isDatetimeChart = customChartOptions?.xaxis?.type === 'datetime'
  const tickAmount = useChartTicks(isDatetimeChart ? null : chartRef)

  React.useEffect(() => {
    void import('react-apexcharts').then((module) => {
      setReactApexChart(() => module.default)
    })
  }, [])

  const defaultOptions = useChartOptions()

  const mutableOptions: ApexOptions = React.useMemo(
    () => ({
      chart: {
        type,
      },
      xaxis: {
        labels: {
          formatter: (value: string) => formatX(value),
        },
        title: {
          text: xAxisLabel,
        },
        ...(tickAmount && { tickAmount }),
      },
      yaxis: {
        labels: {
          formatter: (value: number) => (value !== 0 ? formatY(value) : ''),
        },
        title: {
          text: yAxisLabel,
        },
      },
      legend: {
        show: showLegend,
      },
      tooltip: {
        enabled: true,
        shared: true,
        custom: createChartTooltip(formatTooltipX, formatTooltipY),
      },
    }),
    [
      type,
      formatX,
      formatY,
      formatTooltipX,
      formatTooltipY,
      xAxisLabel,
      yAxisLabel,
      showLegend,
      tickAmount,
    ],
  )

  const mergedOptions = React.useMemo(
    () => mergeChartOptions(defaultOptions, mutableOptions, customChartOptions),
    [defaultOptions, mutableOptions, customChartOptions],
  )

  if (!ReactApexChart) return null // Avoid SSR issues

  return (
    <div
      className={cn(
        'h-full w-full',
        // ApexCharts tooltip lives under this host; arbitrary selectors avoid a global CSS import (Next / Turbopack).
        '[&_.apexcharts-tooltip]:!border-0 [&_.apexcharts-tooltip]:!bg-transparent [&_.apexcharts-tooltip]:!pl-1.5 [&_.apexcharts-tooltip]:!pr-3.5 [&_.apexcharts-tooltip]:!shadow-none',
      )}
      ref={chartRef}
    >
      <ReactApexChart
        type={type}
        series={series}
        options={mergedOptions}
        width={width}
        height={height}
      />
    </div>
  )
}
