import { render, screen, fireEvent } from '@testing-library/react';
import {
  ErrorMessage,
  FullScreenError,
  FieldError,
  EmptyState,
} from '../ErrorMessage';

describe('ErrorMessage Component', () => {
  it('renders error message', () => {
    render(<ErrorMessage message="Something went wrong" />);
    expect(screen.getByText('Something went wrong')).toBeInTheDocument();
  });

  it('renders with different severity levels', () => {
    const { rerender, container } = render(
      <ErrorMessage message="Error" severity="error" />
    );
    let alert = container.querySelector('[role="alert"]');
    expect(alert).toHaveClass('bg-red-50', 'border-red-200');

    rerender(<ErrorMessage message="Warning" severity="warning" />);
    alert = container.querySelector('[role="alert"]');
    expect(alert).toHaveClass('bg-yellow-50', 'border-yellow-200');

    rerender(<ErrorMessage message="Info" severity="info" />);
    alert = container.querySelector('[role="alert"]');
    expect(alert).toHaveClass('bg-blue-50', 'border-blue-200');
  });

  it('calls onRetry when retry button is clicked', () => {
    const handleRetry = jest.fn();
    render(<ErrorMessage message="Failed to load" onRetry={handleRetry} />);

    const retryButton = screen.getByRole('button', { name: /retry/i });
    fireEvent.click(retryButton);

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

  it('calls onDismiss when dismiss button is clicked', () => {
    const handleDismiss = jest.fn();
    render(<ErrorMessage message="Error" onDismiss={handleDismiss} />);

    const dismissButton = screen.getByLabelText('Dismiss');
    fireEvent.click(dismissButton);

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

  it('renders without action buttons', () => {
    render(<ErrorMessage message="Error" />);
    expect(screen.queryByRole('button')).not.toBeInTheDocument();
  });

  it('has proper ARIA attributes', () => {
    render(<ErrorMessage message="Error occurred" />);
    const alert = screen.getByRole('alert');
    expect(alert).toHaveAttribute('aria-live', 'polite');
  });
});

describe('FullScreenError Component', () => {
  it('renders full screen error with title and message', () => {
    render(
      <FullScreenError
        title="Page Not Found"
        message="The page you are looking for does not exist."
      />
    );
    expect(screen.getByText('Page Not Found')).toBeInTheDocument();
    expect(
      screen.getByText('The page you are looking for does not exist.')
    ).toBeInTheDocument();
  });

  it('uses default title when not provided', () => {
    render(<FullScreenError message="An error occurred" />);
    expect(screen.getByText('Something went wrong')).toBeInTheDocument();
  });

  it('calls onRetry when retry button is clicked', () => {
    const handleRetry = jest.fn();
    render(
      <FullScreenError
        message="Failed to load"
        onRetry={handleRetry}
      />
    );

    const retryButton = screen.getByRole('button', { name: /try again/i });
    fireEvent.click(retryButton);

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

  it('calls onBack when back button is clicked', () => {
    const handleBack = jest.fn();
    render(
      <FullScreenError
        message="Error"
        onBack={handleBack}
      />
    );

    const backButton = screen.getByRole('button', { name: /go back/i });
    fireEvent.click(backButton);

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

  it('renders with custom button labels', () => {
    render(
      <FullScreenError
        message="Error"
        onRetry={() => {}}
        onBack={() => {}}
        retryLabel="Reload"
        backLabel="Return"
      />
    );

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

  it('renders different icon types', () => {
    const { container } = render(
      <FullScreenError message="Error" icon="offline" />
    );
    // Check that SVG is rendered
    expect(container.querySelector('svg')).toBeInTheDocument();
  });
});

describe('FieldError Component', () => {
  it('renders field error message', () => {
    render(<FieldError message="Email is required" />);
    expect(screen.getByText('Email is required')).toBeInTheDocument();
  });

  it('has proper ARIA role', () => {
    render(<FieldError message="Invalid input" />);
    const alert = screen.getByRole('alert');
    expect(alert).toBeInTheDocument();
  });

  it('renders with icon', () => {
    const { container } = render(<FieldError message="Error" />);
    const svg = container.querySelector('svg');
    expect(svg).toBeInTheDocument();
  });

  it('applies custom className', () => {
    render(<FieldError message="Error" className="mb-4" />);
    const alert = screen.getByRole('alert');
    expect(alert).toHaveClass('mb-4');
  });
});

describe('EmptyState Component', () => {
  it('renders empty state with title', () => {
    render(<EmptyState title="No items found" />);
    expect(screen.getByText('No items found')).toBeInTheDocument();
  });

  it('renders with message', () => {
    render(
      <EmptyState
        title="No data"
        message="Get started by adding your first item"
      />
    );
    expect(
      screen.getByText('Get started by adding your first item')
    ).toBeInTheDocument();
  });

  it('renders action button when provided', () => {
    const handleAction = jest.fn();
    render(
      <EmptyState
        title="Empty"
        actionLabel="Add Item"
        onAction={handleAction}
      />
    );

    const button = screen.getByRole('button', { name: /add item/i });
    expect(button).toBeInTheDocument();

    fireEvent.click(button);
    expect(handleAction).toHaveBeenCalledTimes(1);
  });

  it('renders custom icon', () => {
    const icon = <div data-testid="custom-icon">Icon</div>;
    render(<EmptyState title="Empty" icon={icon} />);
    expect(screen.getByTestId('custom-icon')).toBeInTheDocument();
  });

  it('does not render action button when not provided', () => {
    render(<EmptyState title="Empty" />);
    expect(screen.queryByRole('button')).not.toBeInTheDocument();
  });
});
