import React from 'react';
import { render, cleanup, waitFor, screen } from '@testing-library/react';
import { getSampleOperatorCards } from 'gatsby-core-theme/tests/factories/modules/card.factory';
import TemplateFour from './index';

let data;
let props;
let relation;

beforeEach(() => {
  data = getSampleOperatorCards();

  props = {
    item: data.items[0],
    page: {
      template: 'operator_review',
      true_votes: 134,
      false_votes: 20,
    },
  };

  relation = props.item.relation;
});

describe('TemplateFour component', () => {
  test('render with props', () => {
    const { container } = render(<TemplateFour {...props} />);
    expect(container).toBeTruthy();
  });
  test('show correct logo and title', async () => {
    // eslint-disable-next-line global-require
    const func = require('gatsby-core-theme/src/helpers/device-detect');
    func.isNativeImageLazyLoadingSupported = jest.fn(() => true);

    const { getByText } = render(<TemplateFour {...props} />);

    await waitFor(() => {
      const img = screen.getByAltText(relation.standardised_logo_url_object.alt);
      expect(img).toBeVisible();
      expect(img).toHaveAttribute(
        'src',
        'https://cdn.images.com/1656339756/casumo-casino-logo.svg'
      );
      expect(img).toHaveAttribute('width', '88');
      expect(img).toHaveAttribute('height', '88');
      expect(getByText(relation.name)).toBeTruthy();
    });
  });
  test('show correct author image', async () => {
    // eslint-disable-next-line global-require
    const func = require('gatsby-core-theme/src/helpers/device-detect');
    func.isNativeImageLazyLoadingSupported = jest.fn(() => true);

    render(<TemplateFour {...props} />);

    await waitFor(() => {
      const img = screen.getByAltText(props.item.author.name);
      expect(img).toBeVisible();
      expect(img).toHaveAttribute(
        'src',
        'https://cdn.images.com/fit-in/21x21/1666946339/cameron-murphy.png'
      );
      expect(img).toHaveAttribute('width', '21');
      expect(img).toHaveAttribute('height', '21');
    });
  });
  test('if no author data, show nothing', async () => {
    props = {
      ...props,
      item: {
        ...props.item,
        author: null,
      },
    };
    const { container } = render(<TemplateFour {...props} />);

    await waitFor(() => {
      expect(container.querySelector('.authorData')).toBeFalsy();
    });
  });
  test('show correct review link', async () => {
    const { getByText } = render(<TemplateFour {...props} />);
    const link = getByText(`${relation.name} Review`);

    await waitFor(() => {
      expect(link).toBeTruthy();
      expect(link).toHaveAttribute('href', props.item.path);
    });
  });
  test('show correct bonus text', async () => {
    const { container } = render(<TemplateFour {...props} />);

    await waitFor(() => {
      expect(container.querySelectorAll('.detailsBox span').length).toBe(2);
      expect(container.querySelectorAll('.detailsBox span')[0].innerHTML).toBe(
        relation.one_liners.main.one_liner.split('+')[0].replace('&', '&amp;')
      );
      expect(container.querySelectorAll('.detailsBox span')[1].innerHTML).toBe(
        `+${relation.one_liners.main.one_liner.split('+')[1]}`
      );
    });
  });
  test('hide bonus text if operator inactive', async () => {
    props.item.relation.status = 'inactive';
    const { container } = render(<TemplateFour {...props} />);

    await waitFor(() => {
      expect(container.querySelector('.casinoText')).toBeFalsy();
    });
  });
  test('show feedback', async () => {
    const { container } = render(<TemplateFour {...props} />);

    await waitFor(() => {
      expect(container.querySelector('.feedbackCounter')).toBeTruthy();
      expect(container.querySelectorAll('.likes')[0].innerHTML.split('</svg>')[1]).toBe(
        `${props.item.true_votes}`
      );
      expect(container.querySelectorAll('.dislikes')[0].innerHTML.split('</svg>')[1]).toBe(
        `${props.item.false_votes}`
      );
    });
  });
  test('if no feedback, show nothing', async () => {
    props.item.true_votes = null;
    props.item.false_votes = null;
    const { container } = render(<TemplateFour {...props} />);

    await waitFor(() => {
      expect(container.querySelector('.feedbackCounter')).toBeFalsy();
      expect(container.querySelector('.likes')).toBeFalsy();
      expect(container.querySelector('.dislikes')).toBeFalsy();
    });
  });
  test('show rating', async () => {
    const { container } = render(<TemplateFour {...props} />);

    await waitFor(() => {
      expect(container.querySelector('.ratingList')).toBeTruthy();
      expect(container.querySelectorAll('.ratingList li').length).toBe(3);
      expect(container.querySelector('.ratingList li .label').innerHTML).toBe('Games');
      expect(
        container.querySelectorAll('.ratingList li')[2].querySelector('.label').innerHTML
      ).toBe('Support');
    });
  });

  test('should render ribbons when showRibbon is true', () => {
    props.item.relation.ribbons = ['New'];
    const { container } = render(<TemplateFour item={props.item} showRibbon />);
    const ribbonElement = container.querySelector('.ribbon');
    expect(ribbonElement).toBeInTheDocument();
    expect(ribbonElement.textContent).toBe('New');
  });
  test('should not render ribbons when showRibbon is false', () => {
    const { container } = render(<TemplateFour item={props.item} />);
    const ribbonElement = container.querySelector('.ribbon');
    expect(ribbonElement).not.toBeInTheDocument();
  });
  test('should not render ribbons when ribbons array is empty', () => {
    props.item.relation.ribbons = [];
    const { container } = render(<TemplateFour item={props.item} />);
    const ribbonElement = container.querySelector('.ribbon');
    expect(ribbonElement).not.toBeInTheDocument();
  });
});
afterEach(() => {
  cleanup();
});
