<script lang="ts">
	import { onMount } from 'svelte';
	import Message from '$lib/Loading/Message.svelte';
	import Skeleton from '$lib/Loading/Skeleton.svelte';
	import HeadTitle from '$lib/Home/HeadTitle.svelte';
	import { parseScheduleHtml } from '$lib/hololive';
	import proxy from '$lib/Utility/proxy';

	interface ParseResult {
		lives: {
			time: Date;
			link: string;
			videoId: string;
			streamer: string;
			livePreviewImage: string;
			guests: string[];
			streaming: boolean;
		}[];
		dict: Record<string, string>;
	}

	let schedulePromise: Promise<Response>;

	onMount(async () => {
		schedulePromise = fetch(proxy('https://schedule.hololive.tv'), {
			headers: {
				Cookie: 'timezone=Asia/Tokyo'
			}
		});
	});

	const typeSchedule = (schedule: any) => schedule as ParseResult;
</script>

<HeadTitle route="hololive Schedule" path="/hololive" />

{#await schedulePromise}
	<Message message="Loading schedule ..." />

	<Skeleton grid={true} count={100} width="49%" height="16.25em" />
{:then scheduleResponse}
	{#if scheduleResponse}
		{#await scheduleResponse.text()}
			<Message message="Parsing schedule ..." />

			<Skeleton grid={true} count={100} width="49%" height="16.25em" />
		{:then untypedSchedule}
			{@const schedule = typeSchedule(parseScheduleHtml(untypedSchedule))}

			{#if schedule.lives.length === 0}
				<Message message="No upcoming streams." loader="ripple" />
			{/if}

			<div class="container">
				{#each schedule.lives
					.filter((live) => {
						const time = new Date(live.time);

						return time.getTime() > Date.now() - 12 * 60 * 60 * 1000 || time.getTime() > Date.now() || live.streaming;
					})
					.sort((a, b) => {
						if (a.streaming && !b.streaming) {
							return -1;
						} else if (!a.streaming && b.streaming) {
							return 1;
						}

						const aTime = new Date(a.time).getTime();

						if (aTime < Date.now() && new Date(b.time).getTime() > Date.now()) {
							return 1;
						} else if (aTime > Date.now() && new Date(b.time).getTime() < Date.now()) {
							return -1;
						}

						return aTime - new Date(b.time).getTime();
					}) as live}
					<div class="stream card">
						<p>
							[{#if live.streaming}
								<b class="live">LIVE</b>{:else if new Date(live.time).getTime() < Date.now()}
								<span class="ended">Ended</span>{:else}
								<span class="upcoming">Upcoming</span>{/if}]
							<b>{live.streamer}</b> <span class="opaque">|</span>
							{new Date(live.time).toLocaleString()}
							{#if live.guests.length > 0}
								<br />
								<small>
									With {live.guests.join(', ').replace(/, ([^,]+)$/, ', & $1')}
								</small>
							{/if}
						</p>

						<a href={live.link} class="preview" target="_blank">
							<img src={live.livePreviewImage} alt="Stream Thumbnail" />
						</a>
					</div>
				{/each}
			</div>
		{:catch}
			<Message loader="ripple" slot>
				Could not parse schedule. <a href={'#'} on:click={() => location.reload()}>Try again?</a>
			</Message>
		{/await}
	{:else}
		<Message message="Loading schedule ..." />

		<Skeleton grid={true} count={100} width="49%" height="16.25em" />
	{/if}
{:catch}
	<Message message="" loader="ripple" slot>
		Could not load schedule. Please <a href={'#'} on:click={() => location.reload()}>try again</a> later.
	</Message>
{/await}

<style lang="scss">
	.preview {
		// margin: 0.15rem;

		img {
			border-radius: 8px;
			height: 20vh;
			object-fit: cover;
			transition: transform 0.3s ease;
		}

		&:hover {
			img {
				position: relative;
				z-index: 2;
				transition: transform 0.3s ease;
				transform: scale(1.05);
			}
		}

		display: flex;
		justify-content: center;
		align-items: center;
	}

	.live {
		color: var(--base0F);
	}

	.upcoming {
		color: var(--base0C);
	}

	.ended {
		color: var(--base0D);
	}

	.container {
		display: grid;
		grid-template-columns: repeat(auto-fill, minmax(22.5em, 1fr));
		gap: 0.5em;
	}
</style>
