import { describe, expect, test, vi } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
import { readable } from 'svelte/store';
import { makeTrack } from '$test-utils/fixtures/track';

const playlistsData = vi.hoisted(() => ({
  owned: [
    {
      id: 'p1',
      user_id: 'u-self',
      owner_username: 'me',
      name: 'B-list',
      description: '',
      is_public: false,
      kind: 'user',
      system_variant: null,
      refreshable: false,
      seed_artist_id: null,
      cover_url: '',
      track_count: 3,
      duration_sec: 0,
      created_at: '',
      updated_at: ''
    },
    {
      id: 'p2',
      user_id: 'u-self',
      owner_username: 'me',
      name: 'A-list',
      description: '',
      is_public: false,
      kind: 'user',
      system_variant: null,
      refreshable: false,
      seed_artist_id: null,
      cover_url: '',
      track_count: 5,
      duration_sec: 0,
      created_at: '',
      updated_at: ''
    }
  ],
  public: [] as unknown[]
}));

vi.mock('$lib/auth/store.svelte', () => ({
  user: { value: { id: 'u-self', username: 'me', is_admin: false } }
}));

vi.mock('$lib/api/playlists', () => ({
  createPlaylistsQuery: () =>
    readable({ data: playlistsData, isPending: false, isError: false }),
  appendTracks: vi.fn().mockResolvedValue({ id: 'p1', tracks: [] }),
  createPlaylist: vi.fn().mockResolvedValue({
    id: 'p3',
    user_id: 'u-self',
    owner_username: 'me',
    name: 'New',
    description: '',
    is_public: false,
    kind: 'user',
    system_variant: null,
    refreshable: false,
    seed_artist_id: null,
    cover_url: '',
    track_count: 0,
    duration_sec: 0,
    created_at: '',
    updated_at: ''
  })
}));

import AddToPlaylistMenu from './AddToPlaylistMenu.svelte';

const track = makeTrack();

describe('AddToPlaylistMenu', () => {
  test('lists own playlists alphabetically followed by "New playlist…"', () => {
    render(AddToPlaylistMenu, { props: { tracks: [track], onClose: vi.fn() } });
    const items = screen.getAllByRole('menuitem');
    // First two should be the playlists in alpha order, then "New playlist…".
    expect(items[0].textContent).toContain('A-list');
    expect(items[1].textContent).toContain('B-list');
    expect(items[2].textContent).toContain('New playlist');
  });

  test('clicking a playlist appends and closes', async () => {
    const onClose = vi.fn();
    const { appendTracks } = await import('$lib/api/playlists');
    render(AddToPlaylistMenu, { props: { tracks: [track], onClose } });
    await fireEvent.click(screen.getByRole('menuitem', { name: /A-list/ }));
    await waitFor(() => expect(onClose).toHaveBeenCalled());
    expect(appendTracks).toHaveBeenCalledWith('p2', ['t1']);
  });

  test('"New playlist…" toggles inline create form', async () => {
    render(AddToPlaylistMenu, { props: { tracks: [track], onClose: vi.fn() } });
    await fireEvent.click(screen.getByRole('menuitem', { name: /New playlist/ }));
    expect(screen.getByPlaceholderText(/playlist name/i)).toBeInTheDocument();
    expect(screen.getByText(/Create & add/i)).toBeInTheDocument();
  });
});
