const getDownsampledBounds = (buffer: Float32Array, numOutputSamples: number) => {
  const result = new Float32Array(numOutputSamples * 2);
  let lastOutputIndex = 0;
  let currentMin = 0;
  let currentMax = 0;
  for (let i = 0; i < buffer.length; i++) {
    const outputIndex = Math.floor((i * numOutputSamples) / buffer.length);
    if (outputIndex === lastOutputIndex) {
      currentMin = Math.min(currentMin, buffer[i]);
      currentMax = Math.max(currentMax, buffer[i]);
    } else {
      result[lastOutputIndex * 2] = currentMin;
      result[lastOutputIndex * 2 + 1] = currentMax;
      currentMin = buffer[i];
      currentMax = buffer[i];
    }
    lastOutputIndex = outputIndex;
  }
  result[lastOutputIndex * 2] = currentMin;
  result[lastOutputIndex * 2 + 1] = currentMax;
  return result;
};

const getUpsampledBounds = (buffer: Float32Array, numOutputSamples: number) => {
  const result = new Float32Array(numOutputSamples * 2);
  for (let i = 0; i < numOutputSamples; i++) {
    const beforeIndex = Math.floor((i * buffer.length) / numOutputSamples);
    const afterIndex = beforeIndex + 1;
    const proportion = (i * buffer.length) / numOutputSamples - beforeIndex;
    const beforeSample = buffer[beforeIndex];
    const afterSample = buffer[afterIndex];
    result[i * 2] = beforeSample + (afterSample - beforeSample) * proportion;
    result[i * 2 + 1] = beforeSample + (afterSample - beforeSample) * proportion;
  }
  return result;
};

const getResampledWaveformBounds = (buffer: Float32Array, numOutputSamples: number) => {
  if (numOutputSamples === buffer.length) {
    const output = new Float32Array(buffer.length * 2);
    for (let i = 0; i < buffer.length; i++) {
      output[i * 2] = buffer[i];
      output[i * 2 + 1] = buffer[i];
    }
    return output;
  } else if (numOutputSamples > buffer.length) {
    return getUpsampledBounds(buffer, numOutputSamples);
  } else {
    return getDownsampledBounds(buffer, numOutputSamples);
  }
};

export default getResampledWaveformBounds;
