<script lang="ts">
	/* eslint svelte/no-at-html-tags: "off" */

	import settings from '$stores/settings';
	import type { Media } from '$lib/Data/AniList/media';
	import { cleanCache, incrementMediaProgress } from '$lib/Media/Anime/cache';
	import { totalEpisodes } from '$lib/Media/Anime/episodes';
	import type { AniListAuthorisation } from '$lib/Data/AniList/identity';
	import ListTitle from '../ListTitle.svelte';
	import MediaTitle from '../MediaTitleDisplay.svelte';
	import { outboundLink } from '$lib/Media/links';
	import { onDestroy, onMount } from 'svelte';
	import type { SubsPlease } from '$lib/Media/Anime/Airing/Subtitled/subsPlease';
	import { mediaTitle } from '../mediaTitle';
	import AiringTime from '$lib/Media/Anime/Airing/AiringTime.svelte';
	import { browser } from '$app/environment';
	import identity from '$stores/identity';
	import Tooltip from '../../Tooltip/LinkedTooltip.svelte';
	import '../covers.css';
	import ParallaxImage from '$lib/Image/ParallaxImage.svelte';

	export let media: Media[];
	export let title: any;
	export let animeLists: Promise<Media[]>;
	export let user: AniListAuthorisation;
	export let endTime: number;
	export let lastUpdatedMedia: number;
	export let completed = false;
	export let previousAnimeList: Media[];
	export let pendingUpdate: number | null;
	export let subsPlease: SubsPlease | null = null;
	export let upcoming = false;
	export let notYetReleased = false;
	export let dummy = false;

	let keyCacher: NodeJS.Timeout;

	onMount(() => {
		keyCacher = setInterval(
			() => {
				media = media;

				if (
					media.some(
						(m) => m.nextAiringEpisode?.airingAt && m.nextAiringEpisode.airingAt < Date.now() / 1000
					)
				)
					animeLists = cleanCache(user, $identity);
			},
			(() => {
				const airingAt = media
					.filter(
						(m) =>
							(m.status === 'RELEASING' || m.status === 'NOT_YET_RELEASED') &&
							m.nextAiringEpisode?.airingAt
					)
					.find((m) => m.nextAiringEpisode?.airingAt)?.nextAiringEpisode?.airingAt;
				const untilAiring = airingAt
					? Math.round((airingAt - Date.now() / 1000) * 100) / 100
					: undefined;

				return untilAiring ? (untilAiring < 0 ? 1000 : untilAiring) : 1000;
			})()
		);

		if (browser)
			localStorage.setItem(
				`last${
					notYetReleased ? 'NotYetReleased' : upcoming ? 'Upcoming' : completed ? 'Completed' : ''
				}AnimeListLength`,
				media.length.toString()
			);
	});

	onDestroy(() => clearInterval(keyCacher));
</script>

<ListTitle time={endTime / 1000} count={media.length} {title} hideTime={dummy} hideCount={dummy} />

