<script lang="ts">
  import { pageTitle } from '$lib/branding';
  import { goto } from '$app/navigation';
  import { Plus } from 'lucide-svelte';
  import PlaylistCard from '$lib/components/PlaylistCard.svelte';
  import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
  import QuickFilter from '$lib/components/QuickFilter.svelte';
  import EmptyState from '$lib/components/EmptyState.svelte';
  import { createPlaylistsQuery, createPlaylist } from '$lib/api/playlists';
  import { useQueryClient } from '@tanstack/svelte-query';
  import { qk } from '$lib/api/queries';

  const playlistsStore = $derived(createPlaylistsQuery());
  const playlistsQuery = $derived($playlistsStore);
  const queryClient = useQueryClient();

  let filter = $state('');
  const fq = $derived(filter.trim().toLowerCase());
  const ownedFiltered = $derived(
    fq
      ? (playlistsQuery?.data?.owned ?? []).filter((p) => p.name.toLowerCase().includes(fq))
      : (playlistsQuery?.data?.owned ?? [])
  );
  const publicFiltered = $derived(
    fq
      ? (playlistsQuery?.data?.public ?? []).filter((p) => p.name.toLowerCase().includes(fq))
      : (playlistsQuery?.data?.public ?? [])
  );
  const filterMatchesNothing = $derived(
    !!fq && ownedFiltered.length === 0 && publicFiltered.length === 0
  );

  let creating = $state(false);
  let newName = $state('');
  let creatingBusy = $state(false);
  let createError = $state<string | null>(null);
  let inputEl: HTMLInputElement | undefined = $state();

  $effect(() => {
    inputEl?.focus();
  });

  async function submitCreate() {
    if (!newName.trim()) {
      createError = 'Name is required';
      return;
    }
    creatingBusy = true;
    createError = null;
    try {
      const p = await createPlaylist({ name: newName.trim() });
      await queryClient.invalidateQueries({ queryKey: qk.playlists() });
      // Detail route stays at /playlists/[id] (matches the API URL);
      // only the LIST view moved under /library.
      goto(`/playlists/${p.id}`);
    } catch (e: unknown) {
      createError = (e as { message?: string })?.message ?? 'Could not create.';
    } finally {
      creatingBusy = false;
      creating = false;
      newName = '';
    }
  }
</script>

<svelte:head><title>{pageTitle('Library · Playlists')}</title></svelte:head>

<div class="space-y-4">
  <header class="flex flex-wrap items-center justify-between gap-3">
    <h1 class="font-display text-2xl font-medium text-text-primary">Playlists</h1>
    <div class="flex items-center gap-3">
      {#if playlistsQuery?.data
        && (playlistsQuery.data.owned.length + playlistsQuery.data.public.length) > 0}
        <QuickFilter bind:value={filter} placeholder="Filter playlists" />
      {/if}
      <button
        type="button"
        onclick={() => (creating = true)}
        class="inline-flex items-center gap-1 rounded-md bg-action-secondary px-3 py-1.5 text-sm text-action-fg"
      >
        <Plus size={14} strokeWidth={1} />
        New playlist
      </button>
    </div>
  </header>

  {#if creating}
    <div class="rounded-md border border-border bg-surface p-4">
      <label class="block text-sm font-medium text-text-primary">
        Name
        <input
          type="text"
          bind:this={inputEl}
          bind:value={newName}
          placeholder="Saturday morning"
          class="mt-1 w-full rounded border border-border bg-background px-3 py-1.5 text-sm text-text-primary"
          onkeydown={(e) => { if (e.key === 'Enter') submitCreate(); if (e.key === 'Escape') creating = false; }}
        />
      </label>
      {#if createError}
        <p class="mt-2 text-xs text-action-destructive">{createError}</p>
      {/if}
      <div class="mt-3 flex justify-end gap-2">
        <button
          type="button"
          class="rounded-md border border-border px-3 py-1.5 text-sm text-text-muted hover:text-text-primary"
          onclick={() => { creating = false; newName = ''; createError = null; }}
        >
          Cancel
        </button>
        <button
          type="button"
          onclick={submitCreate}
          disabled={creatingBusy || !newName.trim()}
          class="rounded-md bg-action-secondary px-3 py-1.5 text-sm text-action-fg disabled:opacity-50"
        >
          Create
        </button>
      </div>
    </div>
  {/if}

  {#if playlistsQuery?.isPending}
    <p class="text-text-muted">Loading playlists…</p>
  {:else if playlistsQuery?.isError}
    <ApiErrorBanner error={playlistsQuery.error} onRetry={() => playlistsQuery.refetch()} />
  {:else if playlistsQuery?.data}
    {#if filterMatchesNothing}
      <p class="text-sm text-text-muted">
        No playlists match <span class="font-medium">'{filter.trim()}'</span>.
      </p>
    {/if}

    {#if !fq || ownedFiltered.length > 0}
    <section>
      <h2 class="mb-3 text-sm font-medium uppercase tracking-wide text-text-muted">Your playlists</h2>
      {#if playlistsQuery.data.owned.length === 0}
        <EmptyState
          title="No playlists yet"
          hint="Group tracks together for a road trip, a focus session, anything."
        >
          {#snippet actions()}
            <button
              type="button"
              onclick={() => (creating = true)}
              class="inline-flex items-center gap-1 rounded-md bg-action-secondary px-4 py-2 text-sm text-action-fg hover:opacity-90"
            >
              <Plus size={14} strokeWidth={1} />
              Create a playlist
            </button>
          {/snippet}
        </EmptyState>
      {:else}
        <div class="grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
          {#each ownedFiltered as p (p.id)}
            <PlaylistCard playlist={p} />
          {/each}
        </div>
      {/if}
    </section>
    {/if}

    {#if (!fq && playlistsQuery.data.public.length > 0) || (fq && publicFiltered.length > 0)}
      <section>
        <h2 class="mb-3 text-sm font-medium uppercase tracking-wide text-text-muted">From other users</h2>
        <div class="grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
          {#each publicFiltered as p (p.id)}
            <PlaylistCard playlist={p} />
          {/each}
        </div>
      </section>
    {/if}
  {/if}
</div>
