import React from 'react';

import '@testing-library/jest-dom';
import { render } from '@testing-library/react';

import { noop } from 'utils/common';

import { THEME } from '../../constants';
import { Alert, alertClassName } from './Alert';
import { ALERT_TYPE } from './types';

describe('Alert', () => {
  const content = 'Alert content';

  test('applies theme class', () => {
    const theme = THEME.dark;
    const { container } = render(
      <Alert
        text={content}
        type={ALERT_TYPE.success}
        theme={theme}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);
    expect(alert).not.toBeNull();
    expect(alert).toHaveClass(`${alertClassName(null)}--${theme}`);
  });

  test('renders success variant', () => {
    const type = ALERT_TYPE.success;
    const { container } = render(
      <Alert
        text={content}
        type={type}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);
    expect(alert).not.toBeNull();
    expect(alert).toHaveClass(`${alertClassName(null)}--${type}`);
  });

  test('renders error variant', () => {
    const type = ALERT_TYPE.error;
    const { container } = render(
      <Alert
        text={content}
        type={type}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);
    expect(alert).not.toBeNull();
    expect(alert).toHaveClass(`${alertClassName(null)}--${type}`);
  });

  test('renders warning variant', () => {
    const type = ALERT_TYPE.warning;
    const { container } = render(
      <Alert
        text={content}
        type={type}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);
    expect(alert).not.toBeNull();
    expect(alert).toHaveClass(`${alertClassName(null)}--${type}`);
  });

  test('renders info variant', () => {
    const type = ALERT_TYPE.info;
    const { container } = render(
      <Alert
        text={content}
        type={type}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);
    expect(alert).not.toBeNull();
    expect(alert).toHaveClass(`${alertClassName(null)}--${type}`);
  });

  test('renders info variant', () => {
    const type = ALERT_TYPE.info;
    const { container } = render(
      <Alert
        text={content}
        type={type}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);
    expect(alert).not.toBeNull();
    expect(alert).toHaveClass(`${alertClassName(null)}--${type}`);
  });

  test('applies custom class', () => {
    const customClassName = 'alert-custom-class';
    const { container } = render(
      <Alert
        className={customClassName}
        text={content}
        type={ALERT_TYPE.success}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);
    expect(alert).not.toBeNull();
    expect(alert).toHaveClass(customClassName);
  });

  test('renders title', () => {
    const { container } = render(
      <Alert
        title="Alert title"
        text={content}
        type={ALERT_TYPE.success}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);

    if (alert) {
      const titleElement = alert.querySelector(`.${alertClassName('title')}`);
      expect(titleElement).not.toBeNull();
    } else {
      expect(alert).toThrow('Alert does not exist');
    }
  });

  test('renders link', () => {
    const { container } = render(
      <Alert
        link={{
          text: 'Hyperlink',
          attributes: {
            target: '_blank',
            href: 'https://google.com',
          },
        }}
        text={content}
        type={ALERT_TYPE.success}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);

    if (alert) {
      const linkElement = alert.querySelector(`.${alertClassName('link')}`);
      expect(linkElement).not.toBeNull();
    } else {
      expect(alert).toThrow('Alert does not exist');
    }
  });

  test('renders action button', () => {
    const { container } = render(
      <Alert
        action={{
          text: 'Action',
          onClick: noop,
        }}
        text={content}
        type={ALERT_TYPE.success}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);

    if (alert) {
      const actionElement = alert.querySelector(`.${alertClassName('action')}`);
      expect(actionElement).not.toBeNull();
    } else {
      expect(alert).toThrow('Alert does not exist');
    }
  });

  test('renders close button', () => {
    const { container } = render(
      <Alert
        onDismiss={noop}
        text={content}
        type={ALERT_TYPE.success}
      />,
    );

    const alert = container.querySelector(`.${alertClassName(null)}`);

    if (alert) {
      const closeElement = alert.querySelector(`.${alertClassName('close')}`);
      expect(closeElement).not.toBeNull();
    } else {
      expect(alert).toThrow('Alert does not exist');
    }
  });
});
