<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 LandingHero from "$lib/LandingHero.svelte";
import stateBin, { hydrateStateBin } from "$stores/stateBin.js";
import type { PageData } from "./$types";

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

type UserProp = PageData["user"];
type LastActivitySvelteComponent = Component<{
	user: UserProp;
}>;
type UpcomingAnimeListSvelteComponent = Component<{
	user: UserProp;
}>;
type IndexColumnSvelteComponent = Component<{
	user: UserProp;
	userIdentity: { id: number };
}>;
type MangaListTemplateSvelteComponent = Component<{
	user: UserProp;
	displayUnresolved: boolean;
	due: boolean;
}>;

let removeHeightObserver: (() => void) | undefined;
let LastActivityComponent: LastActivitySvelteComponent | null = $state(null);
let UpcomingAnimeListComponent: UpcomingAnimeListSvelteComponent | null =
	$state(null);
let IndexColumnComponent: IndexColumnSvelteComponent | null = $state(null);
let MangaListTemplateComponent: MangaListTemplateSvelteComponent | null =
	$state(null);
let authenticatedHomeSurfaceImport: Promise<void> | null = null;

const loadAuthenticatedHomeSurface = () => {
	if (data.user === undefined) return null;
	if (authenticatedHomeSurfaceImport) return authenticatedHomeSurfaceImport;

	authenticatedHomeSurfaceImport = Promise.all([
		import("$lib/Home/LastActivity.svelte"),
		import("$lib/List/Anime/UpcomingAnimeList.svelte"),
		import("$lib/List/Anime/DueIndexColumn.svelte"),
		import("$lib/List/Manga/MangaListTemplate.svelte"),
	]).then(
		([lastActivity, upcomingAnimeList, indexColumn, mangaListTemplate]) => {
			LastActivityComponent = lastActivity.default;
			UpcomingAnimeListComponent = upcomingAnimeList.default;
			IndexColumnComponent = indexColumn.default;
			MangaListTemplateComponent = mangaListTemplate.default;
		},
	);

	return authenticatedHomeSurfaceImport;
};

onMount(async () => {
	removeHeightObserver = createHeightObserver();
	await hydrateStateBin();
	$stateBin.upcomingAnimeListOpen ??= true;
	$stateBin.dueMangaListOpen ??= true;
	void loadAuthenticatedHomeSurface();
});

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

<HeadTitle />

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

{#if data.user === undefined}
  <LandingHero />

  <Spacer size="lg" />

  <Landing />
{:else}
  <div
    class="grid-container"
    style={`
			grid-template-columns: ${
        [!$settings.disableUpcomingAnime, !$settings.disableAnime, !$settings.disableManga]
          .map(Number)
          .reduce((a, b) => a + b) > 1
          ? '1fr 1fr'
          : '1fr'
      }
		`}
  >
    <div class="left-column">
      {#if !$settings.disableUpcomingAnime}
        <details bind:open={$stateBin.upcomingAnimeListOpen} class="list list-upcoming">
          {#if $userIdentity.id !== -2}
            {#if UpcomingAnimeListComponent}
              <UpcomingAnimeListComponent user={data.user} />
            {:else}
              <ListTitle title={$locale().lists.upcoming.episodes} />

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

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

      {#if !$settings.disableAnime && !$settings.disableManga}
        {#if IndexColumnComponent}
          <IndexColumnComponent user={data.user} userIdentity={$userIdentity} />
        {:else}
          <details bind:open={$stateBin.dueAnimeListOpen} class="list list-due">
            <ListTitle title={$locale().lists.due.episodes} />

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

    <div class="right-column">
      {#if !$settings.disableAnime && $settings.disableManga}
        {#if IndexColumnComponent}
          <IndexColumnComponent user={data.user} userIdentity={$userIdentity} />
        {:else}
          <details bind:open={$stateBin.dueAnimeListOpen} class="list list-due">
            <ListTitle title={$locale().lists.due.episodes} />

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

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

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

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

    {#if $settings.disableUpcomingAnime && $settings.disableAnime && $settings.disableManga}
      <video src="https://video.twimg.com/tweet_video/Do_eDPnX0AAKV9f.mp4" autoplay loop>
        <track kind="captions" />
      </video>
    {/if}
  </div>
{/if}

<style>
  .grid-container {
    display: grid;
    gap: 1rem;
  }

  .left-column {
    display: grid;
    gap: 1rem;
    align-content: start;
  }

  .right-column {
    align-self: start;
  }

  .list {
    overflow-y: auto;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  @media (max-width: 800px) {
    .grid-container {
      grid-template-columns: 1fr !important;
    }
  }
</style>