{#if media.length === 0}
	No anime to display. <button on:click={() => (animeLists = cleanCache(user, $identity))}>
		Force refresh
	</button>
{/if}

{#if $settings.displayCoverModeAnime}
	<div
		class="covers"
		style={`grid-template-columns: repeat(auto-fill, minmax(${$settings.displayCoverWidth}px, 1fr))`}
	>
		{#each media as anime}
			{@const progress = (anime.mediaListEntry || { progress: 0 }).progress}

			{#if upcoming || notYetReleased || progress !== (anime.nextAiringEpisode?.episode || 9999) - 1}
				<div class="cover-card" id={`anime-${anime.id}`}>
					<Tooltip
						id={`anime-${anime.id}`}
						pin={`anime-${anime.id}`}
						content={anime ? mediaTitle(anime) : ''}
						relative={dummy}
					>
						<div class="cover-card-image">
							<a
								href={$settings.displayCopyMediaTitleNotLink
									? '#'
									: outboundLink(anime, 'anime', $settings.displayOutboundLinksTo)}
								on:click={(e) => {
									if ($settings.displayCopyMediaTitleNotLink) {
										e.preventDefault();

										navigator.clipboard.writeText(anime.title.romaji);
									}
								}}
								target="_blank"
							>
								<span class="cover-container">
									<ParallaxImage
										source={anime.coverImage.extraLarge}
										alternativeText="Cover"
										limit={12.5}
										classList={`cover${
											anime.isAdult && $settings.displayBlurAdultContent ? ' adult' : ''
										}`}
									/>
								</span>
							</a>
						</div>
					</Tooltip>

					<div class="cover-title">
						{#if !upcoming && !notYetReleased}
							{pendingUpdate === anime.id ? progress + 1 : progress}{@html totalEpisodes(anime)}
							<button
								class={`button-square button-action ${pendingUpdate === anime.id ? 'opaque' : ''}`}
								style={pendingUpdate === anime.id ? 'pointer-events: none;' : ''}
								on:click={() => {
									if (!dummy && pendingUpdate !== anime.id) {
										lastUpdatedMedia = anime.id;
										pendingUpdate = anime.id;

										incrementMediaProgress(anime.id, anime.mediaListEntry?.progress, user, () => {
											const mediaListEntry = media.find((m) => m.id === anime.id)?.mediaListEntry;

											if (mediaListEntry) mediaListEntry.progress = progress + 1;

											previousAnimeList = media;
											animeLists = cleanCache(user, $identity);
											pendingUpdate = null;
										});
									}
								}}>+</button
							>
							{#if !completed}
								[{anime.nextAiringEpisode?.episode === -1
									? '?'
									: (anime.nextAiringEpisode?.episode || 1) - 1}]
								<br />
								<AiringTime originalAnime={anime} {subsPlease} />
							{/if}
						{:else}
							<AiringTime originalAnime={anime} {subsPlease} upcoming={true} />
						{/if}
					</div>
				</div>
			{/if}
		{/each}
	</div>
{:else}
	<ul>
		{#each media as anime}
			{@const progress = (anime.mediaListEntry || { progress: 0 }).progress}

			{#if upcoming || notYetReleased || progress !== (anime.nextAiringEpisode?.episode || 9999) - 1}
				<li class="entry">
					<span class="content">
						<Tooltip
							content={`<img src="${anime.coverImage.extraLarge}" style="width: 250px; object-fit: cover; border-radius: 8px;" />`}
							id={`anime-${anime.id}`}
							pin={`anime-${anime.id}`}
							pinPosition="right"
							disable={!$settings.displayHoverCover}
						>
							<a
								href={$settings.displayCopyMediaTitleNotLink
									? '#'
									: outboundLink(anime, 'anime', $settings.displayOutboundLinksTo)}
								on:click={(e) => {
									if ($settings.displayCopyMediaTitleNotLink) {
										e.preventDefault();

										navigator.clipboard.writeText(anime.title.romaji);
									}
								}}
								target="_blank"
							>
								<span
									style={lastUpdatedMedia === anime.id && anime.episodes !== progress
										? 'color: lightcoral'
										: ''}
								>
									<MediaTitle title={anime.title} />
								</span>
							</a>
						</Tooltip>
						{#if $settings.displaySocialButton}
							[<a href={`https://anilist.co/anime/${anime.id}/social`} target="_blank">S</a>]
						{/if}
						{#if !upcoming || notYetReleased || !$settings.displayCountdownRightAligned}
							<span class="opaque">|</span>
						{/if}
						{#if !upcoming || notYetReleased}
							<!-- {anime.mediaListEntry?.progress || 0}{@html totalEpisodes(anime)} -->
							{pendingUpdate === anime.id ? progress + 1 : progress}{@html totalEpisodes(anime)}
							<button
								class={`button-square button-action ${pendingUpdate === anime.id ? 'opaque' : ''}`}
								style={pendingUpdate === anime.id ? 'pointer-events: none;' : ''}
								on:click={() => {
									if (!dummy && pendingUpdate !== anime.id) {
										lastUpdatedMedia = anime.id;
										pendingUpdate = anime.id;

										incrementMediaProgress(anime.id, anime.mediaListEntry?.progress, user, () => {
											const mediaListEntry = media.find((m) => m.id === anime.id)?.mediaListEntry;

											if (mediaListEntry) mediaListEntry.progress = progress + 1;

											previousAnimeList = media;
											animeLists = cleanCache(user, $identity);
											pendingUpdate = null;
										});
									}
								}}>+</button
							>
							{#if !completed}
								[{anime.nextAiringEpisode?.episode === -1
									? '?'
									: (anime.nextAiringEpisode?.episode || 1) -
									  ((anime.nextAiringEpisode?.airingAt || 999) <
									  (anime.nextAiringEpisode?.nativeAiringAt || 0)
											? 2
											: 1)}]
								<span class:countdown={$settings.displayCountdownRightAligned}>
									<AiringTime originalAnime={anime} {subsPlease} />
								</span>
							{/if}
						{:else}
							<span class:countdown={$settings.displayCountdownRightAligned}>
								<AiringTime originalAnime={anime} {subsPlease} upcoming={true} />
							</span>
						{/if}
					</span>
				</li>
			{/if}
		{/each}
	</ul>
{/if}
