<script lang="ts">
	import userIdentity from '../../stores/userIdentity.js';
	import {
		userIdentity as getUserIdentity,
		type AniListAuthorisation
	} from '$lib/AniList/identity';
	import { onMount } from 'svelte';
	import { wrapped } from '$lib/AniList/wrapped.js';
	import { activityHistory, fillMissingDays } from '$lib/AniList/activity.js';
	import { Type, mediaListCollection, type Media } from '$lib/AniList/media.js';
	import anime from '../../stores/anime.js';
	import lastPruneTimes from '../../stores/lastPruneTimes.js';
	import manga from '../../stores/manga.js';
	import Error from '$lib/Error.svelte';

	export let user: AniListAuthorisation;

	let currentUserIdentity = { name: '', id: -1 };
	let episodes = 0;
	let animeList: Media[] | undefined = undefined;
	let mangaList: Media[] | undefined = undefined;

	onMount(async () => {
		if (user !== undefined) {
			if ($userIdentity === '') {
				userIdentity.set(JSON.stringify(await getUserIdentity(user)));
			}

			currentUserIdentity = JSON.parse($userIdentity);
			currentUserIdentity.name = currentUserIdentity.name;
			animeList = await mediaListCollection(
				user,
				currentUserIdentity,
				Type.Anime,
				$anime,
				$lastPruneTimes.anime,
				true,
				true
			);
			mangaList = await mediaListCollection(
				user,
				currentUserIdentity,
				Type.Manga,
				$manga,
				$lastPruneTimes.manga,
				true,
				true
			);
			animeList = animeList.sort((a, b) => {
				if (a.mediaListEntry?.score === undefined) {
					return 1;
				} else if (b.mediaListEntry?.score === undefined) {
					return -1;
				} else {
					return b.mediaListEntry?.score - a.mediaListEntry?.score;
				}
			});
			mangaList = mangaList.sort((a, b) => {
				if (a.mediaListEntry?.score === undefined) {
					return 1;
				} else if (b.mediaListEntry?.score === undefined) {
					return -1;
				} else {
					return b.mediaListEntry?.score - a.mediaListEntry?.score;
				}
			});

			for (const media of animeList) {
				if (media.startDate.year === new Date(Date.now()).getFullYear()) {
					episodes += media.mediaListEntry?.progress || 0;
				}
			}
		}
	});

	/* eslint-disable @typescript-eslint/no-explicit-any */
	const year = (statistic: { startYears: any }) => {
		return statistic.startYears.find((y: { startYear: number }) => y.startYear === 2023);
	};
</script>

{#if currentUserIdentity.id !== -1}
	{#await wrapped(user, currentUserIdentity)}
		Loading ...
	{:then wrapped}
		{@const anime = year(wrapped.statistics.anime)}
		{@const manga = year(wrapped.statistics.manga)}

		<div class="categories-grid">
			<div class="grid-item image-grid">
				<a href={`https://anilist.co/user/${currentUserIdentity.name}`} target="_blank">
					<img src={wrapped.avatar.large} alt="User Avatar" />
				</a>
				<div>
					<div>
						<a href={`https://anilist.co/user/${currentUserIdentity.name}`} target="_blank">
							<b>
								{currentUserIdentity.name}
							</b>
						</a>
					</div>
					<div>
						Status Posts: {wrapped.activities.statusCount}
					</div>
					<div>
						Messages: {wrapped.activities.messageCount}
					</div>
					<div>
						Days Active: {#await activityHistory(currentUserIdentity)}
							Loading ...
						{:then activities}
							{#if activities === undefined}
								Loading ...
							{:else}
								{fillMissingDays(activities, true).filter((a) => a.amount !== 0).length}/365
							{/if}
						{/await}
					</div>
				</div>
			</div>
			<div class="category-grid">
				<div class="grid-item">
					<b>Anime</b>
				</div>
				<div class="grid-item">
					Time Watched: {((anime.minutesWatched || 0) / 60 / 24).toFixed(2)} days
				</div>
				<div class="grid-item">
					Completed: {anime.count}
				</div>
				<div class="grid-item">Episodes: {episodes}</div>
			</div>
			<div class="category-grid">
				<div class="grid-item">
					<b>Manga</b>
				</div>
				<div class="grid-item">
					Time Read: {(((manga.chaptersRead || 0) * 8.58) / 60 / 24).toFixed(2)} days
				</div>
				<div class="grid-item">
					Completed: {manga.count}
				</div>
				<div class="grid-item">
					Chapters: {manga.chaptersRead || 0}
				</div>
			</div>
			<div class="category-grid">
				<div class="grid-item image-grid">
					{#if animeList !== undefined}
						<a href={`https://anilist.co/anime/${animeList[0].id}`} target="_blank">
							<img
								src={animeList[0].coverImage.extraLarge}
								alt="Highest Rated Anime Cover"
								class="cover-image"
							/>
						</a>
						<div>
							<b>Highest Rated Anime</b>
							<ol>
								{#each animeList?.slice(0, 5) as anime}
									<li>
										<a href={`https://anilist.co/anime/${anime.id}`} target="_blank">
											{anime.title.english || anime.title.romaji || anime.title.native}
										</a>
									</li>
								{/each}
							</ol>
						</div>
					{:else}
						Loading ...
					{/if}
				</div>
			</div>
			<div class="category-grid">
				<div class="grid-item image-grid">
					{#if mangaList !== undefined}
						<a href={`https://anilist.co/manga/${mangaList[0].id}`} target="_blank">
							<img
								src={mangaList[0].coverImage.extraLarge}
								alt="Highest Rated Manga Cover"
								class="cover-image"
							/>
						</a>
						<div>
							<b>Highest Rated Manga</b>
							<ol>
								{#each mangaList?.slice(0, 5) as manga}
									<li>
										<a href={`https://anilist.co/manga/${manga.id}`} target="_blank">
											{manga.title.english || manga.title.romaji || manga.title.native}
										</a>
									</li>
								{/each}
							</ol>
						</div>
					{:else}
						Loading ...
					{/if}
				</div>
			</div>
		</div>
	{:catch}
		<Error />
	{/await}
{:else}
	Loading ...
{/if}

<style>
	.categories-grid {
		display: flex;
		flex-wrap: wrap;
		row-gap: 1em;
		column-gap: 1em;
	}

	.category-grid {
		display: grid;
	}

	.image-grid {
		display: grid;
		column-gap: 1em;
		grid-template-columns: 1fr 2fr;
	}

	.image-grid img {
		height: 6em;
	}

	.cover-image {
		height: 8.75em !important;
	}

	.grid-item {
		min-width: 300px;
		flex: 1 1 300px;
		/* text-align: center; */
	}

	a {
		text-decoration: none;
		color: unset;
	}
</style>
