const trimAudioBuffer = ({
  audioBuffer,
  maxLengthSeconds,
  minLengthSeconds,
  trimStart,
  trimEnd,
  maintainEnd = false,
}: {
  audioBuffer: AudioBuffer;
  maxLengthSeconds: number;
  minLengthSeconds: number;
  trimStart: number;
  trimEnd: number;
  maintainEnd?: boolean;
}) => {
  const outputBufferLength = Math.min(
    maxLengthSeconds,
    Math.max(minLengthSeconds, trimEnd - trimStart)
  );

  const trimmedBuffer = new AudioBuffer({
    sampleRate: audioBuffer.sampleRate,
    length: outputBufferLength * audioBuffer.sampleRate,
    numberOfChannels: audioBuffer.numberOfChannels,
  });

  const [finalTrimStart, finalTrimEnd] = maintainEnd
    ? ([Math.max(trimStart, trimEnd - outputBufferLength), trimEnd] as const)
    : ([trimStart, Math.min(trimEnd, trimStart + outputBufferLength)] as const);

  const trimStartSamples = finalTrimStart * audioBuffer!.sampleRate;
  const trimEndSamples = finalTrimEnd * audioBuffer!.sampleRate;

  for (let i = 0; i < trimmedBuffer.numberOfChannels; i++) {
    trimmedBuffer.copyToChannel(
      audioBuffer!
        .getChannelData(i)!
        .subarray(trimStartSamples, trimEndSamples),
      i,
      maintainEnd
        ? (outputBufferLength - (finalTrimEnd - finalTrimStart)) *
            audioBuffer!.sampleRate
        : 0
    );
  }

  return trimmedBuffer;
};

export default trimAudioBuffer;
