/**
 * Brand-aligned Lottie tinting (Tailwind theme tokens → normalized RGBA).
 * Primary: #5750F1 — slightly lifted in dark mode for contrast on `dark` bg.
 */

export type LottieThemeMode = "light" | "dark";

/** #5750F1 */
const PRIMARY_LIGHT = [87 / 255, 80 / 255, 241 / 255, 1] as const;
/** Brighter violet for fills on #111928 */
const PRIMARY_ON_DARK = [125 / 255, 118 / 255, 252 / 255, 1] as const;

function deepClone<T>(value: T): T {
  return JSON.parse(JSON.stringify(value)) as T;
}

function colorsMatch(a: unknown, b: readonly number[]): boolean {
  if (!Array.isArray(a) || a.length !== 4) return false;
  return a.every(
    (v, i) => typeof v === "number" && Math.abs(v - b[i]!) < 0.0001,
  );
}

/**
 * Replace exact RGBA quadruples anywhere in the JSON tree (Lottie uses nested `c.k`).
 */
function replaceRgbaEverywhere(
  node: unknown,
  from: readonly number[],
  to: readonly number[],
): unknown {
  if (node === null || typeof node !== "object") {
    return node;
  }
  if (Array.isArray(node)) {
    if (colorsMatch(node, from)) {
      return [...to];
    }
    return node.map((item) => replaceRgbaEverywhere(item, from, to));
  }
  const out: Record<string, unknown> = {};
  for (const [k, v] of Object.entries(node)) {
    out[k] = replaceRgbaEverywhere(v, from, to);
  }
  return out;
}

/** Pure black fills/strokes → brand primary (loading spinner dots, etc.). */
export function applyLoadingLottieTheme<T extends object>(
  data: T,
  mode: LottieThemeMode,
): T {
  const clone = deepClone(data);
  const to = mode === "dark" ? PRIMARY_ON_DARK : PRIMARY_LIGHT;
  return replaceRgbaEverywhere(clone, [0, 0, 0, 1], to) as T;
}

/**
 * Full illustrations (e.g. 404): clone only until we add palette maps per asset.
 */
export function applyIllustrationLottieTheme<T extends object>(
  data: T,
  _mode: LottieThemeMode,
): T {
  return deepClone(data);
}
