<script lang="ts">
	import { browser } from '$app/environment';
	import type { Media } from '$lib/Data/AniList/media';
	import { findClosestMedia } from '$lib/Media/Anime/Airing/Subtitled/match';
	import type { SubsPlease, SubsPleaseEpisode } from '$lib/Media/Anime/Airing/Subtitled/subsPlease';
	import { outboundLink } from '$lib/Media/links';
	import { parseOrDefault } from '$lib/Utility/parameters';
	import settings from '$stores/settings';
	import CoverBypass from './CoverBypass.svelte';

	export let subsPlease: SubsPlease;
	export let scheduledMedia: Partial<Media[]>;
	export let forceListMode = false;

	const urlParameters = browser ? new URLSearchParams(window.location.search) : null;
	let day: string | null = parseOrDefault(urlParameters, 'day', null);

	const shiftSubsPleaseSchedule = (schedule: SubsPlease['schedule']) => {
		const shiftedSchedule: { [key: string]: SubsPleaseEpisode[] } = {};

		if (day && Object.keys(schedule).includes(day)) {
			shiftedSchedule[day] = schedule[
				day as keyof typeof schedule
			] as unknown as SubsPleaseEpisode[];

			return shiftedSchedule;
		}

		const days = Object.keys(schedule);
		const currentDayIndex = days.indexOf(new Date().toLocaleString('en-us', { weekday: 'long' }));

		days
			.slice(currentDayIndex)
			.concat(days.slice(0, currentDayIndex))
			.forEach((day) => {
				const scheduleEntry = schedule[day as keyof typeof schedule];

				shiftedSchedule[day] = Array.isArray(scheduleEntry)
					? scheduleEntry
					: ([scheduleEntry] as unknown as SubsPleaseEpisode[]);
			});

		Object.entries(shiftedSchedule).forEach(([day, scheduleEntry]) => {
			if (scheduleEntry.length === 0) {
				delete shiftedSchedule[day];
			}
		});

		return shiftedSchedule;
	};

	const associateMedia = (media: (Media | undefined)[], title: string) =>
		findClosestMedia(media as Media[], title);

	const episode = (media: Media, weekday: string) => {
		if (media.nextAiringEpisode?.episode === 1) return 1;

		if (
			media.nextAiringEpisode?.airingAt &&
			weekday === new Date().toLocaleString('en-us', { weekday: 'long' }) &&
			new Date(media.nextAiringEpisode.airingAt * 1000).getTime() - new Date().getTime() >
				24 * 60 * 60 * 1000
		)
			return media.nextAiringEpisode?.episode - 1;

		return media.nextAiringEpisode?.episode || 1;
	};
</script>

{#each Object.entries(shiftSubsPleaseSchedule(subsPlease.schedule)) as [day, scheduleEntry]}
	<details
		open
		class="list"
		class:today={day === new Date().toLocaleString('en-us', { weekday: 'long' })}
	>
		<summary>{day}</summary>

		{#if !$settings.displayScheduleListMode && !forceListMode}
			<div class="covers" style={`grid-template-columns: repeat(auto-fill, minmax(11.5%, 1fr))`}>
				{#each Object.values(scheduleEntry) as entry}
					{@const media = associateMedia(scheduledMedia, entry.title)}

					<div class="cover-card">
						<a
							href={outboundLink(
								media ? media : null,
								'anime',
								$settings.displayOutboundLinksTo,
								media === null,
								entry.title
							)}
							target="_blank"
						>
							<img
								class="cover"
								src={media
									? media.coverImage.extraLarge
									: `https://subsplease.org${entry.image_url}`}
								alt="Cover"
							/>
						</a>

						<div class="cover-title">
							<CoverBypass {media} {entry} cover={false} />
							<span class:countdown={$settings.displayCountdownRightAligned}>
								{#if media && media.nextAiringEpisode}
									<span class="opaque">
										{episode(media, day)}{media.episodes ? `/${media.episodes}` : ''} at
									</span>
								{/if}
								{entry.time}
							</span>
						</div>
					</div>
				{/each}
			</div>
		{:else}
			<ol>
				{#each Object.values(scheduleEntry) as entry}
					{@const media = associateMedia(scheduledMedia, entry.title)}

					<li class="entry">
						<CoverBypass {media} {entry} />
						{#if !$settings.displayCountdownRightAligned}
							<span class="opaque">|</span>
						{/if}
						<span class:countdown={$settings.displayCountdownRightAligned}>
							{#if media && media.nextAiringEpisode}
								<span class="opaque">
									{episode(media, day)}{media.episodes ? `/${media.episodes}` : ''} at
								</span>
							{/if}
							{entry.time}
						</span>
					</li>
				{/each}
			</ol>
		{/if}
	</details>

	<p />
{/each}

<style>
	.covers {
		display: grid;
		justify-content: center;
		gap: 1em 0.5em;
		margin-top: 0.5rem;
	}

	.cover {
		background-size: cover;
		background-position: center;
		border-radius: 8px;
		width: 7.5rem;
	}

	.cover-card {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		transition: transform 0.3s ease;
		box-sizing: border-box;
	}

	.cover-card:hover {
		transform: scale(1.1);
		position: relative;
		z-index: 2;
		transition: transform 0.3s ease;
	}

	.cover-title {
		text-align: center;
		margin: 0.5em 0.25em;
	}

	.entry::after {
		content: '';
		display: table;
		clear: both;
	}

	.countdown {
		white-space: nowrap;
		float: right;
	}

	.today {
		box-shadow: 0 2.5px 10px var(--base01), 0 0 0 5px var(--base0E), 0 4px 30px var(--base01);
	}

	.list {
		overflow-y: auto;
		break-inside: avoid-column;
		page-break-inside: avoid;
	}
</style>
