import type { AudioProcessor, ProcessorCategory } from "./AudioProcessor";

export class OctaveUp implements AudioProcessor {
  getName(): string {
    return "Octave Up";
  }

  getDescription(): string {
    return "Shifts pitch up one octave by doubling playback rate";
  }

  getCategory(): ProcessorCategory {
    return 'Pitch';
  }

  async process(
    leftChannel: Float32Array,
    rightChannel: Float32Array
  ): Promise<[Float32Array, Float32Array]> {
    const inputLength = leftChannel.length;
    const outputLength = Math.floor(inputLength / 2);

    const newLeft = new Float32Array(outputLength);
    const newRight = new Float32Array(outputLength);

    for (let i = 0; i < outputLength; i++) {
      const sourceIndex = i * 2;
      const lowerIndex = Math.floor(sourceIndex);
      const upperIndex = Math.min(lowerIndex + 1, inputLength - 1);
      const fraction = sourceIndex - lowerIndex;

      newLeft[i] = leftChannel[lowerIndex] * (1 - fraction) + leftChannel[upperIndex] * fraction;
      newRight[i] = rightChannel[lowerIndex] * (1 - fraction) + rightChannel[upperIndex] * fraction;
    }

    this.applyFadeOut(newLeft, newRight);

    return [newLeft, newRight];
  }

  private applyFadeOut(left: Float32Array, right: Float32Array): void {
    const fadeLength = Math.min(Math.floor(left.length * 0.05), 2205);
    const fadeStart = left.length - fadeLength;

    for (let i = 0; i < fadeLength; i++) {
      const gain = 1 - (i / fadeLength);
      const index = fadeStart + i;
      left[index] *= gain;
      right[index] *= gain;
    }
  }
}
