<script lang="ts">
	import { mediaListCollection, Type, flattenLists, type Media } from '$lib/AniList/media';
	import type { UserIdentity, AniListAuthorisation } from '$lib/AniList/identity';
	import { onMount } from 'svelte';
	import { chapterCount } from '$lib/mangadex';
	import chaptersLastPrune from '../../../stores/chaptersLastPrune';
	import manga from '../../../stores/manga';
	import { chapterDatabase } from '$lib/chapterDatabase';
	import cacheMangaMinutes from '../../../stores/cacheMangaMinutes';
	import roundDownChapters from '../../../stores/roundDownChapters';
	import mangaLastPrune from '../../../stores/mangaLastPrune';
	import displayNotStarted from '../../../stores/displayNotStarted';

	export let user: AniListAuthorisation;
	export let identity: UserIdentity;
	export let displayUnresolved: boolean;

	let mangaLists: any;
	let startTime: number;
	let endTime: number;

	onMount(async () => {
		startTime = performance.now();
		mangaLists = mediaListCollection(user, identity, Type.Manga, $manga, $mangaLastPrune);
	});

	const cleanMedia = async (media: object[][], displayUnresolved: boolean) => {
		if (media === undefined) {
			return [];
		}

		if ($chaptersLastPrune == '') {
			chaptersLastPrune.set(new Date().getTime().toString());
		} else {
			if (
				(new Date().getTime() - Number($chaptersLastPrune)) / 1000 / 60 >
				Number($cacheMangaMinutes)
			) {
				const unresolved = await chapterDatabase.chapters.where('chapters').equals(-1).toArray();
				const ids = unresolved.map((m) => m.id);

				chaptersLastPrune.set(new Date().getTime().toString());
				await chapterDatabase.chapters.bulkDelete(ids);
			}
		}

		const flattenedLists = flattenLists(media);
		const releasingMedia = flattenedLists.filter(
			(media: Media) =>
				media.status == 'RELEASING' &&
				media.format != 'NOVEL' &&
				(media.mediaListEntry || { progress: 0 }).progress >=
					($displayNotStarted === 'true' ? 0 : 1)
		);
		let finalMedia = releasingMedia;

		const chapterPromises = finalMedia.map((m: Media) => chapterCount(m));
		const chapterCounts = await Promise.all(chapterPromises);

		finalMedia.forEach((m: Media, i) => {
			m.episodes = chapterCounts[i] || -1337;
		});

		if (!displayUnresolved) {
			finalMedia = finalMedia.filter((m: Media) => m.episodes !== -1337);
		}

		finalMedia.sort((a: Media, b: Media) => {
			return (
				(a.episodes || 9999) -
				a.mediaListEntry!.progress -
				((b.episodes || 9999) - b.mediaListEntry!.progress)
			);
		});

		finalMedia = finalMedia.filter((item, index, array) => {
			return (
				array.findIndex((i) => {
					return i.id === item.id;
				}) === index &&
				(item.episodes === -1337 && displayUnresolved
					? true
					: (item.mediaListEntry?.progress || 0) <
					  ($roundDownChapters === 'true' ? Math.floor(item.episodes) : item.episodes))
			);
		});

		if (!endTime) {
			endTime = performance.now() - startTime;
		}

		return finalMedia;
	};

	const updateMedia = async (id: number, progress: number | undefined) => {
		manga.set('');
		chapterDatabase.chapters.delete(id).then(async () => {
			mangaLists = mediaListCollection(user, identity, Type.Manga, $manga, $mangaLastPrune);

			await fetch(`/anilist/increment?id=${id}&progress=${progress! + 1}`);
		});
	};
</script>

{#await mangaLists}
	<summary>Manga [...] <small style="opacity: 50%">...s</small></summary>

	<ul><li>Loading ...</li></ul>
{:then media}
	{#await cleanMedia(media, displayUnresolved)}
		<summary>Manga [...] <small style="opacity: 50%">...s</small></summary>

		<ul><li>Loading ...</li></ul>
	{:then cleanedMedia}
		<summary>
			Manga [{cleanedMedia.length}]
			<small style="opacity: 50%">{endTime / 1000}s</small>
		</summary>

		<ul>
			{#each cleanedMedia as manga}
				<li>
					<a href={`https://anilist.co/manga/${manga.id}`} target="_blank">
						{manga.title.english || manga.title.romaji || manga.title.native}
					</a>
					<span style="opacity: 50%;">|</span>
					{(manga.mediaListEntry || { progress: 0 }).progress}
					<a href="#" on:click={() => updateMedia(manga.id, manga.mediaListEntry?.progress)}>+</a>
					[{manga.episodes || '?'}]
				</li>
			{/each}
		</ul>
	{:catch}
		<summary>Manga [?] <small style="opacity: 50%">0s</small></summary>

		<ul>
			<li>
				<p>
					Media could not be loaded. You might have been <a
						href="https://en.wikipedia.org/wiki/Rate_limiting"
						target="_blank">rate limited</a
					>.
				</p>
				<p>
					Try again in a few minutes. If the problem persists, please contact
					<a href="https://anilist.co/user/fuwn" target="_blank">@fuwn</a> on AniList.
				</p>
			</li>
		</ul>
	{/await}
{/await}
