<script lang="ts">
  import { onMount, getContext } from "svelte";
  import { goto } from "$app/navigation";
  import type { Library, MediaItem } from "$lib/api/types";
  import {
    library,
    libraries,
    libraryItems,
    isLibraryLoading,
    currentLibrary,
    selectedGenres,
  } from "$lib/stores/library";
  import { isServerReachable } from "$lib/stores/connectivity";
  import type { useScrollGuard } from "$lib/composables/useScrollGuard";
  import LibraryGrid from "$lib/components/library/LibraryGrid.svelte";
  import GenreFilter from "$lib/components/library/GenreFilter.svelte";
  import MosaicGrid from "$lib/components/library/MosaicGrid.svelte";
  import MosaicTile from "$lib/components/library/MosaicTile.svelte";
  import { buildLibraryMosaic } from "$lib/components/library/libraryMosaic";

  // Scroll guard from layout - prevents accidental taps during scrolling (Android)
  const scrollGuard = getContext<ReturnType<typeof useScrollGuard>>("scrollGuard");

  // Search results are rendered exclusively by /search — this page used to
  // render them inline, which made the header search bar appear broken on every
  // other /library/** route. TRACES: UR-049 | DR-063

  const isMusicLibrary = $derived($currentLibrary?.collectionType === "music");

  // Music/TV/Movies libraries have their own dedicated landing pages
  // (/library/music, /library/tv, /library/movies). When `currentLibrary` is one
  // of those, any inline "library content" view here is a STALE leftover from
  // navigating into that page — showing it makes "up"/back from that page render
  // the library's item list instead of the libraries overview. Treat those types
  // as "no inline content" so this page always shows the overview for them,
  // whether we arrived via the header Up affordance or the hardware back button.
  // Live TV / channels / other types still render their content inline here.
  const currentLibraryHasDedicatedPage = $derived(
    $currentLibrary?.collectionType === "music" ||
      $currentLibrary?.collectionType === "tvshows" ||
      $currentLibrary?.collectionType === "movies",
  );
  const showInlineLibraryContent = $derived(!!$currentLibrary && !currentLibraryHasDedicatedPage);

  // Filter out Playlist libraries - they belong in Music sub-library
  const visibleLibraries = $derived.by(() => {
    return $libraries.filter((lib) => lib.collectionType !== "playlists");
  });

  // The overview is a mosaic: rows of one height, tiles of their own widths, so
  // a square music cover sits beside a wide backdrop without either being
  // cropped to the other's shape. Each category also gets a favourites tile of
  // its own, beside the library it belongs to. TRACES: UR-075 | DR-174, DR-175
  const mosaicEntries = $derived(buildLibraryMosaic(visibleLibraries));

  // Track if we've done an initial load and previous server state
  let hasLoadedOnce = false;
  let previousServerReachable = false;

  onMount(async () => {
    if ($libraries.length === 0) {
      await library.loadLibraries();
    }
    hasLoadedOnce = true;
  });

  // Reload when server becomes reachable (handles cache-first timing issue)
  $effect(() => {
    const serverReachable = $isServerReachable;

    if (serverReachable && !previousServerReachable && hasLoadedOnce) {
      // Reload libraries when server becomes available
      library.loadLibraries();
      // Also reload current library items if viewing a library
      if ($currentLibrary) {
        library.loadItems($currentLibrary.id, {
          genres: $selectedGenres.length > 0 ? $selectedGenres : undefined,
        });
      }
    }

    previousServerReachable = serverReachable;
  });

  async function handleLibraryClick(lib: Library) {
    // Prevent accidental taps during scrolling (Android)
    if (scrollGuard.isScrollActive()) return;

    // Route to dedicated music library page
    if (lib.collectionType === "music") {
      library.setCurrentLibrary(lib);
      goto("/library/music");
      return;
    }

    // Route to dedicated TV library landing page
    if (lib.collectionType === "tvshows") {
      library.setCurrentLibrary(lib);
      goto("/library/tv");
      return;
    }

    // Route to dedicated movies library landing page
    if (lib.collectionType === "movies") {
      library.setCurrentLibrary(lib);
      goto("/library/movies");
      return;
    }

    // Live TV channels use a dedicated endpoint
    if (lib.collectionType === "livetv") {
      library.setCurrentLibrary(lib);
      library.clearGenres();
      await library.loadLiveTvChannels();
      return;
    }

    // Plugin "Channels" root list uses a dedicated endpoint
    if (lib.collectionType === "channels") {
      library.setCurrentLibrary(lib);
      library.clearGenres();
      await library.loadChannels();
      return;
    }

    // For other library types, load items normally
    library.setCurrentLibrary(lib);
    library.clearGenres();
    await library.loadItems(lib.id);
  }

  async function handleGenreFilterChange() {
    if ($currentLibrary) {
      await library.loadItems($currentLibrary.id, {
        genres: $selectedGenres.length > 0 ? $selectedGenres : undefined,
      });
    }
  }

  function handleItemClick(item: MediaItem | Library) {
    // Prevent accidental taps during scrolling (Android)
    if (scrollGuard.isScrollActive()) return;

    if ("kind" in item) {
      // It's a MediaItem
      const mediaItem = item as MediaItem;
      // A playable channel leaf plays directly; a channel container drills in.
      if (mediaItem.kind === "channelItem") {
        goto(`/player/${mediaItem.id}`);
        return;
      }
      switch (mediaItem.kind) {
        case "series":
        case "movie":
        case "album":
        case "artist":
        case "folder":
        case "playlist":
        case "channel":
          // Navigate to detail view
          goto(`/library/${mediaItem.id}`);
          break;
        case "episode":
          // Episodes play directly
          goto(`/player/${mediaItem.id}`);
          break;
        default:
          // For other items, try detail page first
          goto(`/library/${mediaItem.id}`);
          break;
      }
    } else {
      // It's a Library
      handleLibraryClick(item as Library);
    }
  }

  function goBackToLibraries() {
    // Prevent accidental taps during scrolling (Android)
    if (scrollGuard.isScrollActive()) return;
    library.setCurrentLibrary(null);
  }
