<script lang="ts">
	import { uploadToHuggingFace } from "@gradio/utils";
	import { Empty } from "@gradio/atoms";
	import {
		ShareButton,
		IconButton,
		BlockLabel,
		DownloadLink,
		IconButtonWrapper
	} from "@gradio/atoms";
	import type { CustomButton as CustomButtonType } from "@gradio/utils";
	import { Download, Music } from "@gradio/icons";
	import type { I18nFormatter } from "@gradio/utils";
	import AudioPlayer from "../player/AudioPlayer.svelte";
	import MinimalAudioPlayer from "../shared/MinimalAudioPlayer.svelte";
	import { createEventDispatcher } from "svelte";
	import type { FileData } from "@gradio/client";
	import type { WaveformOptions, SubtitleData } from "../shared/types";

	export let value: null | FileData = null;
	export let subtitles: null | FileData | SubtitleData[] = null;
	export let label: string;
	export let show_label = true;
	export let buttons: (string | CustomButtonType)[] = [];
	export let on_custom_button_click: ((id: number) => void) | null = null;
	export let i18n: I18nFormatter;
	export let waveform_settings: Record<string, any> = {};
	export let waveform_options: WaveformOptions = {
		show_recording_waveform: true
	};
	export let editable = true;
	export let loop: boolean;
	export let display_icon_button_wrapper_top_corner = false;
	export let minimal = false;
	export let playback_position = 0;

	const dispatch = createEventDispatcher<{
		change: FileData;
		play: undefined;
		pause: undefined;
		end: undefined;
		stop: undefined;
	}>();

	$: value && dispatch("change", value);
</script>

<BlockLabel
	{show_label}
	Icon={Music}
	float={false}
	label={label || i18n("audio.audio")}
/>

{#if value !== null}
	{#if minimal}
		<MinimalAudioPlayer {value} label={label || i18n("audio.audio")} {loop} />
	{:else}
		<IconButtonWrapper
			display_top_corner={display_icon_button_wrapper_top_corner}
			{buttons}
			{on_custom_button_click}
		>
			{#if buttons.some((btn) => typeof btn === "string" && btn === "download")}
				<DownloadLink
					href={value.is_stream
						? value.url?.replace("playlist.m3u8", "playlist-file")
						: value.url}
					download={value.orig_name || value.path}
				>
					<IconButton Icon={Download} label={i18n("common.download")} />
				</DownloadLink>
			{/if}
			{#if buttons.some((btn) => typeof btn === "string" && btn === "share")}
				<ShareButton
					{i18n}
					on:error
					on:share
					formatter={async (value) => {
						if (!value) return "";
						let url = await uploadToHuggingFace(value.url, "url");
						return `<audio controls src="${url}"></audio>`;
					}}
					{value}
				/>
			{/if}
		</IconButtonWrapper>

		<AudioPlayer
			{value}
			subtitles={Array.isArray(subtitles) ? subtitles : subtitles?.url}
			{label}
			{i18n}
			{waveform_settings}
			{waveform_options}
			{editable}
			{loop}
			bind:playback_position
			on:pause
			on:play
			on:stop
			on:load
		/>
	{/if}
{:else}
	<Empty size="small">
		<Music />
	</Empty>
{/if}
