<script lang="ts">
import type { Component } from "svelte";
import Spacer from "$lib/Layout/Spacer.svelte";
import { onDestroy, onMount } from "svelte";
import userIdentity from "$stores/identity.js";
import settings from "$stores/settings";
import ListTitle from "$lib/List/ListTitle.svelte";
import HeadTitle from "$lib/Home/HeadTitle.svelte";
import { createHeightObserver } from "$lib/Utility/html.js";
import Skeleton from "$lib/Loading/Skeleton.svelte";
import locale from "$stores/locale.js";
import Landing from "$lib/Landing.svelte";
import stateBin from "$stores/stateBin.js";
import type { PageData } from "./$types";

let { data }: { data: PageData } = $props();

type UserProp = PageData["user"];
type LastActivitySvelteComponent = Component<{
	user: UserProp;
}>;
type WatchingAnimeListSvelteComponent = Component<{
	user: UserProp;
}>;
type MangaListTemplateSvelteComponent = Component<{
	user: UserProp;
	displayUnresolved: boolean;
	due: boolean;
}>;

let removeHeightObserver: (() => void) | undefined;
let LastActivityComponent: LastActivitySvelteComponent | null = $state(null);
let WatchingAnimeListComponent: WatchingAnimeListSvelteComponent | null =
	$state(null);
let MangaListTemplateComponent: MangaListTemplateSvelteComponent | null =
	$state(null);
let completedSurfaceImport: Promise<void> | null = null;

const loadCompletedSurface = () => {
	if (data.user === undefined) return null;
	if (completedSurfaceImport) return completedSurfaceImport;

	completedSurfaceImport = Promise.all([
		import("$lib/Home/LastActivity.svelte"),
		import("$lib/List/Anime/CompletedAnimeList.svelte"),
		import("$lib/List/Manga/MangaListTemplate.svelte"),
	]).then(([lastActivity, watchingAnimeList, mangaListTemplate]) => {
		LastActivityComponent = lastActivity.default;
		WatchingAnimeListComponent = watchingAnimeList.default;
		MangaListTemplateComponent = mangaListTemplate.default;
	});

	return completedSurfaceImport;
};

onMount(() => {
	removeHeightObserver = createHeightObserver();
	$stateBin.completedAnimeListOpen ??= true;
	$stateBin.completedMangaListOpen ??= true;
	void loadCompletedSurface();
});

onDestroy(() => removeHeightObserver?.());
</script>

<HeadTitle route="Completed" path="/completed" />

{#if LastActivityComponent}
  <LastActivityComponent user={data.user} />
{/if}

{#if data.user === undefined}
  <div class="card">Please log in to view completed media.</div>

  <Spacer />

  <Landing />
{:else}
  <div class="list-container">
    {#if !$settings.displayFiltersIncludeCompleted || !$settings.disableAnime}
      <details bind:open={$stateBin.completedAnimeListOpen} class="list">
        {#if $userIdentity.id !== -2}
          {#if WatchingAnimeListComponent}
            <WatchingAnimeListComponent user={data.user} />
          {:else}
            <ListTitle title={$locale().lists.completed.anime} />

            <Skeleton card={false} count={5} height="0.9rem" list />
          {/if}
        {:else}
          <ListTitle title={$locale().lists.completed.anime} />

          <Skeleton card={false} count={5} height="0.9rem" list />
        {/if}
      </details>
    {/if}

    {#if !$settings.displayFiltersIncludeCompleted || !$settings.disableManga}
      <details bind:open={$stateBin.completedMangaListOpen} class="list">
        {#if $userIdentity.id !== -2}
          {#if MangaListTemplateComponent}
            <MangaListTemplateComponent
              user={data.user}
              displayUnresolved={$settings.displayUnresolved}
              due={false}
            />
          {:else}
            <ListTitle title={$locale().lists.completed.mangaAndLightNovels} />

            <Skeleton card={false} count={5} height="0.9rem" list />
          {/if}
        {:else}
          <ListTitle title={$locale().lists.completed.mangaAndLightNovels} />

          <Skeleton card={false} count={5} height="0.9rem" list />
        {/if}
      </details>
    {/if}
  </div>
{/if}

<style>
  .list-container {
    display: flex;
    flex-wrap: wrap;
    align-items: start;
    gap: 1em;
  }

  .list {
    overflow-y: auto;
    min-width: 300px;
    flex: 1 1 300px;
  }
</style>
