function clampInt(n: number, min: number, max: number): number {
  if (!Number.isFinite(n)) return min;
  return Math.min(max, Math.max(min, Math.floor(n)));
}

function hashStringToInt32(input: string): number {
  // 简单可复现 hash：用于把 seed 映射为偏移量（不用于安全场景）
  let h = 0;
  for (let i = 0; i < input.length; i += 1) {
    // eslint-disable-next-line no-bitwise
    h = (h * 31 + input.charCodeAt(i)) | 0;
  }
  return h;
}

/**
 * 生成 t ∈ [0,1]，用于 Color(t)=lerp(top,bottom,t)
 *
 * 说明：
 * - Home 没有 scroll，用“切换文案 step_index”模拟连续流动
 * - 采用往返波形，避免从 1 回到 0 的突跳
 */
export function computeTFromStep(args: {
  stepIndex: number;
  segments?: number; // N，默认 12
  seed?: string; // 允许用 seed 做初始相位偏移（同一次冷启动内稳定）
}): number {
  const N = clampInt(args.segments ?? 12, 3, 60);
  const stepIndex = clampInt(args.stepIndex, 0, 1_000_000_000);
  const period = 2 * (N - 1);

  const seed = String(args.seed ?? '');
  const offset = seed ? Math.abs(hashStringToInt32(seed)) % period : 0;

  const phase = (stepIndex + offset) % period;
  const up = phase <= (N - 1);
  const pos = up ? phase : period - phase;
  return pos / (N - 1);
}

