import { Edit } from '@transferwise/icons';
import { mockMatchMedia, render, screen, userEvent } from '../../test-utils';
import { ListItem, type ListItemProps } from '../ListItem';

mockMatchMedia();

describe('ListItem.IconButton', () => {
  const renderWith = (overrides: Partial<ListItemProps> = {}) =>
    render(<ListItem title="Test title" {...overrides} />);

  describe('as button', () => {
    it('renders as button by default', () => {
      renderWith({
        control: (
          <ListItem.IconButton>
            <Edit />
          </ListItem.IconButton>
        ),
      });
      expect(screen.getByRole('button')).toBeInTheDocument();
    });

    it('renders as button if onClick is provided', () => {
      renderWith({
        control: (
          <ListItem.IconButton onClick={() => {}}>
            <Edit />
          </ListItem.IconButton>
        ),
      });

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

    it('handles onClick events', async () => {
      const handleClick = jest.fn();
      renderWith({
        control: (
          <ListItem.IconButton onClick={handleClick}>
            <Edit />
          </ListItem.IconButton>
        ),
      });

      await userEvent.click(screen.getByRole('button'));
      expect(handleClick).toHaveBeenCalledTimes(1);
    });

    it('is disabled when ListItem is disabled', async () => {
      const handleClick = jest.fn();
      renderWith({
        disabled: true,
        control: (
          <ListItem.IconButton onClick={handleClick}>
            <Edit />
          </ListItem.IconButton>
        ),
      });

      const button = screen.getByRole('button');
      expect(button).toBeDisabled();
      await userEvent.click(button);
      expect(handleClick).not.toHaveBeenCalled();
    });
  });

  describe('as link', () => {
    it('renders as link when href is provided', () => {
      renderWith({
        control: (
          <ListItem.IconButton href="/test">
            <Edit />
          </ListItem.IconButton>
        ),
      });

      expect(screen.getByRole('link')).toHaveAttribute('href', '/test');
    });

    it('supports target attribute for links', () => {
      renderWith({
        control: (
          <ListItem.IconButton href="/test" target="_blank">
            <Edit />
          </ListItem.IconButton>
        ),
      });

      const link = screen.getByRole('link');
      expect(link).toHaveAttribute('target', '_blank');
      expect(link).toHaveAttribute('rel', 'noopener noreferrer');
    });

    it('handles onClick events', async () => {
      const handleClick = jest.fn();
      renderWith({
        control: (
          <ListItem.IconButton href="#test" onClick={handleClick}>
            <Edit />
          </ListItem.IconButton>
        ),
      });
      await userEvent.click(screen.getByRole('link'));
      expect(handleClick).toHaveBeenCalledTimes(1);
    });

    it('is disabled when ListItem is disabled', async () => {
      renderWith({
        disabled: true,
        control: (
          <ListItem.IconButton href="/test">
            <Edit />
          </ListItem.IconButton>
        ),
      });
      expect(screen.getByRole('link')).toHaveAttribute('aria-disabled', 'true');
    });
  });

  it('renders children content', () => {
    renderWith({
      control: (
        <ListItem.IconButton>
          <Edit />
        </ListItem.IconButton>
      ),
    });

    expect(screen.getByTestId('edit-icon')).toBeInTheDocument();
  });
});
