import { RegionEvolutionPoint } from "../../../models/RegionEvolution";

export const WIDTH = 950;
export const HEIGHT = 380;
export const MARGIN = { top: 20, right: 20, bottom: 55, left: 60 };

export const AVAILABLE_YEARS = [2019, 2020, 2021, 2022, 2023];

export function extent(values: number[]): [number, number] {
  let min = Infinity;
  let max = -Infinity;
  for (const v of values) {
    if (v < min) min = v;
    if (v > max) max = v;
  }
  return [min, max];
}

export function scaleLinear(domain: [number, number], range: [number, number]) {
  const [d0, d1] = domain;
  const [r0, r1] = range;
  const m = d1 === d0 ? 0 : (r1 - r0) / (d1 - d0);
  return (x: number) => r0 + (x - d0) * m;
}

export function padDomain([min, max]: [number, number], ratio = 0.15): [number, number] {
  if (!isFinite(min) || !isFinite(max)) return [0, 1];
  if (min === max) return [min - 1, max + 1];
  const pad = (max - min) * ratio;
  return [min - pad, max + pad];
}

export function buildPath(points: { x: number; y: number }[]) {
  if (points.length === 0) return "";
  return points
    .map((p, i) => `${i === 0 ? "M" : "L"} ${p.x.toFixed(2)} ${p.y.toFixed(2)}`)
    .join(" ");
}

export function colorForRegion(name: string) {
  const palette = [
    "#6366f1",
    "#8b5cf6",
    "#ec4899",
    "#10b981",
    "#3b82f6",
    "#f59e0b",
    "#06b6d4",
    "#a855f7",
    "#84cc16",
    "#f43f5e",
  ];
  let hash = 0;
  for (let i = 0; i < name.length; i++) hash = (hash * 31 + name.charCodeAt(i)) >>> 0;
  return palette[hash % palette.length];
}

export function groupByRegion(raw: RegionEvolutionPoint[]) {
  const map = new Map<string, RegionEvolutionPoint[]>();
  for (const p of raw) {
    if (!map.has(p.regionName)) map.set(p.regionName, []);
    map.get(p.regionName)!.push(p);
  }
  for (const [name, arr] of Array.from(map.entries())) {
    arr.sort((a, b) => a.year - b.year);
    map.set(name, arr);
  }
  return map;
}
export function distanceToSegment(
  px: number,
  py: number,
  x1: number,
  y1: number,
  x2: number,
  y2: number
) {
  const dx = x2 - x1;
  const dy = y2 - y1;
  if (dx === 0 && dy === 0) return Math.hypot(px - x1, py - y1);

  const t = Math.max(
    0,
    Math.min(1, ((px - x1) * dx + (py - y1) * dy) / (dx * dx + dy * dy))
  );
  const projX = x1 + t * dx;
  const projY = y1 + t * dy;
  return Math.hypot(px - projX, py - projY);
}