</script>

<div class="space-y-8">
  {#if showInlineLibraryContent}
    <!-- Library content (live TV / channels / other inline-rendered types) -->
    <div class="space-y-6">
      <div class="flex items-center gap-4">
        <button
          onclick={goBackToLibraries}
          class="text-gray-400 hover:text-white transition-colors"
          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>
        <h1 class="text-2xl font-bold text-white">{$currentLibrary?.name}</h1>
      </div>

      {#if isMusicLibrary}
        <GenreFilter onFilterChange={handleGenreFilterChange} />
      {/if}

      <LibraryGrid
        items={$libraryItems}
        loading={$isLibraryLoading}
        onItemClick={handleItemClick}
      />
    </div>
  {:else}
    <!-- Libraries overview -->
    <div>
      <div class="flex items-center justify-between mb-6">
        <h1 class="text-2xl font-bold text-white">Your Libraries</h1>
        <div class="flex items-center gap-1">
          <!-- Favourites cut across libraries, so they live beside the library
             list rather than inside one. ux-flows §5C.2.
             TRACES: UR-067 | DR-117 -->
          <button
            onclick={() => goto("/library/favorites")}
            class="p-2 rounded-lg hover:bg-white/10 transition-colors text-gray-400 hover:text-white"
            title="Favourites"
            aria-label="Favourites"
          >
            <svg
              class="w-6 h-6"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
              stroke-width="2"
            >
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
              />
            </svg>
          </button>
          <button
            onclick={() => goto("/settings")}
            class="p-2 rounded-lg hover:bg-white/10 transition-colors text-gray-400 hover:text-white"
            title="Settings"
          >
            <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="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
              />
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                stroke-width="2"
                d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
              />
            </svg>
          </button>
        </div>
      </div>

      {#if $isLibraryLoading}
        <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
          {#each Array(6) as _}
            <div class="animate-pulse">
              <div class="aspect-video bg-[var(--color-surface)] rounded-lg"></div>
              <div class="mt-2 h-4 bg-[var(--color-surface)] rounded w-3/4"></div>
            </div>
          {/each}
        </div>
      {:else if visibleLibraries.length === 0}
        <div class="text-center py-12 text-gray-400">
          <p>No libraries found</p>
        </div>
      {:else}
        <!-- Favourites are destinations in their own right, not just the icon in
             the header above. The cross-library entry leads the mosaic and each
             category's own favourites sits beside its library — a labelled tile
             at the same weight as a library is the difference between a feature
             people find and one they don't. ux-flows §5C.2.
             TRACES: UR-067, UR-075 | DR-117, DR-174 -->
        <MosaicGrid items={mosaicEntries} gap={8}>
          {#snippet tile(entry)}
            {#if entry.kind === "favorites"}
              <MosaicTile
                label={entry.label}
                width={entry.width}
                height={entry.height}
                accent
                onclick={() => goto(entry.href)}
              >
                {#snippet icon()}
                  <svg
                    class="w-10 h-10 text-[var(--color-jellyfin)]"
                    fill="currentColor"
                    viewBox="0 0 24 24"
                    aria-hidden="true"
                  >
                    <path
                      d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
                    />
                  </svg>
                {/snippet}
              </MosaicTile>
            {:else}
              <MosaicTile
                label={entry.label}
                width={entry.width}
                height={entry.height}
                itemId={entry.library.id}
                imageTag={entry.library.imageTag}
                onRatio={entry.reportRatio}
                onclick={() => handleLibraryClick(entry.library)}
              />
            {/if}
          {/snippet}
        </MosaicGrid>
      {/if}
    </div>
  {/if}
</div>
