/**
 * Tests pour PlaylistErrorBoundary
 * T0502: Create Playlist Error Handling Improvements
 */

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { PlaylistErrorBoundary } from './PlaylistErrorBoundary';
import { BrowserRouter } from 'react-router-dom';

// Composant qui lance une erreur pour tester l'ErrorBoundary
const ThrowError = ({ shouldThrow }: { shouldThrow: boolean }) => {
  if (shouldThrow) {
    throw new Error('Test error');
  }
  return <div>No error</div>;
};

// Wrapper pour fournir le router
const renderWithRouter = (component: React.ReactElement) => {
  return render(<BrowserRouter>{component}</BrowserRouter>);
};

describe('PlaylistErrorBoundary', () => {
  beforeEach(() => {
    // Supprimer les erreurs de console pour les tests
    jest.spyOn(console, 'error').mockImplementation(() => {});
  });

  afterEach(() => {
    jest.restoreAllMocks();
  });

  it('should render children when there is no error', () => {
    renderWithRouter(
      <PlaylistErrorBoundary>
        <div>Test content</div>
      </PlaylistErrorBoundary>,
    );

    expect(screen.getByText('Test content')).toBeInTheDocument();
  });

  it('should render error UI when an error occurs', () => {
    renderWithRouter(
      <PlaylistErrorBoundary>
        <ThrowError shouldThrow={true} />
      </PlaylistErrorBoundary>,
    );

    expect(screen.getByText('Erreur de chargement')).toBeInTheDocument();
    expect(screen.getByText(/Une erreur s'est produite/)).toBeInTheDocument();
  });

  it('should call onError callback when error occurs', () => {
    const onError = jest.fn();

    renderWithRouter(
      <PlaylistErrorBoundary onError={onError}>
        <ThrowError shouldThrow={true} />
      </PlaylistErrorBoundary>,
    );

    expect(onError).toHaveBeenCalled();
    expect(onError).toHaveBeenCalledWith(
      expect.any(Error),
      expect.objectContaining({
        componentStack: expect.any(String),
      }),
    );
  });

  it('should reset error state when reset button is clicked', () => {
    renderWithRouter(
      <PlaylistErrorBoundary>
        <ThrowError shouldThrow={true} />
      </PlaylistErrorBoundary>,
    );

    expect(screen.getByText('Erreur de chargement')).toBeInTheDocument();

    const resetButton = screen.getByText('Réessayer');
    fireEvent.click(resetButton);

    // Après le reset, le composant devrait essayer de rendre à nouveau
    // Note: Dans un vrai scénario, le composant enfant ne devrait plus lancer d'erreur
  });

  it('should render custom fallback when provided', () => {
    const customFallback = <div>Custom error message</div>;

    renderWithRouter(
      <PlaylistErrorBoundary fallback={customFallback}>
        <ThrowError shouldThrow={true} />
      </PlaylistErrorBoundary>,
    );

    expect(screen.getByText('Custom error message')).toBeInTheDocument();
    expect(screen.queryByText('Erreur de chargement')).not.toBeInTheDocument();
  });

  it('should display error message when available', () => {
    renderWithRouter(
      <PlaylistErrorBoundary>
        <ThrowError shouldThrow={true} />
      </PlaylistErrorBoundary>,
    );

    expect(screen.getByText('Test error')).toBeInTheDocument();
  });
});
