/**
 * Tests pour PlaylistBatchActions
 * T0506: Create Playlist Batch Operations
 */

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { PlaylistBatchActions } from './PlaylistBatchActions';
import type { Playlist } from '../types';

// Mock hooks
vi.mock('../hooks/usePlaylist', () => ({
  useDeletePlaylist: vi.fn(() => ({
    mutateAsync: vi.fn().mockResolvedValue(undefined),
  })),
  useCreateShareLink: vi.fn(() => ({
    mutateAsync: vi
      .fn()
      .mockResolvedValue({ share_link: 'https://example.com/share/123' }),
  })),
}));

vi.mock('@/hooks/useToast', () => ({
  useToast: vi.fn(() => ({
    toast: vi.fn(),
  })),
}));

// Mock clipboard API
Object.assign(navigator, {
  clipboard: {
    writeText: vi.fn().mockResolvedValue(undefined),
  },
});

describe('PlaylistBatchActions', () => {
  const mockPlaylists: Playlist[] = [
    {
      id: 1,
      user_id: 1,
      title: 'Playlist 1',
      description: 'Description 1',
      is_public: true,
      track_count: 5,
      created_at: '2024-01-01T00:00:00Z',
      updated_at: '2024-01-01T00:00:00Z',
    },
    {
      id: 2,
      user_id: 1,
      title: 'Playlist 2',
      description: 'Description 2',
      is_public: false,
      track_count: 10,
      created_at: '2024-01-02T00:00:00Z',
      updated_at: '2024-01-02T00:00:00Z',
    },
  ];

  const mockOnSelectionClear = vi.fn();
  const mockOnPlaylistsDeleted = vi.fn();

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

  it('should not render when no playlists are selected', () => {
    const { container } = render(
      <PlaylistBatchActions
        selectedPlaylists={[]}
        onSelectionClear={mockOnSelectionClear}
      />,
    );
    expect(container.firstChild).toBeNull();
  });

  it('should render when playlists are selected', () => {
    render(
      <PlaylistBatchActions
        selectedPlaylists={[mockPlaylists[0]]}
        onSelectionClear={mockOnSelectionClear}
      />,
    );

    expect(screen.getByText(/1 playlist sélectionnée/)).toBeInTheDocument();
  });

  it('should display correct count for multiple playlists', () => {
    render(
      <PlaylistBatchActions
        selectedPlaylists={mockPlaylists}
        onSelectionClear={mockOnSelectionClear}
      />,
    );

    expect(screen.getByText(/2 playlists sélectionnées/)).toBeInTheDocument();
  });

  it('should call onSelectionClear when clear button is clicked', async () => {
    const user = userEvent.setup();
    render(
      <PlaylistBatchActions
        selectedPlaylists={[mockPlaylists[0]]}
        onSelectionClear={mockOnSelectionClear}
      />,
    );

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

    expect(mockOnSelectionClear).toHaveBeenCalledTimes(1);
  });

  it('should export playlists to JSON', async () => {
    const user = userEvent.setup();
    const createElementSpy = vi.spyOn(document, 'createElement');
    const appendChildSpy = vi.spyOn(document.body, 'appendChild');
    const removeChildSpy = vi.spyOn(document.body, 'removeChild');

    render(
      <PlaylistBatchActions
        selectedPlaylists={[mockPlaylists[0]]}
        onSelectionClear={mockOnSelectionClear}
      />,
    );

    const exportButton = screen.getByLabelText('Exporter en JSON');
    await user.click(exportButton);

    await waitFor(() => {
      expect(createElementSpy).toHaveBeenCalledWith('a');
      expect(appendChildSpy).toHaveBeenCalled();
      expect(removeChildSpy).toHaveBeenCalled();
    });
  });

  it('should export playlists to CSV', async () => {
    const user = userEvent.setup();
    const createElementSpy = vi.spyOn(document, 'createElement');

    render(
      <PlaylistBatchActions
        selectedPlaylists={[mockPlaylists[0]]}
        onSelectionClear={mockOnSelectionClear}
      />,
    );

    const exportButton = screen.getByLabelText('Exporter en CSV');
    await user.click(exportButton);

    await waitFor(() => {
      expect(createElementSpy).toHaveBeenCalledWith('a');
    });
  });

  it('should show delete confirmation dialog', async () => {
    const user = userEvent.setup();
    render(
      <PlaylistBatchActions
        selectedPlaylists={[mockPlaylists[0]]}
        onSelectionClear={mockOnSelectionClear}
        onPlaylistsDeleted={mockOnPlaylistsDeleted}
      />,
    );

    const deleteButton = screen.getByLabelText(
      'Supprimer les playlists sélectionnées',
    );
    await user.click(deleteButton);

    expect(screen.getByText(/Supprimer les playlists \?/)).toBeInTheDocument();
    expect(screen.getByText(/1 playlist/)).toBeInTheDocument();
  });

  it('should have accessible labels', () => {
    render(
      <PlaylistBatchActions
        selectedPlaylists={mockPlaylists}
        onSelectionClear={mockOnSelectionClear}
      />,
    );

    expect(screen.getByRole('region')).toHaveAttribute(
      'aria-label',
      expect.stringContaining('2 playlists sélectionnées'),
    );
  });
});
