import React from 'react';
import { render, cleanup, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';

import { getExtraField, translate, copyrightText } from 'gatsby-core-theme/src/helpers/getters';
import MainProvider from '~context/MainProvider';
import getFooterData from '../../../../../../tests/factories/modules/footer.factory';
import TemplateOne from '.';

const translations = {
  licensed_casinos: 'We only list licensed casinos',
};

const helpText = `
<p>
  Gambling can be addictive, please play responsibly.
  <br>
  If you are a problem gambler, please visit this
  <a href="https://www.begambleaware.org/" target="_blank" rel="nofollow" class="footer-gtm">
    website
  </a>
  in order to get help.
</p>`;
const phoneNum = '- 89 241 5401';

const dmcaImg = (
  <img
    src="https://cdn.irishluck.ie/5d29ae7f19cc9366a119f3ca168395d7.png"
    width="100"
    height="33"
    alt="DMCA.com Protection Status"
  />
);

function renderComponent(footerData) {
  return render(
    <MainProvider
      value={{
        translations,
      }}
    >
      <TemplateOne {...footerData} />
    </MainProvider>
  );
}

let data;
let props;
let footerMenu;
let asSeenOn;
let gamblingText;
let socialIcons;
let copyrightDisclaimer;
let footerLogos;

beforeEach(() => {
  data = getFooterData();
  footerMenu = getExtraField(data?.extra_fields, 'links');
  asSeenOn = getExtraField(data?.extra_fields, 'as_seen_on');
  gamblingText = getExtraField(data?.extra_fields, 'gambling_text');
  socialIcons = getExtraField(data?.extra_fields, 'social_icons');
  copyrightDisclaimer = getExtraField(data.extra_fields, 'copyright_disclaimer');
  footerLogos = getExtraField(data?.extra_fields, 'logos');

  props = {
    section: data,
    template: 'default',
    hasFooterLinks: false,
    footerTemplate: 'template_one',
    showLinks: true,
    copyrightDisclaimer,
    footerLogos,
    footerMenu,
    asSeenOn,
    gamblingText,
    socialIcons,
    hasDisclaimer: true,
    showCopyright: true,
    logo: '../../../../../images/logo.svg',
    securityIcon: '../../../../../images/security.svg',
    helpText,
    phoneNum,
    dmcaImg,
  };
});
describe('Show template one', () => {
  test('render with props', () => {
    const { container } = renderComponent(props);
    expect(container).toBeTruthy();
  });
  test('show correct template ', async () => {
    const { container } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelectorAll('.footer.templateThree').length).toBe(1);
    });
  });
  test('show as seen on', async () => {
    const { container, getByText } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelectorAll('footer > div')).toHaveLength(2);
      expect(container.querySelectorAll('.asSeenOn')).toHaveLength(1);

      // show correct title
      expect(getByText('As Seen On:')).toHaveTextContent(`${asSeenOn.title}:`);

      // show correct number of logos
      expect(container.querySelectorAll('.asSeenOn li')).toHaveLength(3);
    });
  });
  test('hide as seen on', async () => {
    props = {
      ...props,
      asSeenOn: null,
    };
    const { container } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelectorAll('footer > div')).toHaveLength(1);
      expect(container.querySelectorAll('.asSeenOn')).toHaveLength(0);
    });
  });
  test('render menu list', async () => {
    const { container, getByText } = renderComponent(props);

    await waitFor(() => {
      expect(container.querySelectorAll('.topPart')).toHaveLength(1);
      expect(container.querySelectorAll('.links')).toHaveLength(1);
      expect(container.querySelectorAll('.links ul')).toHaveLength(footerMenu.children.length);

      // show correct title
      expect(getByText(footerMenu.children[0].title)).toBeTruthy();
      expect(getByText(footerMenu.children[2].title)).toBeTruthy();

      // show correct number of child lists
      expect(getByText(footerMenu.children[1].title).closest('ul').children).toHaveLength(7);
      expect(getByText(footerMenu.children[2].title).closest('ul').children).toHaveLength(6);

      // show correct url
      expect(
        getByText(footerMenu.children[1].children[0].title).closest('a').getAttribute('href')
      ).toEqual(`/${footerMenu.children[1].children[0].value}`);
      expect(
        getByText(footerMenu.children[2].children[2].title).closest('a').getAttribute('href')
      ).toEqual(`/${footerMenu.children[2].children[2].value}`);
    });
  });
  test('hide menu list', async () => {
    props = {
      ...props,
      showLinks: null,
    };
    const { container } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelectorAll('.links')).toHaveLength(0);
      expect(container.querySelectorAll('.links ul')).toHaveLength(0);
    });
  });
  test('hide gambling text', async () => {
    const { container } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelectorAll('.license > div')).toHaveLength(4);
      expect(container.querySelectorAll('.gamblingText')).toHaveLength(1);
    });
  });
  test('correct security text', async () => {
    const { getByText } = renderComponent(props);
    await waitFor(() => {
      expect(
        getByText(translate(translations, 'licensed_casinos', 'We only list licensed casinos'))
          .closest('span')
          .getAttribute('class')
      ).toContain('securityText');
    });
  });
  test('footer middle part does not show another as seen on', async () => {
    const { container } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelectorAll('.footerHotline > div')).toHaveLength(1);
      expect(container.querySelectorAll('.footerHotline .asSeenOn')).toHaveLength(0);
    });
  });
  test('correct help text', async () => {
    const { container } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelector('.helpText')).toBeTruthy();
      expect(container.querySelector('.helpText').innerHTML).toBe(helpText);
    });
  });
  test('correct phone number', async () => {
    const { getByText, container } = renderComponent(props);
    await waitFor(() => {
      expect(getByText(phoneNum)).toBeTruthy();
      expect(container.querySelector('.phoneNum').innerHTML.split('</svg>')[1]).toBe(phoneNum);
    });
  });
  test('show copyright disclaimer', async () => {
    const { container } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelectorAll('.copyrightDisclaimer')).toBeTruthy();

      expect(container.querySelector('.copyrightDisclaimer').innerHTML).toBe(copyrightDisclaimer);
    });
  });
  test('show copyright', async () => {
    const { container } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelector('.copyrightText')).toHaveTextContent(copyrightText());
    });
  });
  test('hide copyright', async () => {
    props = {
      ...props,
      showCopyright: false,
    };
    const { container } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelector('.copyrightText')).toBeFalsy();
    });
  });
  test('show dmca image', async () => {
    // eslint-disable-next-line global-require
    const func = require('gatsby-core-theme/src/helpers/device-detect');
    func.isNativeImageLazyLoadingSupported = jest.fn(() => true);
    props = {
      ...props,
      showCopyright: false,
      dmcaImage: '../../../../../images/dmca.png',
    };
    const { container } = renderComponent(props);
    expect(container.querySelector('.logos > a').querySelector('img')).toBeTruthy();
    expect(container.querySelector('.logos > a').querySelector('img')).toHaveAttribute(
      'src',
      '../../../../../images/dmca.png'
    );
    expect(container.querySelector('.logos > a').querySelector('img')).toHaveAttribute(
      'loading',
      'lazy'
    );
  });
  test('hide dmca image', async () => {
    props = {
      ...props,
      hasDisclaimer: false,
    };
    const { container } = renderComponent(props);
    await waitFor(() => {
      expect(container.querySelector('.logos > a')).toBeFalsy();
    });
  });
});
afterEach(() => {
  cleanup();
});
