import type WaveSurfer from "wavesurfer.js";
import { audioBufferToWav } from "./audioBufferToWav";

export interface LoadedParams {
	autoplay?: boolean;
}

export function blob_to_data_url(blob: Blob): Promise<string> {
	return new Promise((fulfill, reject) => {
		let reader = new FileReader();
		reader.onerror = reject;
		reader.onload = () => fulfill(reader.result as string);
		reader.readAsDataURL(blob);
	});
}

export const process_audio = async (
	audioBuffer: AudioBuffer,
	start?: number,
	end?: number,
	waveform_sample_rate?: number
): Promise<Uint8Array> => {
	const audioContext = new AudioContext({
		sampleRate: waveform_sample_rate || audioBuffer.sampleRate
	});
	const numberOfChannels = audioBuffer.numberOfChannels;
	const sampleRate = waveform_sample_rate || audioBuffer.sampleRate;

	let trimmedLength = audioBuffer.length;
	let startOffset = 0;
	if (start != null && end != null) {
		startOffset = Math.round(start * sampleRate);
		const endOffset = Math.round(end * sampleRate);
		trimmedLength = endOffset - startOffset;
	}

	const trimmedAudioBuffer = audioContext.createBuffer(
		numberOfChannels,
		trimmedLength,
		sampleRate
	);

	for (let channel = 0; channel < numberOfChannels; channel++) {
		const channelData = audioBuffer.getChannelData(channel);
		const trimmedData = trimmedAudioBuffer.getChannelData(channel);
		for (let i = 0; i < trimmedLength; i++) {
			trimmedData[i] = channelData[startOffset + i];
		}
	}

	return audioBufferToWav(trimmedAudioBuffer);
};

export function loaded(
	node: HTMLAudioElement,
	{ autoplay }: LoadedParams = {}
): void {
	async function handle_playback(): Promise<void> {
		if (!autoplay) return;
		node.pause();
		await node.play();
	}
}

export const skip_audio = (waveform: WaveSurfer, amount: number): void => {
	if (!waveform) return;
	waveform.skip(amount);
};

export const get_skip_rewind_amount = (
	audio_duration: number,
	skip_length?: number | null
): number => {
	if (!skip_length) {
		skip_length = 5;
	}
	return (audio_duration / 100) * skip_length || 5;
};
