<script lang="ts">
	import { reveal } from '$lib/actions/reveal';
	import LazyLoadingImg from './LazyLoadingImg.svelte';
	import type { RecentPlay } from '$lib/types';

	let { recentPlays }: { recentPlays: Promise<RecentPlay[]> } = $props();

	// Track which rows' cover art failed to load so we can swap in the fallback.
	let coverFailed = $state<Record<number, boolean>>({});

	const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
	const DIVISIONS: { amount: number; unit: Intl.RelativeTimeFormatUnit }[] = [
		{ amount: 60, unit: 'seconds' },
		{ amount: 60, unit: 'minutes' },
		{ amount: 24, unit: 'hours' },
		{ amount: 7, unit: 'days' },
		{ amount: 4.34524, unit: 'weeks' },
		{ amount: 12, unit: 'months' },
		{ amount: Number.POSITIVE_INFINITY, unit: 'years' }
	];

	function relativeTime(iso: string | null): string {
		if (!iso) return '';
		const date = new Date(iso);
		if (Number.isNaN(date.getTime())) return '';
		let duration = (date.getTime() - Date.now()) / 1000;
		for (const division of DIVISIONS) {
			if (Math.abs(duration) < division.amount) {
				return rtf.format(Math.round(duration), division.unit);
			}
			duration /= division.amount;
		}
		return '';
	}
</script>

<section class="mx-auto mt-24 max-w-3xl px-2 md:mt-32">
	<div class="flex flex-col items-center justify-center">
		<h1 class="text-center font-urbanist text-3xl font-semibold md:text-5xl">Music</h1>
		<span class="text-md mt-2 px-2 text-center font-urbanist opacity-70 md:mt-4 md:text-xl">
			Tracks I've been listening to recently
		</span>
	</div>

	{#await recentPlays}
		<ul class="mt-10 flex flex-col gap-3">
			{#each Array(8) as _, i (i)}
				<li class="card flex-row items-center gap-4 bg-base-100 p-3 shadow-sm">
					<div class="h-16 w-16 flex-none skeleton rounded-md"></div>
					<div class="flex min-w-0 flex-1 flex-col gap-2">
						<div class="h-4 w-1/2 skeleton"></div>
						<div class="h-3 w-1/3 skeleton"></div>
					</div>
				</li>
			{/each}
		</ul>
	{:then recentPlays}
		{#if recentPlays.length === 0}
			<p class="mt-10 text-center font-urbanist opacity-60">Nothing to show right now.</p>
		{:else}
			<ul class="mt-10 flex flex-col gap-3">
				{#each recentPlays as play, i (i)}
					<li
						class="card flex-row items-center gap-4 bg-base-100 p-3 shadow-sm transition duration-300 hover:-translate-y-0.5"
					>
						{#if play.coverArt && !coverFailed[i]}
							<LazyLoadingImg
								class="h-16 w-16 flex-none rounded-md shadow-sm"
								src={play.coverArt}
								alt={play.releaseName ?? play.trackName}
								onerror={() => (coverFailed[i] = true)}
							/>
						{:else}
							<div
								class="flex h-16 w-16 flex-none items-center justify-center rounded-md bg-base-300"
							>
								<svg
									xmlns="http://www.w3.org/2000/svg"
									class="h-7 w-7 opacity-60"
									viewBox="0 0 24 24"
									fill="currentColor"
								>
									<path
										d="M12 3v10.55A4 4 0 1 0 14 17V7h4V3h-6zm-2 16a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"
									/>
								</svg>
							</div>
						{/if}

						<div class="flex min-w-0 flex-1 flex-col">
							<h2 class="truncate font-urbanist text-lg font-black">{play.trackName}</h2>
							<p class="truncate font-urbanist text-sm font-medium opacity-60">{play.artists}</p>
							{#if play.releaseName}
								<p class="truncate font-urbanist text-xs font-medium opacity-40">
									{play.releaseName}
								</p>
							{/if}
						</div>

						<div class="flex flex-none flex-col items-end gap-2">
							{#if play.playedTime}
								<span class="font-urbanist text-xs opacity-50">{relativeTime(play.playedTime)}</span
								>
							{/if}
							{#if play.url}
								<a
									class="btn font-urbanist btn-ghost btn-xs"
									href={play.url}
									target="_blank"
									rel="noopener noreferrer"
								>
									Listen
								</a>
							{/if}
						</div>
					</li>
				{/each}
			</ul>
		{/if}
	{:catch}
		<p class="mt-10 text-center font-urbanist opacity-60">Nothing to show right now.</p>
	{/await}
</section>
