import { Skeleton } from '@/components/ui/skeleton';
import { useTheme } from '@/context/theme-context';
import { useCurrency } from '@/hooks/use-currency';
import { useApiSWR } from '@/hooks/useSWR';
import { Suspense, useState } from 'react';
import Chart from 'react-apexcharts';
import { useTranslation } from 'react-i18next';

type ChartPoint = {
  date: string;
  earnings: number;
  signups: number;
};

const RANGES = [
  { label: '7D', days: 7 },
  { label: '30D', days: 30 },
] as const;

interface ReferralChartProps {
  brand?: string;
}

export default function ReferralChart({
  brand = 'Rewards',
}: ReferralChartProps) {
  const { t } = useTranslation();
  const { theme } = useTheme();
  const { format } = useCurrency();
  const [range, setRange] = useState<(typeof RANGES)[number]>(RANGES[1]);

  const { data, isLoading } = useApiSWR<ChartPoint[]>('/user/referrals/chart');

  const isDark = theme === 'dark';
  const textColor = isDark ? 'rgba(255,255,255,0.4)' : 'rgba(0,0,0,0.4)';
  const gridColor = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)';
  const accent = 'var(--pm-accent)';

  const points = (data ?? []).slice(-range.days);
  const series = [
    {
      name: t('Earnings'),
      data: points.map((p) => [new Date(p.date).getTime(), p.earnings]) as [
        number,
        number,
      ][],
    },
  ];

  const hasData = points.some((p) => p.earnings > 0);

  const options: ApexCharts.ApexOptions = {
    chart: {
      type: 'area',
      background: 'transparent',
      toolbar: { show: false },
      zoom: { enabled: false },
      animations: { enabled: true, speed: 400 },
    },
    colors: [isDark ? 'rgba(125, 145, 255, 0.9)' : 'oklch(0.53 0.18 268)'],
    stroke: { curve: 'smooth', width: 2 },
    fill: {
      type: 'gradient',
      gradient: {
        shadeIntensity: 1,
        opacityFrom: 0.22,
        opacityTo: 0.02,
        stops: [0, 100],
      },
    },
    xaxis: {
      type: 'datetime',
      labels: {
        datetimeUTC: false,
        format: 'MMM d',
        style: { colors: textColor, fontSize: '11px' },
      },
      axisBorder: { show: false },
      axisTicks: { show: false },
    },
    yaxis: {
      opposite: true,
      forceNiceScale: true,
      min: 0,
      tickAmount: 4,
      labels: {
        formatter: (v) => format(v, 'code'),
        style: { colors: textColor, fontSize: '11px' },
      },
    },
    markers: { size: 0 },
    grid: {
      borderColor: gridColor,
      strokeDashArray: 4,
      xaxis: { lines: { show: false } },
      padding: { left: 4, right: 4 },
    },
    dataLabels: { enabled: false },
    legend: { show: false },
    tooltip: {
      theme: isDark ? 'dark' : 'light',
      x: { format: 'MMM dd' },
      y: { formatter: (v) => format(v, 'code') },
    },
  };

  return (
    <div className="relative">
      {/* Range toggle */}
      <div className="mb-2 flex items-center justify-between">
        <div className="flex items-center gap-2 text-sm font-semibold text-black/25 dark:text-white/25">
          <span
            aria-hidden
            className="grid size-5 place-items-center rounded-md"
            style={{ background: accent, opacity: 0.9 }}
          >
            <span className="block size-2 rotate-45 bg-white" />
          </span>
          {brand}
        </div>
        <div className="flex gap-1">
          {RANGES.map((r) => (
            <button
              key={r.label}
              type="button"
              onClick={() => setRange(r)}
              className={
                range.label === r.label
                  ? 'rounded-md bg-black/10 px-2 py-0.5 text-xs font-medium text-black dark:bg-white/10 dark:text-white'
                  : 'rounded-md px-2 py-0.5 text-xs font-medium text-black/40 transition-colors hover:text-black/70 dark:text-white/40 dark:hover:text-white/70'
              }
            >
              {r.label}
            </button>
          ))}
        </div>
      </div>

      {isLoading ? (
        <Skeleton className="h-[260px] w-full rounded-xl" />
      ) : !hasData ? (
        <div className="relative flex h-[260px] items-center justify-center">
          <span
            className="pointer-events-none absolute inset-0 grid place-items-center text-3xl font-bold text-black/5 dark:text-white/5"
            aria-hidden
          >
            {brand}
          </span>
          <span className="relative text-sm text-black/40 dark:text-white/40">
            {t('No referral earnings yet.')}
          </span>
        </div>
      ) : (
        <Suspense
          fallback={<Skeleton className="h-[260px] w-full rounded-xl" />}
        >
          <Chart
            options={options}
            series={series}
            type="area"
            width="100%"
            height={260}
          />
        </Suspense>
      )}

      <p className="mt-1 text-right text-xs text-black/30 dark:text-white/30">
        {t('Data updates every 30 minutes')}
      </p>
    </div>
  );
}
