import { useMemo } from 'react';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import type { PlayStats } from '@tracearr/shared';
import { ChartSkeleton } from '@/components/ui/skeleton';

interface PlaysChartProps {
  data: PlayStats[] | undefined;
  isLoading?: boolean;
  height?: number;
  period?: 'day' | 'week' | 'month' | 'year' | 'all' | 'custom';
}

export function PlaysChart({ data, isLoading, height = 200, period = 'month' }: PlaysChartProps) {
  const options = useMemo<Highcharts.Options>(() => {
    if (!data || data.length === 0) {
      return {};
    }

    return {
      chart: {
        type: 'area',
        height,
        backgroundColor: 'transparent',
        style: {
          fontFamily: 'inherit',
        },
        reflow: true,
      },
      title: {
        text: undefined,
      },
      credits: {
        enabled: false,
      },
      legend: {
        enabled: false,
      },
      xAxis: {
        categories: data.map((d) => d.date),
        labels: {
          style: {
            color: 'hsl(var(--muted-foreground))',
          },
          formatter: function () {
            // this.value could be index (number) or category string depending on Highcharts version
            const categories = this.axis.categories;
            const categoryValue = typeof this.value === 'number'
              ? categories[this.value]
              : this.value;
            if (!categoryValue) return '';
            const date = new Date(categoryValue);
            if (isNaN(date.getTime())) return '';
            if (period === 'year') {
              // Short month name for yearly view (Dec, Jan, Feb)
              return date.toLocaleDateString('en-US', { month: 'short' });
            }
            // M/D format for week/month views
            return `${date.getMonth() + 1}/${date.getDate()}`;
          },
          step: Math.ceil(data.length / 12), // Show ~12 labels
        },
        lineColor: 'hsl(var(--border))',
        tickColor: 'hsl(var(--border))',
      },
      yAxis: {
        title: {
          text: undefined,
        },
        labels: {
          style: {
            color: 'hsl(var(--muted-foreground))',
          },
        },
        gridLineColor: 'hsl(var(--border))',
        min: 0,
      },
      plotOptions: {
        area: {
          fillColor: {
            linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
            stops: [
              [0, 'hsl(var(--primary) / 0.3)'],
              [1, 'hsl(var(--primary) / 0.05)'],
            ],
          },
          marker: {
            enabled: false,
            states: {
              hover: {
                enabled: true,
                radius: 4,
              },
            },
          },
          lineWidth: 2,
          lineColor: 'hsl(var(--primary))',
          states: {
            hover: {
              lineWidth: 2,
            },
          },
          threshold: null,
        },
      },
      tooltip: {
        backgroundColor: 'hsl(var(--popover))',
        borderColor: 'hsl(var(--border))',
        style: {
          color: 'hsl(var(--popover-foreground))',
        },
        formatter: function () {
          // With categories, this.x is the index. Use this.point.category for the actual value
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          const categoryValue = (this as any).point?.category as string | undefined;
          const date = categoryValue ? new Date(categoryValue) : null;
          const dateStr = date && !isNaN(date.getTime())
            ? date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })
            : 'Unknown';
          return `<b>${dateStr}</b><br/>Plays: ${this.y}`;
        },
      },
      series: [
        {
          type: 'area',
          name: 'Plays',
          data: data.map((d) => d.count),
        },
      ],
      responsive: {
        rules: [
          {
            condition: {
              maxWidth: 400,
            },
            chartOptions: {
              xAxis: {
                labels: {
                  style: {
                    fontSize: '9px',
                  },
                  step: Math.ceil(data.length / 6),
                },
              },
              yAxis: {
                labels: {
                  style: {
                    fontSize: '9px',
                  },
                },
              },
            },
          },
        ],
      },
    };
  }, [data, height, period]);

  if (isLoading) {
    return <ChartSkeleton height={height} />;
  }

  if (!data || data.length === 0) {
    return (
      <div
        className="flex items-center justify-center rounded-lg border border-dashed text-muted-foreground"
        style={{ height }}
      >
        No play data available
      </div>
    );
  }

  return (
    <HighchartsReact
      highcharts={Highcharts}
      options={options}
      containerProps={{ style: { width: '100%', height: '100%' } }}
    />
  );
}
