/**
 * White/black mix ratios tuned to match Tailwind neutral scales (zinc reference).
 * PrimeUIX palette() uses uniform 19% steps toward white, which makes surface-50
 * vs surface-100 far too distinct for UI neutrals.
 */
const LIGHT_MIX = {
  50: 0.965,
  100: 0.923,
  200: 0.81,
  300: 0.697,
  400: 0.338,
};

const DARK_MIX = {
  600: 0.274,
  700: 0.442,
  800: 0.655,
  900: 0.788,
  950: 0.921,
};

const SURFACE_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];

function normalizeHex(hex) {
  if (typeof hex !== "string" || !/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(hex)) {
    return null;
  }
  if (hex.length === 4) {
    const [, r, g, b] = hex;
    return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();
  }
  return hex.toLowerCase();
}

function hexToRgb(hex) {
  const normalized = normalizeHex(hex);
  if (!normalized) {
    return null;
  }
  const value = parseInt(normalized.slice(1), 16);
  return [(value >> 16) & 255, (value >> 8) & 255, value & 255];
}

function rgbToHex([r, g, b]) {
  return `#${[r, g, b]
    .map((channel) => Math.max(0, Math.min(255, channel)).toString(16).padStart(2, "0"))
    .join("")}`;
}

function mixTowardWhite(rgb, ratio) {
  return rgb.map((channel) => Math.round(channel + (255 - channel) * ratio));
}

function mixTowardBlack(rgb, ratio) {
  return rgb.map((channel) => Math.round(channel * (1 - ratio)));
}

/**
 * Build a full surface palette from a single mid-tone hex (shade 500).
 *
 * @param {string} hex
 * @returns {Record<string, string>}
 */
export function buildNeutralSurfacePalette(hex) {
  const normalized = normalizeHex(hex);
  const baseRgb = hexToRgb(normalized);
  if (!baseRgb || !normalized) {
    return {};
  }

  const palette = {
    0: "#ffffff",
    500: normalized,
  };

  for (const step of SURFACE_STEPS) {
    if (step === 500) {
      continue;
    }

    if (step < 500) {
      palette[step] = rgbToHex(mixTowardWhite(baseRgb, LIGHT_MIX[step]));
      continue;
    }

    palette[step] = rgbToHex(mixTowardBlack(baseRgb, DARK_MIX[step]));
  }

  return palette;
}
