<script lang="ts">
	import type { Media } from '$lib/AniList/media';
	import Error from '$lib/Error/RateLimited.svelte';
	import { volumeCount } from '$lib/Media/Manga/volumes';
	import { outboundLink } from '$lib/Media/links';
	import settings from '$stores/settings';
	import ListTitle from '../ListTitle.svelte';
	import MediaTitle from '../MediaTitleDisplay.svelte';
	import HoverCover from '$lib/Media/Cover/HoverCover.svelte';
	import {
		onMouseEnter,
		onMouseLeave,
		onMouseMove,
		type HoverCoverResponse
	} from '$lib/Media/Cover/hoverCover';
	import { onMount } from 'svelte';
	import proxy from '$lib/Utility/proxy';
	import Loading from '$lib/Utility/Loading.svelte';

	export let media: Media[];
	export let cleanCache: () => void;
	export let endTime: number;
	export let lastUpdatedMedia: number;
	export let updateMedia: (
		id: number,
		progress: number | undefined,
		media: Media[]
	) => Promise<void>;
	export let pendingUpdate: number | null;
	export let due: boolean;
	export let rateLimited: boolean;
	export let authorised: boolean;

	let hoverCoverState: HoverCoverResponse = {};
	let serviceStatusResponse: Promise<Response>;

	onMount(() => (serviceStatusResponse = fetch(proxy('https://mangadex.org'))));
</script>

{#if authorised}
	<ListTitle count={media.length} time={endTime / 1000}>
		<button
			class="small-button"
			title="Force a full refresh"
			on:click={cleanCache}
			data-umami-event="Force Refresh Manga">Refresh</button
		>
	</ListTitle>
{/if}

{#if rateLimited}
	{#await serviceStatusResponse}
		<Loading type="service status" percent={33} card={false} />
	{:then status}
		{#if status}
			{#if status.status === 503}
				<a href="https://due.moe">due.moe</a>'s manga data source is currently down for maintenance.
				Please check back later.
			{:else if status.status !== 200}
				<a href="https://due.moe">due.moe</a>'s manga data source is currently unavailable. Please
				check back later.
			{:else}
				<Error />
			{/if}
		{:else}
			<Loading type="service status" percent={66} card={false} />
		{/if}
	{:catch}
		<a href="https://due.moe">due.moe</a>'s manga data source is currently unreachable. Please check
		back later.
	{/await}
{/if}

{#if media.length === 0 && !rateLimited}
	{#if rateLimited}
		<p />
	{/if}

	<p>
		No manga to display. <button on:click={cleanCache} data-umami-event="Force Refresh No Manga"
			>Force refresh</button
		>
	</p>

	<span>
		Don't read manga? <button
			on:click={() => ($settings.disableManga = true)}
			data-umami-event="Disable No Manga">Hide the manga panel</button
		>
		You can re-enable it later in the <a href="/settings">Settings</a>.
	</span>
{/if}

<ul>
	{#each media as manga}
		{@const progress = (manga.mediaListEntry || { progress: 0 }).progress}

		{#if progress !== manga.episodes}
			<li class="entry">
				<a
					href={outboundLink(manga, 'manga', $settings.displayOutboundLinksTo)}
					target="_blank"
					on:mouseenter={() => {
						const response = onMouseEnter(manga);

						hoverCoverState.hovering = response.hovering;
						hoverCoverState.item = response.item;
						hoverCoverState.media = response.media;
					}}
					on:mouseleave={() => {
						const response = onMouseLeave();

						hoverCoverState.hovering = response.hovering;
						hoverCoverState.item = response.item;
						hoverCoverState.media = response.media;
					}}
					on:mousemove={(e) => {
						const response = onMouseMove(e, 300);

						hoverCoverState.style = response.style;
					}}
				>
					<span
						style={lastUpdatedMedia === manga.id && manga.chapters !== progress
							? 'color: lightcoral'
							: ''}
					>
						<MediaTitle title={manga.title} />
					</span>
				</a>
				{#if $settings.displaySocialButton}
					[<a href={`https://anilist.co/manga/${manga.id}/social`} target="_blank">S</a>]
				{/if}
				<span style="opacity: 50%;">|</span>
				{pendingUpdate === manga.id ? progress + 1 : progress}{#if !due}
					<span style="opacity: 50%;">/{manga.chapters || '?'}</span>
				{/if}
				<button
					class="button-square button-action"
					style={pendingUpdate === manga.id ? 'pointer-events: none; opacity: 50%;' : ''}
					on:click={() =>
						pendingUpdate === manga.id
							? null
							: updateMedia(manga.id, manga.mediaListEntry?.progress, media)}
				>
					+
				</button>
				{#if due || Math.floor(manga.episodes) < manga.chapters}
					[{manga.episodes || '?'}]
					{#await volumeCount(manga) then volumes}
						{@const volumeProgress = manga.mediaListEntry?.progressVolumes}
						{#if volumes !== null && (volumeProgress || 0) < volumes}
							<span style="color: lightcoral;">
								Vol. {volumeProgress} &#8594; {volumes}
							</span>
						{/if}
					{/await}
				{/if}
			</li>
		{/if}
	{/each}
</ul>

<HoverCover options={hoverCoverState} width={300} />
