/**
 * Map color utilities for World Map visualization.
 *
 * Provides color interpolation logic that maps ban counts to colors based on
 * configurable thresholds. Countries with zero bans remain transparent;
 * non-zero counts are interpolated through green → yellow → red color stops.
 */

/**
 * Interpolate a value between two numbers.
 *
 * @param start - Start value
 * @param end - End value
 * @param t - Interpolation factor in [0, 1]
 * @returns The interpolated value
 */
function lerp(start: number, end: number, t: number): number {
  return start + (end - start) * t;
}

/**
 * Convert RGB values to hex color string.
 *
 * @param r - Red component (0-255)
 * @param g - Green component (0-255)
 * @param b - Blue component (0-255)
 * @returns Hex color string in format "#RRGGBB"
 */
function rgbToHex(r: number, g: number, b: number): string {
  const toHex = (n: number): string => {
    const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);
    return hex.length === 1 ? "0" + hex : hex;
  };
  return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}

/**
 * Compute the fill color for a country based on its ban count.
 *
 * Returns "transparent" for zero bans. For non-zero counts, interpolates
 * through color stops:
 * - 1 to threshold_low: light green → full green
 * - threshold_low to threshold_medium: green → yellow
 * - threshold_medium to threshold_high: yellow → red
 * - threshold_high or more: solid red
 *
 * @param banCount - Number of bans for the country
 * @param thresholdLow - Ban count for green coloring (default: 20)
 * @param thresholdMedium - Ban count for yellow coloring (default: 50)
 * @param thresholdHigh - Ban count for red coloring (default: 100)
 * @returns Hex color string or "transparent"
 */
export function getBanCountColor(
  banCount: number,
  thresholdLow: number = 20,
  thresholdMedium: number = 50,
  thresholdHigh: number = 100,
): string {
  // Zero bans → transparent (no fill)
  if (banCount === 0) {
    return "transparent";
  }

  // Color stops
  const lightGreen = { r: 144, g: 238, b: 144 }; // #90EE90
  const green = { r: 0, g: 128, b: 0 }; // #008000
  const yellow = { r: 255, g: 255, b: 0 }; // #FFFF00
  const red = { r: 220, g: 20, b: 60 }; // #DC143C (crimson)

  // 1 to threshold_low: interpolate light green → green
  if (banCount <= thresholdLow) {
    const t = (banCount - 1) / (thresholdLow - 1);
    const r = lerp(lightGreen.r, green.r, t);
    const g = lerp(lightGreen.g, green.g, t);
    const b = lerp(lightGreen.b, green.b, t);
    return rgbToHex(r, g, b);
  }

  // threshold_low to threshold_medium: interpolate green → yellow
  if (banCount <= thresholdMedium) {
    const t = (banCount - thresholdLow) / (thresholdMedium - thresholdLow);
    const r = lerp(green.r, yellow.r, t);
    const g = lerp(green.g, yellow.g, t);
    const b = lerp(green.b, yellow.b, t);
    return rgbToHex(r, g, b);
  }

  // threshold_medium to threshold_high: interpolate yellow → red
  if (banCount <= thresholdHigh) {
    const t = (banCount - thresholdMedium) / (thresholdHigh - thresholdMedium);
    const r = lerp(yellow.r, red.r, t);
    const g = lerp(yellow.g, red.g, t);
    const b = lerp(yellow.b, red.b, t);
    return rgbToHex(r, g, b);
  }

  // threshold_high or more: solid red
  return rgbToHex(red.r, red.g, red.b);
}
