import { describe, it, expect, vi } from 'vitest';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { TrackListSelectionActions } from './TrackListSelectionActions';

describe('TrackListSelectionActions', () => {
  const mockOnPlay = vi.fn();
  const mockOnDelete = vi.fn();
  const mockOnLike = vi.fn();
  const mockOnDownload = vi.fn();
  const mockOnMore = vi.fn();
  const mockOnClearSelection = vi.fn();

  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('should not render when selectedCount is 0', () => {
    const { container } = render(
      <TrackListSelectionActions selectedCount={0} selectedTrackIds={[]} />,
    );
    expect(container.firstChild).toBeNull();
  });

  it('should render when selectedCount is greater than 0', () => {
    render(
      <TrackListSelectionActions selectedCount={1} selectedTrackIds={[1]} />,
    );
    expect(screen.getByText(/1 piste sélectionnée/)).toBeInTheDocument();
  });

  it('should display correct count for multiple tracks', () => {
    render(
      <TrackListSelectionActions
        selectedCount={5}
        selectedTrackIds={[1, 2, 3, 4, 5]}
      />,
    );
    expect(screen.getByText(/5 pistes sélectionnées/)).toBeInTheDocument();
  });

  it('should call onPlay when play button is clicked', async () => {
    const user = userEvent.setup();
    render(
      <TrackListSelectionActions
        selectedCount={2}
        selectedTrackIds={[1, 2]}
        onPlay={mockOnPlay}
      />,
    );

    const playButton = screen.getByLabelText(/Lire.*pistes/);
    await user.click(playButton);

    expect(mockOnPlay).toHaveBeenCalledWith([1, 2]);
  });

  it('should call onDelete when delete button is clicked', async () => {
    const user = userEvent.setup();
    render(
      <TrackListSelectionActions
        selectedCount={2}
        selectedTrackIds={[1, 2]}
        onDelete={mockOnDelete}
      />,
    );

    const deleteButton = screen.getByLabelText(/Supprimer.*pistes/);
    await user.click(deleteButton);

    expect(mockOnDelete).toHaveBeenCalledWith([1, 2]);
  });

  it('should call onLike when like button is clicked', async () => {
    const user = userEvent.setup();
    render(
      <TrackListSelectionActions
        selectedCount={2}
        selectedTrackIds={[1, 2]}
        onLike={mockOnLike}
      />,
    );

    const likeButton = screen.getByLabelText(/Ajouter.*favoris/);
    await user.click(likeButton);

    expect(mockOnLike).toHaveBeenCalledWith([1, 2]);
  });

  it('should call onDownload when download button is clicked', async () => {
    const user = userEvent.setup();
    render(
      <TrackListSelectionActions
        selectedCount={2}
        selectedTrackIds={[1, 2]}
        onDownload={mockOnDownload}
      />,
    );

    const downloadButton = screen.getByLabelText(/Télécharger.*pistes/);
    await user.click(downloadButton);

    expect(mockOnDownload).toHaveBeenCalledWith([1, 2]);
  });

  it('should call onMore when more button is clicked', async () => {
    const user = userEvent.setup();
    render(
      <TrackListSelectionActions
        selectedCount={2}
        selectedTrackIds={[1, 2]}
        onMore={mockOnMore}
      />,
    );

    const moreButton = screen.getByLabelText(/Plus d'options/);
    await user.click(moreButton);

    expect(mockOnMore).toHaveBeenCalledWith([1, 2]);
  });

  it('should call onClearSelection when clear button is clicked', async () => {
    const user = userEvent.setup();
    render(
      <TrackListSelectionActions
        selectedCount={2}
        selectedTrackIds={[1, 2]}
        onClearSelection={mockOnClearSelection}
      />,
    );

    const clearButton = screen.getByLabelText(
      'Désélectionner toutes les pistes',
    );
    await user.click(clearButton);

    expect(mockOnClearSelection).toHaveBeenCalled();
  });

  it('should only show buttons for provided actions', () => {
    render(
      <TrackListSelectionActions
        selectedCount={2}
        selectedTrackIds={[1, 2]}
        onPlay={mockOnPlay}
        onDelete={mockOnDelete}
      />,
    );

    expect(screen.getByLabelText(/Lire/)).toBeInTheDocument();
    expect(screen.getByLabelText(/Supprimer/)).toBeInTheDocument();
    expect(screen.queryByLabelText(/favoris/)).not.toBeInTheDocument();
    expect(screen.queryByLabelText(/Télécharger/)).not.toBeInTheDocument();
  });

  it('should have accessible attributes', () => {
    render(
      <TrackListSelectionActions
        selectedCount={3}
        selectedTrackIds={[1, 2, 3]}
        onPlay={mockOnPlay}
      />,
    );

    const toolbar = screen.getByRole('toolbar');
    expect(toolbar).toHaveAttribute('aria-label');
  });

  it('should apply custom className', () => {
    const { container } = render(
      <TrackListSelectionActions
        selectedCount={1}
        selectedTrackIds={[1]}
        className="custom-class"
      />,
    );

    const toolbar = container.querySelector('[role="toolbar"]');
    expect(toolbar).toHaveClass('custom-class');
  });
});
