import { render, screen, userEvent } from '../test-utils';
import type { PropsWithChildren } from 'react';

import NavigationOption, { type NavigationOptionProps } from './NavigationOption';

describe('Navigation option', () => {
  const initialProps = {
    id: 'componentId',
    name: 'componentName',
    title: 'Component Title',
    content: <img alt="contentImage" />,
    media: <img alt="media" />,
    onClick: jest.fn(),
    complex: true,
  };
  const customRender = (overrides: Partial<NavigationOptionProps> = {}) =>
    render(<NavigationOption {...initialProps} {...overrides} />);

  afterEach(jest.resetAllMocks);

  describe('render as', () => {
    it('should render `button` when a `href` and `as` is not passed', () => {
      customRender();
      expect(
        screen.getByRole('button', { name: new RegExp(initialProps.title) }),
      ).toBeInTheDocument();
    });

    it('should render anchor when a `href` is passed', () => {
      const href = 'https://wise.com';
      customRender({ href });
      expect(screen.getByRole('link', { name: new RegExp(initialProps.title) })).toHaveAttribute(
        'href',
        href,
      );
    });

    it('should respect `as` prop', () => {
      const View = (props: PropsWithChildren) => <div {...props} data-testid="wrapper" />;
      customRender({ as: View });

      expect(screen.getByTestId('wrapper')).toBeInTheDocument();
    });
  });

  it('should render `media`', () => {
    customRender();
    expect(screen.getByRole('img', { name: 'media' })).toBeInTheDocument();
  });

  it('passes `id`', () => {
    customRender();
    expect(screen.getByRole('button')).toHaveAttribute('id', initialProps.id);
  });

  it('passes `name`', () => {
    customRender();
    expect(screen.getByRole('button')).toHaveAttribute('name', initialProps.name);
  });

  describe('disabled', () => {
    it('should be `false` by default', () => {
      customRender();
      expect(screen.getByRole('button')).toBeEnabled();
    });

    it('should respect the prop', () => {
      customRender({ disabled: true });
      expect(screen.getByRole('button')).toBeDisabled();
    });

    it('calls click handler on option click when not disabled', async () => {
      customRender();
      await userEvent.click(screen.getByRole('button'));
      expect(initialProps.onClick).toHaveBeenCalledTimes(1);
    });

    it('does not call click handler when disabled', async () => {
      customRender({ disabled: true });
      await userEvent.click(screen.getByRole('button'));
      expect(initialProps.onClick).not.toHaveBeenCalled();
    });
  });

  describe('rendering circle', () => {
    it('should render it by default', () => {
      customRender();
      expect(screen.getByRole('img', { name: 'media' }).parentNode).toHaveClass('circle');
    });

    it('should respect `showMediaCircle` prop', () => {
      customRender({ showMediaCircle: false });
      expect(screen.getByRole('img', { name: 'media' }).parentNode).not.toHaveClass('circle');
    });
  });

  it('should pass correct class names to Option', () => {
    customRender({ className: 'test-class-name' });
    expect(screen.getByRole('button')).toHaveClass('test-class-name');
  });

  describe('isContainerAligned', () => {
    it('should not be aligned by default', () => {
      const { container } = customRender();
      expect(container.querySelector('.np-option')).not.toHaveClass('np-option__container-aligned');
    });

    it('renders aligned with container content', () => {
      const { container } = customRender({ isContainerAligned: true });
      expect(container.querySelector('.np-option')).toHaveClass('np-option__container-aligned');
    });
  });
});
