<script lang="ts">
  import { Plus } from 'lucide-svelte';
  import { useQueryClient } from '@tanstack/svelte-query';
  import { createPlaylistsQuery, appendTracks, createPlaylist } from '$lib/api/playlists';
  import { qk } from '$lib/api/queries';
  import { errMessage } from '$lib/api/errors';
  import TrackMenuItem from './TrackMenuItem.svelte';
  import TrackMenuDivider from './TrackMenuDivider.svelte';
  import type { TrackRef } from '$lib/api/types';

  let {
    tracks,
    onClose
  }: {
    tracks: TrackRef[];
    onClose: () => void;
  } = $props();

  const queryClient = useQueryClient();
  const playlistsStore = $derived(createPlaylistsQuery());
  const playlistsQuery = $derived($playlistsStore);
  const ownPlaylists = $derived(
    (playlistsQuery?.data?.owned ?? []).slice().sort((a, b) => a.name.localeCompare(b.name))
  );

  let creating = $state(false);
  let newName = $state('');
  let busy = $state(false);
  let error = $state<string | null>(null);

  async function add(playlistID: string) {
    busy = true;
    error = null;
    try {
      await appendTracks(playlistID, tracks.map((t) => t.id));
      await queryClient.invalidateQueries({ queryKey: qk.playlist(playlistID) });
      await queryClient.invalidateQueries({ queryKey: qk.playlists() });
      onClose();
    } catch (e: unknown) {
      error = errMessage(e);
    } finally {
      busy = false;
    }
  }

  async function createAndAdd() {
    if (!newName.trim()) {
      error = 'Name is required';
      return;
    }
    busy = true;
    error = null;
    try {
      const created = await createPlaylist({ name: newName.trim() });
      await appendTracks(created.id, tracks.map((t) => t.id));
      await queryClient.invalidateQueries({ queryKey: qk.playlists() });
      onClose();
    } catch (e: unknown) {
      error = errMessage(e);
    } finally {
      busy = false;
    }
  }
</script>

<div
  role="menu"
  tabindex="-1"
  aria-label="Add to playlist"
  class="absolute right-full bottom-0 z-30 mr-1 w-56 rounded-md border border-border bg-surface p-1 shadow-lg"
  onclick={(e) => e.stopPropagation()}
  onkeydown={(e) => { e.stopPropagation(); if (e.key === 'Escape') onClose?.(); }}
>
  {#each ownPlaylists as p (p.id)}
    <TrackMenuItem
      icon={Plus}
      label={p.name}
      onclick={() => add(p.id)}
    />
  {/each}

  {#if ownPlaylists.length > 0}
    <TrackMenuDivider />
  {/if}

  {#if !creating}
    <TrackMenuItem
      icon={Plus}
      label="New playlist…"
      onclick={() => { creating = true; }}
    />
  {:else}
    <div class="p-2">
      <input
        type="text"
        placeholder="Playlist name"
        bind:value={newName}
        class="w-full rounded border border-border bg-background px-2 py-1 text-sm text-text-primary"
        onkeydown={(e) => { if (e.key === 'Enter') createAndAdd(); }}
      />
      <div class="mt-2 flex justify-end gap-1">
        <button
          type="button"
          onclick={() => { creating = false; newName = ''; }}
          class="rounded px-2 py-1 text-xs text-text-muted hover:bg-surface-hover"
        >
          Cancel
        </button>
        <button
          type="button"
          onclick={createAndAdd}
          disabled={busy || !newName.trim()}
          class="rounded bg-action-secondary px-2 py-1 text-xs text-action-fg disabled:opacity-50"
        >
          Create & add
        </button>
      </div>
    </div>
  {/if}

  {#if error}
    <p class="px-2 py-1 text-xs text-action-destructive">{error}</p>
  {/if}
</div>
