import { groupBy } from './common';
import {
  filterPages,
  processCardsV2,
  filterGames,
  filterEvents,
  filterOperators,
  processBonus,
  processTopListModule,
  shouldSavePrefilled,
} from './modules';
import { objectsHolder } from '~tests/factories/modules/modules.factory';
import getPageDataList from '~tests/factories/pages/list.factory';
import {
  getSampleCardsV2ModuleManual,
  getSampleCardsV2Filtered,
} from '~tests/factories/modules/card.factory.js';
import { relationData, singleToplistData } from '../../../tests/factories/modules/toplist.factory';

describe('Modules Helper', () => {
  beforeEach(() => {
    jest.resetModules();
    process.env = { ...process.env };
    delete process.env.NODE_ENV;
  });
  test('Cards V2 Manual list', () => {
    const pagesNum = 10;
    const moduleData = getSampleCardsV2ModuleManual();
    const pageList = getPageDataList(pagesNum);

    processCardsV2(
      moduleData,
      groupBy(pageList, 'relation_type'),
      groupBy(getPageDataList(pagesNum), 'id', true)
    );

    expect(moduleData.items).toHaveLength(3);

    moduleData.cards_selector_manual_list.map((item, index) => {
      expect(moduleData.items[index].id).toBe(item.page_id);
      return true;
    });
  });

  test('Cards V2 Filter manual list when inactive operator', () => {
    process.env.GATSBY_SITE_NAME = 'irishluck.ie';
    const pagesNum = 13;
    const moduleData = getSampleCardsV2ModuleManual();
    const pageList = getPageDataList(pagesNum).map((page, i) =>
      i % 2
        ? { ...page, relation_type: 'operator', relation: { ...page.relation, status: 'inactive' } }
        : { ...page, relation_type: 'operator', relation: { ...page.relation, status: 'active' } }
    );
    // eslint-disable-next-line global-require
    const { processCardsV2: processCardsV2Clean } = require('./modules');
    processCardsV2Clean(moduleData, groupBy(pageList, 'relation_type'), groupBy(pageList, 'id'));
    // console.log(pageList);
    const item = [];
    moduleData.cards_selector_manual_list.forEach((page) => {
      // eslint-disable-next-line camelcase
      const { page_id } = page;
      pageList.map((operator) => {
        // eslint-disable-next-line camelcase
        if (operator.id === page_id) {
          // eslint-disable-next-line no-unused-expressions
          operator.relation.status === 'active' ? item.push(operator) : null;
        }
        return item;
      });
    });
    item.forEach((element) => {
      expect(element.relation.status).toEqual('active');
    });
    // expect(item.relation.status).toEqual('active');
    expect(moduleData.num_of_items).toEqual(3);
  });

  test('Cards V2 FIltered list empty', () => {
    const pagesNum = 10;
    const moduleData = getSampleCardsV2Filtered(true);
    const pageList = getPageDataList(pagesNum);
    processCardsV2(moduleData, groupBy(pageList, 'relation_type'), groupBy(pageList, 'id', true));

    expect(moduleData.items).toHaveLength(4);
  });

  test('Cards V2 FIltered inactive', () => {
    process.env.GATSBY_SITE_NAME = 'irishluck.ie';
    const pagesNum = 10;
    const moduleData = getSampleCardsV2Filtered(false, 'Game');
    moduleData.cards_selector_filters_sort_by = 'random';
    moduleData.cards_selector_filters_limit = '3';
    moduleData.cards_page_type = 'operator';
    const pageList = getPageDataList(pagesNum).map((page, i) =>
      i % 2
        ? { ...page, relation_type: 'operator', relation: { ...page.relation, status: 'inactive' } }
        : { ...page, relation_type: 'operator', relation: { ...page.relation, status: 'active' } }
    );
    // eslint-disable-next-line global-require
    const { processCardsV2: processCardsV2Clean } = require('./modules');
    processCardsV2Clean(moduleData, groupBy(pageList, 'relation_type'), groupBy(pageList, 'id'));

    expect(moduleData.items).toHaveLength(3);
    moduleData.items.forEach((item) => {
      expect(item.id % 2).toEqual(0);
    });
  });

  test('filterEvents function', () => {
    const pages = getPageDataList(3);
    pages[0].relation = { event: 'test' };

    const filteredPages = filterEvents(pages);
    expect(filteredPages).toHaveLength(1);
    expect(filteredPages[0].relation.event).toEqual('test');
  });

  test('filterPages function', () => {
    const pages = getPageDataList(3);
    pages[0].author_id = 1;
    const selectedFilters = [1];

    const filteredPages = filterPages(pages, selectedFilters, 'author_id');
    expect(filteredPages).toHaveLength(1);
    expect(filteredPages[0].author_id).toEqual(1);
  });

  test('Filter games function', () => {
    let pages = getPageDataList(2);
    let filtered = filterGames(pages, undefined, undefined);
    expect(filtered).toHaveLength(2);

    pages = getPageDataList(3);
    pages[0].relation = { game_categories: [{ id: 2 }], game_provider: { id: 4 } };
    pages[1].relation = { game_categories: [{ id: 3 }], game_provider: { id: 3 } };
    pages[2].relation = { game_categories: [{ id: 5 }], game_provider: { id: 5 } };
    filtered = filterGames(pages, [3], [4]);

    expect(filtered).toHaveLength(2);
  });

  test('Filter operators function', () => {
    let pages = getPageDataList(3);
    let filtered = filterOperators(pages, undefined, undefined);
    expect(filtered).toHaveLength(3);

    pages = getPageDataList(4);
    pages[0].relation = { software: [{ id: 2 }], types: [1] };
    pages[1].relation = { software: [{ id: 3 }], types: [2] };
    pages[2].relation = { software: [{ id: 4 }], types: [3] };
    pages[3].relation = { software: [{ id: 5 }], types: [4] };

    filtered = filterOperators(pages, [2], [4]);

    expect(filtered).toHaveLength(2);
  });

  test('Process Bonus function', () => {
    const module = { value: 1 };
    const relations = { operator: { 1: { test: 'test' } } };

    processBonus(module, relations);
    expect(module.value.test).toEqual('test');
  });

  test('Process TopList module', () => {
    processTopListModule(singleToplistData, relationData);

    expect(singleToplistData.items[0].items[0].rating_casino).toEqual('4');
    expect(singleToplistData.items[0].items[0].selling_points).toHaveLength(2);
    expect(singleToplistData.items[0].items[0].short_name).toEqual('slotum');
    expect(singleToplistData.items[0].items[0].bonus.deposit_methods).toHaveLength(1);
  });

  test('Process TopList module multiple market', () => {
    processTopListModule(
      singleToplistData,
      relationData,
      {
        operator: [{ relation_id: 6342, market: 'en_za' }],
      },
      { en_za: { path_prefix: 'en' } }
    );

    expect(singleToplistData.items[0].items[0].review_link).toEqual('en/slotum');
    expect(singleToplistData.items[0].items[0].rating_casino).toEqual('4');
    expect(singleToplistData.items[0].items[0].selling_points).toHaveLength(2);
    expect(singleToplistData.items[0].items[0].short_name).toEqual('slotum');
    expect(singleToplistData.items[0].items[0].bonus.deposit_methods).toHaveLength(1);
  });

  test('Should Generate Prefilled', () => {
    const objects = objectsHolder('prefilledModules');
    objects.forEach((prefilled) => {
      expect(shouldSavePrefilled(prefilled.module, prefilled.siteName)).toEqual(prefilled.expected);
    });
  });
});
