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

import { ErrorWithRetry } from './error-with-retry';

describe('ErrorWithRetry', () => {
  it('renders default title and message', () => {
    render(<ErrorWithRetry />);

    expect(screen.getByText('Something went wrong')).toBeInTheDocument();
    expect(screen.getByText('An error occurred. Try again.')).toBeInTheDocument();
  });

  it('renders custom title and message', () => {
    render(<ErrorWithRetry title="Load failed" message="Could not fetch recommendations." />);

    expect(screen.getByText('Load failed')).toBeInTheDocument();
    expect(screen.getByText('Could not fetch recommendations.')).toBeInTheDocument();
  });

  it('renders retry button when onRetry is provided', () => {
    render(<ErrorWithRetry onRetry={() => {}} />);

    expect(screen.getByRole('button', { name: /try again/i })).toBeInTheDocument();
  });

  it('does not render retry button when onRetry is omitted', () => {
    render(<ErrorWithRetry />);

    expect(screen.queryByRole('button', { name: /try again/i })).not.toBeInTheDocument();
  });

  it('calls onRetry when button is clicked', async () => {
    const onRetry = vi.fn();
    const user = userEvent.setup();

    render(<ErrorWithRetry onRetry={onRetry} />);

    await user.click(screen.getByRole('button', { name: /try again/i }));

    expect(onRetry).toHaveBeenCalledOnce();
  });

  it('shows retrying state and disables button', () => {
    render(<ErrorWithRetry onRetry={() => {}} retrying />);

    const button = screen.getByRole('button', { name: /retrying/i });
    expect(button).toBeDisabled();
    expect(screen.getByText('Retrying...')).toBeInTheDocument();
  });

  it('has role=alert for accessibility', () => {
    render(<ErrorWithRetry />);

    expect(screen.getByRole('alert')).toBeInTheDocument();
  });

  it('applies custom className', () => {
    render(<ErrorWithRetry className="mt-8" />);

    expect(screen.getByRole('alert')).toHaveClass('mt-8');
  });
});
