import { render, screen, userEvent } from '../test-utils';
import Header, { HeaderProps } from '.';

describe('Header', () => {
  const defaultProps: HeaderProps = {
    title: 'Header title',
  };

  const renderHeader = (props: Partial<HeaderProps> = {}) => {
    return render(<Header {...defaultProps} {...props} />);
  };

  it('can set header title', () => {
    renderHeader();
    expect(screen.getByText('Header title')).toBeInTheDocument();
  });

  it('can trigger header action', async () => {
    const onHeaderActionClick = jest.fn();
    renderHeader({
      action: {
        text: 'Click me!',
        onClick: onHeaderActionClick,
      },
    });

    await userEvent.click(screen.getByRole('button', { name: 'Click me!' }));
    expect(onHeaderActionClick).toHaveBeenCalledTimes(1);
  });

  it('can set aria-label property for header action', async () => {
    const onHeaderActionClick = jest.fn();
    renderHeader({
      action: {
        'aria-label': 'Magic',
        text: 'Click me!',
        onClick: onHeaderActionClick,
      },
    });

    await userEvent.click(screen.getByRole('button', { name: 'Magic' }));
    expect(onHeaderActionClick).toHaveBeenCalledTimes(1);
  });

  it('renders header action as a link when href is provided', () => {
    renderHeader({
      action: {
        'aria-label': 'Click me!',
        text: 'I am a link',
        href: 'https://wise.com',
      },
    });

    const link = screen.getByRole('link', { name: 'Click me!' });
    expect(link).toHaveAttribute('href', 'https://wise.com');
  });

  it('renders header with h5 heading tag by default', () => {
    renderHeader();
    expect(screen.getByRole('heading', { name: 'Header title', level: 5 })).toBeInTheDocument();
  });

  it('can render header with specific heading tag', () => {
    renderHeader({ as: 'h3' });
    expect(screen.getByRole('heading', { name: 'Header title', level: 3 })).toBeInTheDocument();
  });

  it('renders header with group level', () => {
    renderHeader({ level: 'group' });
    const header = screen.getByRole('heading', { name: 'Header title' });
    expect(header).toHaveClass('np-header--group');
  });

  it('warns if Header as legend is not inside a fieldset', () => {
    const consoleWarnMock = jest.spyOn(console, 'warn').mockImplementation();

    renderHeader({ as: 'legend' });

    expect(consoleWarnMock).toHaveBeenCalledWith(
      'Legends should be the first child in a fieldset, and this is not possible when including an action',
    );

    consoleWarnMock.mockRestore();
  });

  it('does not warn if Header as legend is inside a fieldset', () => {
    const consoleWarnMock = jest.spyOn(console, 'warn').mockImplementation();

    render(
      <fieldset>
        <Header as="legend" title="Header title" />
      </fieldset>,
    );

    expect(consoleWarnMock).not.toHaveBeenCalled();

    consoleWarnMock.mockRestore();
  });

  it('runs onClick if specified even when it got href prop', async () => {
    const callback = jest.fn();
    renderHeader({
      as: 'h3',
      action: { text: 'Click me', href: '#', onClick: callback },
    });

    const button = screen.getByRole('link', { name: 'Click me' });
    expect(button).toBeInTheDocument();

    await userEvent.click(button);
    expect(callback).toHaveBeenCalledTimes(1);
  });
});
