/* eslint-disable react/jsx-no-target-blank */
import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react';
import getVolatilityTranslationMeta from 'gatsby-core-theme/src/helpers/volatility';
import getOperatorData from '../../tests/factories/pages/operator.factory';
import { defaultInfoGrid } from '../constants/info-grid';
import {
  getKeyValues,
  generateLabel,
  formatDate,
  generateRtp,
  generateVolatility,
  generateYesorNo,
  generateLicenseAndSupportTypes,
  latestItems,
  isLiveCasino,
  getCurrencies,
  getMaxWin,
  getMaxStake,
  generateLink,
} from './info-grid';

let data;
let gridLabels;
let gridItems;

beforeEach(() => {
  data = getOperatorData();
  gridLabels = defaultInfoGrid[data.template];
  gridItems = getKeyValues(data.relation, gridLabels, data.market);
});
describe('Info Grid helper component', () => {
  test('Get Key values', () => {
    const obj = {
      details: {
        categories: null,
        currencies: {
          0: {
            crypto: 0,
            id: 168,
            iso_code: 'ZAR',
            name: 'South Africa Rand',
            symbol: 'R',
          },
        },
        deposit_methods: {
          0: { id: 1, name: 'Visa' },
          1: { id: 1, name: 'MasterCard' },
          2: { id: 1, name: 'ApplePay' },
        },
        games_amount: '5000',
        live_casinos: { 0: 'casino', 1: 'livecasino', 2: 'sportsbook', 3: 'bonus' },
        software: {
          0: { id: 2, name: '2by2 Gaming', short_name: '2_by_2_gaming' },
          1: { id: 2, name: 'Ash Gaming', short_name: 'ash_gaming' },
          2: { id: 2, name: 'Big Time Gaming', short_name: 'big-time_gaming' },
        },
      },
      info: {
        email: 'hey@casumo.com',
        founded: '2012-01-01',
        licenses: null,
        owner: 'Casumo Services Ltd',
        support_types: '24/7, BitcoinTalk, Email, Facebook, Live chat',
      },
    };
    expect(getKeyValues(data.relation, gridLabels, data.market).toString()).toBe(`${obj}`);
  });

  test('Get Key values when there are other options such as market data and option field to select if primary field is not avaialble', () => {
    const labels = {
      maximum_bet: ['markets[market].maximum_bet || maximum_bet', 'Max bet'],
      bonus_features: ['affiliate_games[market].extra_fields.bonus_features', 'Bonus features'],
      games_amount: ['bonus.games_amount || games_amount', '🎲 Games amount'],
    };
    const obj = { maximum_bet: null, bonus_features: null, games_amount: '5000' };
    expect(getKeyValues(data.relation, labels, data.market).toString()).toBe(`${obj}`);
  });
  test('Generate label for grid item', () => {
   

    
    expect(
      generateLabel(
        Object.keys(gridItems)[2],
        Object.values(gridItems)[2],
        Object.values(gridLabels)[2][2]
      )
    ).toBe('South Africa Rand');
  });
  test('Generate Volatility for grid item', () => {
    const { displayValue } = getVolatilityTranslationMeta(data.relation.volatility);
    expect(generateVolatility(data.relation.volatility)).toBe(displayValue);
  });
  test('format date for grid item', () => {
    expect(formatDate(data.relation.founded)).toBe('2012');
  });
  test('Generate Yes No for grid item', () => {
    expect(generateYesorNo(data.relation.freespins)).toBe('Yes');
  });
  test('Generate RTP for grid item', () => {
    expect(generateRtp(data.relation.rtp)).toBe(null);
  });
  test('Generate latest items for grid item', () => {
    expect(latestItems(data.relation.software)).toBe(
      '2by2 Gaming, Ash Gaming, Big Time Gaming, 2by2 Gaming, Ash Gaming, Big Time Gaming, 2by2 Gaming, Ash Gaming, Big Time Gaming, 2by2 Gaming, Ash Gaming, Big Time Gaming'
    );
  });
  test('Generate latest items when null array passed', () => {
    expect(latestItems(null)).toBe(null);
  });
  test('Generate latest items for a limit', () => {
    expect(latestItems(data.relation.software, null, 5).split(',').length).toBe(5);
    expect(latestItems(data.relation.deposit_methods, null, 3).split(',').length).toBe(3);
  });
  test('Generate latest items for a limit and show how many remaining as tooltip', async () => {
    const { container } = render(
      latestItems(data.relation.software, { showMore: true, tooltip: true }, 5)
    );
    const { container: containerOne } = render(
      latestItems(data.relation.software, { showMore: true, tooltip: true }, 3)
    );

    expect(container).toHaveTextContent(
      '2by2 Gaming, Ash Gaming, Big Time Gaming, 2by2 Gaming, Ash Gaming 7 more'
    );
    expect(container.querySelector('.wrapper')).toHaveTextContent('7 more');
    expect(containerOne).toHaveTextContent('2by2 Gaming, Ash Gaming, Big Time Gaming 9 more');
    expect(containerOne.querySelector('.wrapper')).toHaveTextContent('9 more');
  });
  test('Generate latest items for a limit and show see more text with tooltip', async () => {
    const { container } = render(
      latestItems(
        data.relation.software,
        {
          showMore: true,
          tooltip: true,
          customValue: { translationKey: 'see_more', label: 'see more' },
        },
        5
      )
    );
    const { container: containerOne } = render(
      latestItems(
        data.relation.software,
        {
          showMore: true,
          tooltip: true,
          customValue: { translationKey: 'see_more', label: 'see more' },
        },
        3
      )
    );

    expect(container).toHaveTextContent(
      '2by2 Gaming, Ash Gaming, Big Time Gaming, 2by2 Gaming, Ash Gaming see more'
    );
    expect(container.querySelector('.wrapper')).toHaveTextContent('see more');
    expect(containerOne).toHaveTextContent('2by2 Gaming, Ash Gaming, Big Time Gaming see more');
    expect(containerOne.querySelector('.wrapper')).toHaveTextContent('see more');
  });
  test('Generate latest items for a limit, show how many remaining, and on hover, show remaining items as tooltip', async () => {
    const { container } = render(
      latestItems(data.relation.software, { tooltip: true, showMore: true }, 5)
    );

    fireEvent.mouseEnter(container.querySelector('.wrapper'));

    await waitFor(() => {
      expect(container.querySelector('.tooltip')).toBeInTheDocument();
      expect(container.querySelector('.tooltip')).toHaveTextContent(
        'Big Time Gaming, 2by2 Gaming, Ash Gaming, Big Time Gaming, 2by2 Gaming, Ash Gaming, Big Time Gaming'
      );
    });
  });
  test('Generate latest items for a limit and show how many remaining as a button', async () => {
    const { container } = render(
      latestItems(data.relation.software, { showMore: true, tooltip: false }, 5)
    );

    expect(container).toHaveTextContent(
      '2by2 Gaming, Ash Gaming, Big Time Gaming, 2by2 Gaming, Ash Gaming 7 more'
    );
    expect(container.querySelector('button')).toBeInTheDocument();
    expect(container.querySelector('button')).toHaveTextContent('7 more');
  });
  test('Generate latest items for a limit and show see more text with a button', async () => {
    const { container } = render(
      latestItems(
        data.relation.software,
        {
          showMore: true,
          tooltip: false,
          customValue: { translationKey: 'see_more', label: 'see more' },
        },
        5
      )
    );

    expect(container).toHaveTextContent(
      '2by2 Gaming, Ash Gaming, Big Time Gaming, 2by2 Gaming, Ash Gaming see more'
    );
    expect(container.querySelector('button')).toBeInTheDocument();
    expect(container.querySelector('button')).toHaveTextContent('see more');
  });
  test('Generate license and support types for grid item', () => {
    expect(generateLicenseAndSupportTypes(data.relation.support_types)).toBe(
      ' 24/7, BitcoinTalk, Email, Facebook, Live chat'
    );
  });
  test('Generate license and support types for a limit', () => {
    expect(latestItems(data.relation.support_types, null, 2).split(',').length).toBe(2);
  });
  test('Check if live Casino or not for grid item', () => {
    expect(isLiveCasino(data.relation.software)).toBe('No');
  });
  test('Get currencies for grid item', () => {
    expect(getCurrencies(data.relation.currencies).toString()).toBe('ZAR');
  });
  test('Get max win for grid item', () => {
    expect(
      getMaxWin(data.relation.markets[data.market].maximum_win || data.relation.maximum_win)
    ).toBe(null);
  });
  test('Get max bet for grid item', () => {
    expect(
      getMaxStake(data.relation.markets[data.market].maximum_bet || data.relation.maximum_bet)
    ).toBe(null);
  });
  test('Generate link for email', () => {
    const email = () => (
      <a href="mailto:hey@casumo.com" target="_blank">
        hey@casumo.com
      </a>
    );

    expect(generateLink(data.relation.email, { type: 'email', newTab: true })).toStrictEqual(
      email()
    );
  });
});
