/**
 * Interpolação 1D em escala log (eixo X) — usada para gráficos como
 * Figura 4 e Figura 5 (arrasto por h/l₁, h/l₂ em escala log) e para
 * interpolar S₂ entre alturas discretas da Tabela 3.
 *
 * Para pontos fora do intervalo, faz clamp nos extremos.
 */

function findBracket(xs: readonly number[], x: number): [number, number] {
  if (xs.length === 0) throw new Error('Vetor vazio');
  const clamped = Math.max(xs[0], Math.min(x, xs[xs.length - 1]));
  if (xs.length === 1) return [0, 0];
  for (let i = 0; i < xs.length - 1; i++) {
    if (clamped >= xs[i] && clamped <= xs[i + 1]) {
      return [i, i + 1];
    }
  }
  return [0, xs.length - 1];
}

export function logInterp1D(
  xs: readonly number[],
  ys: readonly number[],
  x: number,
): number {
  if (xs.length !== ys.length) throw new Error('xs e ys devem ter mesmo tamanho');
  if (xs.length === 0) throw new Error('Vetores vazios');
  if (x <= 0) throw new Error('x deve ser > 0 para interpolação log');

  if (xs.length === 1) return ys[0];

  const [i0, i1] = findBracket(xs, x);
  const x0 = xs[i0];
  const x1 = xs[i1];
  if (x0 === x1) return ys[i0];

  const lx = Math.log(x);
  const lx0 = Math.log(x0);
  const lx1 = Math.log(x1);

  const t = (lx - lx0) / (lx1 - lx0);
  return ys[i0] * (1 - t) + ys[i1] * t;
}

/** Interpolação 1D linear (sem transformação log) */
export function linearInterp1D(
  xs: readonly number[],
  ys: readonly number[],
  x: number,
): number {
  if (xs.length !== ys.length) throw new Error('xs e ys devem ter mesmo tamanho');
  if (xs.length === 0) throw new Error('Vetores vazios');
  if (xs.length === 1) return ys[0];

  const [i0, i1] = findBracket(xs, x);
  const x0 = xs[i0];
  const x1 = xs[i1];
  if (x0 === x1) return ys[i0];
  const t = (x - x0) / (x1 - x0);
  return ys[i0] * (1 - t) + ys[i1] * t;
}