<script lang="ts">
	import { PUBLIC_VERSION } from '$env/static/public';
	import supportedFormats from '$lib/common/supportedFormats.json';
	import Loader from '$lib/components/Loader.svelte';
	import DownloadManager from '$lib/components/DownloadManager.svelte';
	import { mount, unmount } from 'svelte';

	let source = $state('youtube');
	let link = $state('');
	let downloading = $state(false);
	let format = $state('mp3');
	let showModal = $state(false);
	let href = $state('');
	let disabled = $state(true);
	let metadata = $state(false);
	let logs = $state('');
	let downloadManager: DownloadManager | null = null;
	let progress = $state(0);
	let filename = $state('');

	const formats = Object.keys(supportedFormats).map((f) => {
		return { value: f, label: f.toUpperCase() };
	});
	const sources = [
		{ value: 'youtube', label: 'YouTube' },
		{ value: 'youtube', label: 'Any Other Website' }
	];

	const toggleModal = () => {
		showModal = !showModal;
	};

	const download = async (url: string) => {
		const response = await fetch(url);

		if (!response.ok) {
			throw new Error('Network response was not ok');
		}

		const contentDisposition: string | null = response?.headers?.get('content-disposition');
		filename = contentDisposition?.split('filename=')[1] || 'noname';
		const contentLength: number = Number(response?.headers?.get('content-length'));
		const reader = response?.body?.getReader();
		const chunks: Uint8Array[] = [];
		let receivedLength = 0;

		while (true) {
			const { done, value }: ReadableStreamReadResult<Uint8Array> = await reader!.read();
			if (done) break;
			if (value) {
				chunks.push(value);
				receivedLength += value.length;
				progress = Math.round((receivedLength / contentLength) * 100);
			}
		}

		const blob = new Blob(chunks);
		const downloadUrl = URL.createObjectURL(blob);

		const a = document.createElement('a');
		a.href = downloadUrl;
		a.download = filename;
		a.click();
		window.URL.revokeObjectURL(downloadUrl);
	};

	const onClick = async (evt) => {
		evt.preventDefault();

		downloading = true;
		await download(href);
		downloading = false;

		link = '';
	};

	const createAnchor = () => {
		if (!(source && link && format)) {
			disabled = true;
			return;
		}

		try {
			new URL(link);
			disabled = false;
		} catch (err) {
			/*
			if (err.code === 'ERR_INVALID_URL') {

			}
			*/
			disabled = true;
			return;
		}

		const searchParams = new URLSearchParams();
		searchParams.append('source', source);
		searchParams.append('link', link);
		searchParams.append('format', format);

		if (metadata) searchParams.append('metadata', '1');

		href = `/download?${searchParams.toString()}`;
	};

	$effect(() => {
		createAnchor();
		// Auto selected the radio button based on url regex
		if (link.includes('spotify')) {
			source = 'spotify';
		} else if (link.includes('youtube')) {
			source = 'youtube';
		}
	});
</script>

<div
	id="wrapper"
	class="relative mx-auto max-w-full rounded-2xl bg-black p-4 text-green-400 shadow-xl sm:max-w-sm md:max-w-md lg:max-w-lg"
>
	<!-- Loader Overlay -->
	<div
		id="loader"
		class="absolute inset-0 z-10 hidden items-center justify-center bg-black/80 backdrop-blur-sm"
	>
		<Loader />
		{@html logs}
	</div>

	<!-- Info Button -->
	<button
		onclick={toggleModal}
		class="absolute top-3 right-3 text-pink-500 transition hover:text-pink-400"
		aria-label="Open Info Modal"
	>
		<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="h-5 w-5" viewBox="0 0 24 24">
			<path
				d="M12 0C5.373 0 0 5.373 0 12c0 6.627 5.373 12 12 12s12-5.373 12-12C24 5.373 18.627 0 12 0zm.75 18h-1.5v-6h1.5v6zm0-8h-1.5V8h1.5v2z"
			/>
		</svg>
	</button>

	<!-- Title -->
	<p id="title" class="mb-4 text-center font-mono text-xl tracking-tight text-cyan-300">
		🐙 Scaricatore 🐙
	</p>

	<!-- Form -->
	<form class="space-y-5 font-mono text-sm">
		<!-- Source & Format -->
		<div class="flex flex-col gap-4 sm:flex-row">
			<div class="flex-1">
				<label for="source" class="mb-1 block text-cyan-300">Source</label>
				<select
					id="source"
					name="source"
					bind:value={source}
					class="w-full rounded-md border border-green-400 bg-[#000f00] px-3 py-2 text-green-300 focus:border-pink-400 focus:outline-none"
				>
					{#each sources as source}
						<option value={source.value}>{source.label}</option>
					{/each}
				</select>
			</div>

			<div class="flex-1">
				<label for="format" class="mb-1 block text-cyan-300">Format</label>
				<select
					id="format"
					name="format"
					bind:value={format}
					class="w-full rounded-md border border-green-400 bg-[#000f00] px-3 py-2 text-green-300 focus:border-pink-400 focus:outline-none"
				>
					{#each formats as format}
						<option value={format.value}>{format.label}</option>
					{/each}
				</select>
			</div>
		</div>

		<!-- Video Link -->
		<div>
			<label for="link" class="mb-1 block text-cyan-300">Video Link</label>
			<input
				type="url"
				id="link"
				name="link"
				bind:value={link}
				required
				placeholder="https://..."
				class="w-full rounded-md border border-green-400 bg-[#000f00] px-3 py-2 text-green-300 placeholder:text-green-600 focus:border-pink-400 focus:outline-none"
			/>
		</div>

		<!-- Metadata Checkbox -->
		<div class="flex items-center gap-2">
			<input
				type="checkbox"
				id="metadata"
				name="metadata"
				bind:checked={metadata}
				class="h-4 w-4 border border-green-400 bg-[#000f00] text-green-500 focus:ring-pink-400"
			/>
			<label for="metadata" class="text-cyan-300"
				>Set filename (<span class="text-red-500">slow</span>)</label
			>
		</div>

		<!-- Download Button -->
		<a
			id="btn-download"
			{href}
			onclick={onClick}
			class="{disabled
				? 'pointer-events-none opacity-50'
				: ''} block w-full rounded-md border border-pink-400 bg-pink-600 px-4 py-3 text-center text-base font-bold text-black transition hover:bg-pink-500 active:border-yellow-400"
		>
			DOWNLOAD
		</a>
	</form>
</div>

{#if downloading}
	<DownloadManager {filename} {progress}></DownloadManager>
{/if}

<!-- Modal -->
{#if showModal}
	<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/90 text-green-300">
		<div class="w-[90%] max-w-md rounded-lg border border-green-400 bg-[#001a00] p-5 text-center">
			<h2 class="mb-3 text-base font-semibold">🐙 Scaricatore v{PUBLIC_VERSION} 🐙</h2>
			<p>
				Download Spotify playlists and YouTube videos with ease. Choose your source, paste a link,
				select format, go!
			</p>
			<p class="mt-3">
				<a class="text-cyan-400 underline" href="https://git.pweapon.org/odo/dl.emersa.it"
					>Source Code</a
				>
			</p>
			<button
				onclick={toggleModal}
				class="mt-6 rounded-md border border-pink-400 bg-pink-600 px-4 py-2 text-black hover:bg-pink-500"
			>
				Close
			</button>
		</div>
	</div>
{/if}
