import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/svelte';
import QueueTrackRow from './QueueTrackRow.svelte';
import type { TrackRef } from '$lib/api/types';

const playFromQueueIndex = vi.fn();
const removeFromQueue = vi.fn();
const moveQueueItem = vi.fn();

vi.mock('$lib/player/store.svelte', () => ({
  playFromQueueIndex: (...args: unknown[]) => playFromQueueIndex(...args),
  removeFromQueue: (...args: unknown[]) => removeFromQueue(...args),
  moveQueueItem: (...args: unknown[]) => moveQueueItem(...args)
}));

const sampleTrack: TrackRef = {
  id: 't1',
  title: 'Song Title',
  artist_name: 'Artist Name',
  album_name: 'Album',
  duration_ms: 200000,
  stream_url: '/stream/t1'
} as TrackRef;

describe('QueueTrackRow', () => {
  beforeEach(() => {
    playFromQueueIndex.mockClear();
    removeFromQueue.mockClear();
    moveQueueItem.mockClear();
  });

  it('renders track title and artist', () => {
    render(QueueTrackRow, { props: { track: sampleTrack, index: 3, isCurrent: false } });
    expect(screen.getByText('Song Title')).toBeInTheDocument();
    expect(screen.getByText(/Artist Name/)).toBeInTheDocument();
  });

  it('clicking the body calls playFromQueueIndex with the row index', async () => {
    render(QueueTrackRow, { props: { track: sampleTrack, index: 3, isCurrent: false } });
    const body = screen.getByRole('button', { name: /play song title/i });
    await fireEvent.click(body);
    expect(playFromQueueIndex).toHaveBeenCalledWith(3);
  });

  it('clicking the remove button calls removeFromQueue with the row index', async () => {
    render(QueueTrackRow, { props: { track: sampleTrack, index: 3, isCurrent: false } });
    const remove = screen.getByLabelText(/remove from queue/i);
    await fireEvent.click(remove);
    expect(removeFromQueue).toHaveBeenCalledWith(3);
  });

  it('current row shows the "Now playing" chip', () => {
    render(QueueTrackRow, { props: { track: sampleTrack, index: 3, isCurrent: true } });
    expect(screen.getByText(/now playing/i)).toBeInTheDocument();
  });

  it('current row body click does NOT call playFromQueueIndex', async () => {
    render(QueueTrackRow, { props: { track: sampleTrack, index: 3, isCurrent: true } });
    // The body button has a different aria-label when isCurrent
    const body = screen.getByLabelText(/now playing/i);
    await fireEvent.click(body);
    expect(playFromQueueIndex).not.toHaveBeenCalled();
  });

  it('ArrowDown on the drag handle calls moveQueueItem with index+1', async () => {
    render(QueueTrackRow, { props: { track: sampleTrack, index: 3, isCurrent: false } });
    const handle = screen.getByLabelText(/reorder track/i);
    await fireEvent.keyDown(handle, { key: 'ArrowDown' });
    expect(moveQueueItem).toHaveBeenCalledWith(3, 4);
  });

  it('ArrowUp on the drag handle calls moveQueueItem with index-1', async () => {
    render(QueueTrackRow, { props: { track: sampleTrack, index: 3, isCurrent: false } });
    const handle = screen.getByLabelText(/reorder track/i);
    await fireEvent.keyDown(handle, { key: 'ArrowUp' });
    expect(moveQueueItem).toHaveBeenCalledWith(3, 2);
  });
});
