<script lang="ts">
	import { onMount } from "svelte";
	import type { I18nFormatter } from "@gradio/utils";
	import { Spinner } from "@gradio/icons";
	import WaveSurfer from "wavesurfer.js";
	import RecordPlugin from "wavesurfer.js/dist/plugins/record.js";
	import type { WaveformOptions } from "../shared/types";
	import DeviceSelect from "../shared/DeviceSelect.svelte";

	export let recording = false;
	export let paused_recording = false;
	export let stop: () => void;
	export let record: () => void;
	export let i18n: I18nFormatter;
	export let waveform_settings: Record<string, any>;
	export let waveform_options: WaveformOptions = {
		show_recording_waveform: true
	};
	export let waiting = false;

	let micWaveform: WaveSurfer;
	let waveformRecord: RecordPlugin;

	let microphoneContainer: HTMLDivElement;

	let micDevices: MediaDeviceInfo[] = [];

	onMount(() => {
		create_mic_waveform();
	});

	const create_mic_waveform = (): void => {
		if (micWaveform !== undefined) micWaveform.destroy();
		if (!microphoneContainer) return;
		micWaveform = WaveSurfer.create({
			...waveform_settings,
			normalize: false,
			container: microphoneContainer
		});

		waveformRecord = micWaveform.registerPlugin(RecordPlugin.create());
	};
</script>

<div class="mic-wrap">
	{#if waveform_options.show_recording_waveform}
		<div
			bind:this={microphoneContainer}
			style:display={recording ? "block" : "none"}
		/>
	{/if}
	<div class="controls">
		{#if recording && !waiting}
			<button
				class={paused_recording ? "stop-button-paused" : "stop-button"}
				on:click={() => {
					waveformRecord?.stopMic();
					stop();
				}}
			>
				<span class="record-icon">
					<span class="pinger" />
					<span class="dot" />
				</span>
				{paused_recording ? i18n("audio.pause") : i18n("audio.stop")}
			</button>
		{:else if recording && waiting}
			<button
				class="spinner-button"
				on:click={() => {
					stop();
				}}
			>
				<div class="icon">
					<Spinner />
				</div>
				{i18n("audio.waiting")}
			</button>
		{:else}
			<button
				class="record-button"
				on:click={() => {
					waveformRecord?.startMic();
					record();
				}}
			>
				<span class="record-icon">
					<span class="dot" />
				</span>
				{i18n("audio.record")}
			</button>
		{/if}

		<DeviceSelect bind:micDevices {i18n} />
	</div>
</div>

<style>
	.controls {
		display: flex;
		align-items: center;
		justify-content: space-between;
		flex-wrap: wrap;
	}

	.mic-wrap {
		display: block;
		align-items: center;
		margin: var(--spacing-xl);
	}

	.icon {
		width: var(--size-4);
		height: var(--size-4);
		fill: var(--primary-600);
		stroke: var(--primary-600);
	}

	.stop-button-paused {
		display: none;
		height: var(--size-8);
		width: var(--size-20);
		background-color: var(--block-background-fill);
		border-radius: var(--button-large-radius);
		align-items: center;
		border: 1px solid var(--block-border-color);
		margin-right: 5px;
	}

	.stop-button-paused::before {
		content: "";
		height: var(--size-4);
		width: var(--size-4);
		border-radius: var(--radius-full);
		background: var(--primary-600);
		margin: 0 var(--spacing-xl);
	}

	.stop-button::before {
		content: "";
		height: var(--size-4);
		width: var(--size-4);
		border-radius: var(--radius-full);
		background: var(--primary-600);
		margin: 0 var(--spacing-xl);
		animation: scaling 1800ms infinite;
	}

	.stop-button {
		height: var(--size-8);
		width: var(--size-20);
		background-color: var(--block-background-fill);
		border-radius: var(--button-large-radius);
		align-items: center;
		border: 1px solid var(--primary-600);
		margin-right: 5px;
		display: flex;
	}

	.spinner-button {
		height: var(--size-8);
		width: var(--size-24);
		background-color: var(--block-background-fill);
		border-radius: var(--radius-3xl);
		align-items: center;
		border: 1px solid var(--primary-600);
		margin: 0 var(--spacing-xl);
		display: flex;
		justify-content: space-evenly;
	}

	.record-button::before {
		content: "";
		height: var(--size-4);
		width: var(--size-4);
		border-radius: var(--radius-full);
		background: var(--primary-600);
		margin: 0 var(--spacing-xl);
	}

	.record-button {
		height: var(--size-8);
		width: var(--size-24);
		background-color: var(--block-background-fill);
		border-radius: var(--button-large-radius);
		display: flex;
		align-items: center;
		border: 1px solid var(--block-border-color);
	}

	@keyframes scaling {
		0% {
			background-color: var(--primary-600);
			scale: 1;
		}
		50% {
			background-color: var(--primary-600);
			scale: 1.2;
		}
		100% {
			background-color: var(--primary-600);
			scale: 1;
		}
	}
</style>
