// src/components/keywords/sparkline.tsx
import { useId } from "react";

const PAD = 2;

/** Build an SVG path `d` mapping values across width×height (y inverted). */
export function sparklinePath(
  values: number[],
  width: number,
  height: number,
): string {
  if (values.length === 0) return "";
  const mid = height / 2;
  if (values.length === 1) return `M0,${mid} L0,${mid}`;

  const min = Math.min(...values);
  const max = Math.max(...values);
  const span = max - min;
  const innerH = height - PAD * 2;
  const stepX = width / (values.length - 1);

  const y = (v: number) =>
    span === 0 ? mid : PAD + innerH * (1 - (v - min) / span);

  return values
    .map((v, i) => `${i === 0 ? "M" : "L"}${i * stepX},${y(v)}`)
    .join(" ");
}

/**
 * Map a growth % to a colour: green ramp up, red ramp down, amber when flat.
 * Stronger magnitude → more vivid/darker, so the colour itself reads the trend.
 */
export function trendColor(growth: number): string {
  const mag = Math.min(Math.abs(growth) / 40, 1);
  if (growth > 2) return `hsl(152 ${55 + mag * 25}% ${48 - mag * 8}%)`;
  if (growth < -2) return `hsl(2 ${55 + mag * 25}% ${54 - mag * 8}%)`;
  return "hsl(40 92% 50%)";
}

/**
 * % slope of a series: last vs first point (base guarded to 1 when the
 * first value is 0). Fallback colour driver when no growth % is provided.
 */
export function slopePct(values: number[]): number {
  if (values.length < 2) return 0;
  return ((values[values.length - 1] - values[0]) / (values[0] || 1)) * 100;
}

export function Sparkline({
  values,
  growth,
  width = 88,
  height = 24,
  className,
  preserveAspectRatio,
}: {
  values: number[];
  /** growth % driving the colour; falls back to series slope if omitted */
  growth?: number;
  width?: number;
  height?: number;
  className?: string;
  /** pass "none" + a w-full className to stretch the spark to its container */
  preserveAspectRatio?: string;
}) {
  const gid = useId();
  const d = sparklinePath(values, width, height);
  const g = growth ?? slopePct(values);
  const color = trendColor(g);
  const rising = g >= 0;

  // close the line down to the baseline for a subtle gradient fill
  const area = d ? `${d} L${width},${height} L0,${height} Z` : "";

  return (
    <svg
      width={width}
      height={height}
      viewBox={`0 0 ${width} ${height}`}
      preserveAspectRatio={preserveAspectRatio}
      className={className}
      role="img"
      aria-label={
        rising
          ? `Tendance à la hausse (${g > 0 ? "+" : ""}${Math.round(g)}%)`
          : `Tendance à la baisse (${Math.round(g)}%)`
      }
    >
      <defs>
        <linearGradient id={`spark-fill-${gid}`} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity={0.3} />
          <stop offset="100%" stopColor={color} stopOpacity={0} />
        </linearGradient>
      </defs>
      {area ? (
        <path d={area} fill={`url(#spark-fill-${gid})`} stroke="none" />
      ) : null}
      <path
        d={d}
        fill="none"
        stroke={color}
        strokeWidth={1.5}
        strokeLinecap="round"
        strokeLinejoin="round"
        vectorEffect="non-scaling-stroke"
      />
    </svg>
  );
}
