import { useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import type { CrimeYearPoint } from '../../types';

interface CrimeYearChartProps {
  points: CrimeYearPoint[];
  /**
   * Latest year available in the crime dataset as a whole. When the series
   * ends earlier, the area's police force stopped publishing (e.g. Greater
   * Manchester since mid-2019) and the chart is captioned as stale.
   */
  latestAvailableYear?: number;
}

const PADDING = { top: 6, right: 4, bottom: 14, left: 4 };
const HEIGHT = 48;

export default function CrimeYearChart({ points, latestAvailableYear }: CrimeYearChartProps) {
  const { t } = useTranslation();
  const containerRef = useRef<HTMLDivElement>(null);
  const [width, setWidth] = useState(0);

  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    const observer = new ResizeObserver((entries) => {
      const w = entries[0].contentRect.width;
      if (w > 0) setWidth(w);
    });
    observer.observe(el);
    return () => observer.disconnect();
  }, []);

  const { yearMin, yearMax, max } = useMemo(() => {
    let yMin = Infinity;
    let yMax = -Infinity;
    let m = 0;
    for (const p of points) {
      if (p.year < yMin) yMin = p.year;
      if (p.year > yMax) yMax = p.year;
      if (p.count > m) m = p.count;
    }
    return { yearMin: yMin, yearMax: yMax, max: m };
  }, [points]);

  if (points.length === 0) {
    return null;
  }

  const plotW = Math.max(0, width - PADDING.left - PADDING.right);
  const plotH = HEIGHT - PADDING.top - PADDING.bottom;
  const yearRange = Math.max(1, yearMax - yearMin);
  const scaleMax = max > 0 ? max : 1;

  const scaleX = (year: number) => PADDING.left + ((year - yearMin) / yearRange) * plotW;
  const scaleY = (count: number) => PADDING.top + (1 - count / scaleMax) * plotH;

  const baseline = PADDING.top + plotH;
  const lineFill = points
    .map((p, i) => `${i === 0 ? 'M' : 'L'}${scaleX(p.year)},${scaleY(p.count)}`)
    .join(' ');
  const areaFill = `${lineFill} L${scaleX(yearMax)},${baseline} L${scaleX(yearMin)},${baseline} Z`;

  return (
    <div ref={containerRef} className="w-full">
      {width > 0 && (
        <svg width={width} height={HEIGHT} className="block">
          <path d={areaFill} className="fill-rose-400/30 dark:fill-rose-500/25" />
          <path
            d={lineFill}
            fill="none"
            strokeWidth={1.5}
            strokeLinejoin="round"
            strokeLinecap="round"
            className="stroke-rose-600 dark:stroke-rose-400"
          />
          {points.map((p) => (
            <circle
              key={p.year}
              cx={scaleX(p.year)}
              cy={scaleY(p.count)}
              r={1.6}
              className="fill-rose-700 dark:fill-rose-300"
            >
              <title>{`${p.year}: ${p.count.toFixed(1)}/yr`}</title>
            </circle>
          ))}
          <text
            x={scaleX(yearMin)}
            y={HEIGHT - 2}
            textAnchor="start"
            fontSize={9}
            className="fill-warm-500 dark:fill-warm-400"
          >
            {yearMin}
          </text>
          <text
            x={scaleX(yearMax)}
            y={HEIGHT - 2}
            textAnchor="end"
            fontSize={9}
            className="fill-warm-500 dark:fill-warm-400"
          >
            {yearMax}
          </text>
        </svg>
      )}
      {latestAvailableYear != null && yearMax < latestAvailableYear && (
        <p className="mt-0.5 text-[10px] leading-snug text-amber-700 dark:text-amber-400">
          {t('areaPane.crimeDataEnds', { year: yearMax })}
        </p>
      )}
    </div>
  );
}
