<script lang="ts">
  import { onMount } from "svelte";
  import { goto } from "$app/navigation";
  import { auth } from "$lib/stores/auth";
  import type { MediaItem, MediaKind, Person } from "$lib/api/types";
  import MediaCard from "./MediaCard.svelte";

  interface Props {
    currentItemId: string;
    itemKind: MediaKind;
    genres?: string[];
    people?: Person[];
    artistIds?: string[];
    limit?: number;
  }

  let {
    currentItemId,
    itemKind,
    genres = [],
    people = [],
    artistIds = [],
    limit = 12
  }: Props = $props();

  let relatedItems = $state<MediaItem[]>([]);
  let loading = $state(true);
  let error = $state<string | null>(null);

  onMount(async () => {
    await loadRelatedItems();
  });

  async function loadRelatedItems() {
    loading = true;
    error = null;
    relatedItems = [];

    try {
      const repo = auth.getRepository();
      if (!repo) {
        error = "Not authenticated";
        return;
      }

      let items: MediaItem[] = [];

      // First, try to use the Similar Items API (preferred method)
      // This works for Movies and Series (most common cases)
      if (itemKind === "movie" || itemKind === "series") {
        try {
          const result = await repo.getSimilarItems(currentItemId, limit);
          items = result.items.filter(item => item.id !== currentItemId);

          if (items.length > 0) {
            relatedItems = items.slice(0, limit);
            return; // Success - return early
          }
        } catch (e) {
          console.warn("Failed to load similar items from API:", e);
          // Fall through to genre-based loading
        }
      }

      // Fallback: Load by genres using search (works for all item types)
      if (genres && genres.length > 0) {
        try {
          // Search by first genre to find related items. This single-kind query
          // maps the neutral kind to the concrete Jellyfin item type it needs.
          const searchTerm = genres[0];
          const itemTypeForKind: Record<string, string> = {
            movie: "Movie", series: "Series", album: "MusicAlbum", track: "Audio", artist: "MusicArtist",
          };
          const result = await repo.search(searchTerm, {
            includeItemTypes: [itemTypeForKind[itemKind] ?? "Movie"],
            limit: limit * 2
          });

          items = result.items.filter(item => item.id !== currentItemId);
        } catch (e) {
          console.warn("Failed to load related items by genre:", e);
        }
      }

      // For music albums, also try to load by artist (if we don't have enough from similar API)
      if (itemKind === "album" && artistIds && artistIds.length > 0 && items.length === 0) {
        try {
          // Search for other albums by artist name from first artist
          const result = await repo.search(artistIds[0], {
            includeItemTypes: ["MusicAlbum"],
            limit: limit * 2
          });

          const artistAlbums = result.items.filter(item => item.id !== currentItemId);
          items = [...items, ...artistAlbums];
        } catch (e) {
          console.warn("Failed to load albums by artist:", e);
        }
      }

      // Remove duplicates and limit results
      const uniqueItems = Array.from(
        new Map(items.map(item => [item.id, item])).values()
      ).slice(0, limit);

      relatedItems = uniqueItems;
    } catch (e) {
      error = e instanceof Error ? e.message : "Failed to load related items";
      console.error("Error loading related items:", e);
    } finally {
      loading = false;
    }
  }

  function getTitle(): string {
    switch (itemKind) {
      case "movie":
        return "Related Movies";
      case "series":
        return "Related Shows";
      case "album":
        return "Related Albums";
      case "track":
        return "Related Tracks";
      default:
        return "Related Items";
    }
  }

  function handleItemClick(item: MediaItem) {
    goto(`/library/${item.id}`);
  }
</script>

<div class="space-y-4">
  <h2 class="text-xl font-semibold text-white">{getTitle()}</h2>

  {#if loading}
    <!-- Skeleton loading state -->
    {@const isMusicContent = itemKind === "album" || itemKind === "track"}
    <div class="grid grid-cols-2 md:grid-cols-6 gap-4">
      {#each Array(6) as _}
        <div class="animate-pulse">
          <div class="{isMusicContent ? 'aspect-square' : 'aspect-[2/3]'} bg-[var(--color-surface)] rounded-lg mb-2"></div>
          <div class="h-4 bg-[var(--color-surface)] rounded w-3/4 mb-1"></div>
          <div class="h-3 bg-[var(--color-surface)] rounded w-1/2"></div>
        </div>
      {/each}
    </div>
  {:else if error}
    <div class="text-center py-8 text-gray-400">
      <p>Could not load related items</p>
    </div>
  {:else if relatedItems.length === 0}
    <div class="text-center py-8 text-gray-400">
      <p>No related items found</p>
    </div>
  {:else}
    <div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-4">
      {#each relatedItems as item (item.id)}
        <MediaCard {item} onclick={() => handleItemClick(item)} />
      {/each}
    </div>
  {/if}
</div>
