<!--
  The TV library — one page, three tabs.

  Was three routes (`/library/tv`, `/library/tv/shows`, `/library/shows/genres`,
  the last of which did not even share a prefix with the others). They are now
  `?view=browse|all|genres` here; the old routes redirect.

  TRACES: UR-007, UR-023, UR-034, UR-063 | DR-007, DR-038, DR-039, DR-103, DR-105
-->
<script lang="ts">
  import { onMount } from "svelte";
  import { page } from "$app/stores";
  import { goto } from "$app/navigation";
  import { navigateUp } from "$lib/utils/navigation";
  import { library, currentLibrary } from "$lib/stores/library";
  import { tv } from "$lib/stores/tv";
  import { isServerReachable } from "$lib/stores/connectivity";
  import { useServerReachabilityReload } from "$lib/composables/useServerReachabilityReload";
  import HeroBanner from "$lib/components/home/HeroBanner.svelte";
  import Carousel from "$lib/components/home/Carousel.svelte";
  import LibraryViewTabs from "$lib/components/library/LibraryViewTabs.svelte";
  import GenericMediaListPage from "$lib/components/library/GenericMediaListPage.svelte";
  import GenericGenreBrowser from "$lib/components/library/GenericGenreBrowser.svelte";
  import { seasonRedirectTarget, episodeFocusHref } from "$lib/components/library/seriesNavigation";
  import { resolveLibraryView, libraryViewUrl, type LibraryView } from "$lib/utils/libraryView";
  import type { MediaItem } from "$lib/api/types";

  const BASE_PATH = "/library/tv";

  const view = $derived(resolveLibraryView($page.url.searchParams.get("view")));

  const tabLabels: Record<LibraryView, string> = {
    browse: "Browse",
    all: "All Shows",
    genres: "Genres",
  };

  const allShowsConfig = {
    itemType: "Series" as const,
    title: "TV Shows",
    backPath: BASE_PATH,
    searchPlaceholder: "Search shows...",
    sortOptions: [
      { key: "SortName", label: "A-Z" },
      { key: "ProductionYear", label: "Year" },
      { key: "DateCreated", label: "Recently Added" },
      { key: "CommunityRating", label: "Rating" },
    ],
    defaultSort: "SortName",
    displayComponent: "grid" as const,
  };

  const genresConfig = {
    itemTypes: ["Series" as const],
    title: "TV Genres",
    backPath: BASE_PATH,
    genreIcon:
      "M18 4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4h-4z",
    itemDisplayMode: "poster" as const,
    searchPlaceholder: "Search genres...",
    noItemsMessage: "No shows found in this genre",
  };

  async function load() {
    if (!$currentLibrary) {
      goto("/library");
      return;
    }
    await tv.loadSections($currentLibrary.id);
  }

  const { markLoaded, checkServerReachability } = useServerReachabilityReload(load);

  onMount(async () => {
    await load();
    markLoaded();
  });

  $effect(() => {
    checkServerReachability($isServerReachable);
  });

  function handleItemClick(item: MediaItem) {
    switch (item.type) {
      // A season lands on its series, anchored at that season (DR-103).
      case "Season":
        goto(seasonRedirectTarget(item) ?? `/library/${item.id}`);
        break;
      // An episode opens inside its series, never as a bare episode page and
      // never straight into the player (ux-flows §5B.1, §5B.5).
      case "Episode":
        goto(episodeFocusHref(item));
        break;
      case "Series":
      case "Folder":
        goto(`/library/${item.id}`);
        break;
      default:
        goto(`/player/${item.id}`);
        break;
    }
  }

  const heroItems = $derived($tv.heroItems);
  const continueWatching = $derived($tv.continueWatching);
  const nextUp = $derived($tv.nextUp);
  const recentlyAdded = $derived($tv.recentlyAdded);
  const genreRows = $derived($tv.genreRows);
  const isLoading = $derived($tv.isLoading);
  const hasContent = $derived(
    heroItems.length > 0 ||
      continueWatching.length > 0 ||
      nextUp.length > 0 ||
      recentlyAdded.length > 0
  );
</script>

<div class="space-y-6 pb-8">
  <!-- Header — one per page, shared by every tab -->
  <div class="flex items-center justify-between px-4">
    <h1 class="text-3xl font-bold text-white">{$currentLibrary?.name ?? "TV Shows"}</h1>
    <button
      onclick={() => { library.setCurrentLibrary(null); navigateUp("/library"); }}
      class="p-2 rounded-lg hover:bg-white/10 transition-colors text-gray-400 hover:text-white"
      title="Back to libraries"
      aria-label="Back to libraries"
    >
      <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
      </svg>
    </button>
  </div>

  <LibraryViewTabs basePath={BASE_PATH} active={view} labels={tabLabels} />

  {#if view === "all"}
    <div class="px-4">
      <GenericMediaListPage config={allShowsConfig} showHeader={false} />
    </div>
  {:else if view === "genres"}
    <div class="px-4">
      <GenericGenreBrowser config={genresConfig} showHeader={false} />
    </div>
  {:else if isLoading}
    <div class="flex justify-center items-center py-32">
      <div class="w-8 h-8 border-2 border-[var(--color-jellyfin)] border-t-transparent rounded-full animate-spin"></div>
    </div>
  {:else}
    <div class="space-y-8">
      <!-- Hero Banner -->
      {#if heroItems.length > 0}
        <HeroBanner items={heroItems} />
      {/if}

      <!-- Continue Watching -->
      {#if continueWatching.length > 0}
        <Carousel
          title="Continue Watching"
          items={continueWatching}
          onItemClick={handleItemClick}
        />
      {/if}

      <!-- Next Up -->
      {#if nextUp.length > 0}
        <Carousel title="Next Up" items={nextUp} onItemClick={handleItemClick} />
      {/if}

      <!-- Recently Added -->
      {#if recentlyAdded.length > 0}
        <Carousel
          title="Recently Added"
          items={recentlyAdded}
          onItemClick={handleItemClick}
          showAll={() => goto(libraryViewUrl(BASE_PATH, "all"))}
        />
      {/if}

      <!-- One slider per genre -->
      {#each genreRows as row (row.id)}
        <Carousel
          title={row.name}
          items={row.items}
          onItemClick={handleItemClick}
          showAll={() => goto(libraryViewUrl(BASE_PATH, "genres"))}
        />
      {/each}

      {#if !hasContent}
        <p class="px-4 text-gray-400">Nothing here yet. Start watching something to fill this page.</p>
      {/if}
    </div>
  {/if}
</div>
