/* eslint-disable import/no-cycle */
/* eslint-disable camelcase */
/* eslint-disable import/no-extraneous-dependencies */
import loadash from 'lodash/index.js';
import { topListPickKeys } from '../../constants/pick-keys.mjs';
import { generatePlaceholderString } from '../generators.mjs';
import { clonePageForCards, groupBy, removeDuplicates, removeCurrentPage } from './common.mjs';
import settings from '../../constants/settings.mjs';
import ModuleValue from '../../constants/module-value.mjs';
import { shiftFirstOperator, getModuleTitle, getExtraField } from '../getters.mjs';

const pagesGroupedByTemplateId = [];
const { cloneDeep, pick, sampleSize } = loadash;

export function processCardsModule(module, pages, pagesCloned, pagesMappedById) {
  const modelType = module.model_type;
  const displayInput = module.display_input;
  const sortBy = module.sort_by;
  module.items = [];

  if (displayInput === 'automatic' && pages[modelType]) {
    const numOfItems =
      Math.sign(module.num_of_items) === 0 ? pages[modelType].length : Number(module.num_of_items);
    if (sortBy === 'random') {
      const samplePages =
        module.cards_page_type !== 'operator'
          ? pagesCloned[modelType]
          : pagesCloned[modelType].filter(
            (page) =>
              !settings.filter_cards_modules[process.env.GATSBY_SITE_NAME].includes(
                page.relation && page.relation.status
              )
          );
      module.items = sampleSize(samplePages, numOfItems);
    } else {
      module.items = pagesCloned[modelType].slice(0, numOfItems);
    }
  } else if (displayInput === 'custom' && pages[modelType]) {
    const customItems = [];
    module.card_items.forEach((item) => {
      if (pagesMappedById[item]) {
        customItems.push(pagesMappedById[item]);
      }
    });
    module.items = customItems;
  }
  // modify page so it doesn't have too much data
  module.items = module.items.map((item) => clonePageForCards(cloneDeep(item)));
}

export function filterPages(pages, selectedFilters, key) {
  let filteredPages = [];

  if (selectedFilters) {
    selectedFilters.forEach((id) => {
      filteredPages = filteredPages.concat(
        pages.filter((page) => {
          const compareArr = !Array.isArray(page[key]) ? [page[key]] : page[key];
          return compareArr.includes(id);
        })
      );
    });
  } else {
    filteredPages = pages;
  }

  return filteredPages;
}

export function filterGames(pages, selectedCategories, selectedProviders) {
  const pagesFiltered = [];
  if (!selectedCategories && !selectedProviders) {
    return pages;
  }

  pages.forEach((page) => {
    page.relation.game_categories.forEach((game) => {
      if (selectedCategories && selectedCategories.includes(game.id)) {
        pagesFiltered.push(page);
      }
    });
    if (selectedProviders && selectedProviders.includes(page.relation.game_provider.id)) {
      pagesFiltered.push(page);
    }
  });

  return pagesFiltered;
}

export function filterInactiveOperators(items) {
  return items.filter((page) => {
    if (!settings.filter_cards_modules[process.env.GATSBY_SITE_NAME]) {
      return false;
    }

    return !settings.filter_cards_modules[process.env.GATSBY_SITE_NAME].includes(
      page.relation && page.relation.status
    );
  });
}

export function filterEvents(pages) {
  const pagesFiltered = [];
  pages.forEach((page) => {
    if (page.relation && page.relation.event) {
      pagesFiltered.push(page);
    }
  });

  return pagesFiltered;
}

export function filterOperators(pages, selectedProviders, selectedTypes) {
  const pagesFiltered = [];
  if (!selectedTypes && !selectedProviders) {
    return filterInactiveOperators(pages);
  }

  pages.forEach((page) => {
    page.relation.software.forEach((software) => {
      if (selectedProviders && selectedProviders.includes(software.id)) {
        pagesFiltered.push(page);
      }
    });
    page.relation.types.forEach((type) => {
      if (selectedTypes && selectedTypes.includes(type)) {
        pagesFiltered.push(page);
      }
    });
  });

  return filterInactiveOperators(pagesFiltered);
}

export function processCardsV2(module, pagesCloned, pagesMappedById, pageId) {
  const cardType = module.cards_page_type;
  const pageTemplateId = module.cards_page_type_id;
  const sortType = module.cards_selector_filters_sort_by;
  const cardSelector = module.cards_selector;
  const styleName = module.style;
  const moduleSelectedProviders =
    module.cards_selector_filters && module.cards_selector_filters.providers;
  const moduleSelectedCategories =
    module.cards_selector_filters && module.cards_selector_filters.categories;
  const moduleSelectedTypes = module.cards_selector_filters && module.cards_selector_filters.types;

  module.items = [];

  if (cardSelector === 'select_manually') {
    module.cards_selector_manual_list.forEach((page) => {
      // eslint-disable-next-line camelcase
      const { page_id } = page;
      // eslint-disable-next-line no-unused-expressions
      pagesMappedById[page_id] && module.items.push(pagesMappedById[page_id]);
    });

    if (cardType === 'operator') {
      module.items = filterInactiveOperators(module.items);
    }
  } else if (cardSelector === 'use_filters') {
    let pagesList = [];

    if (cardType) {
      // Get all pages by the selected page type
      const pagesGroupedByType = pagesCloned[cardType];

      // Grouping pages by template ID
      if (!pagesGroupedByTemplateId[cardType]) {
        pagesGroupedByTemplateId[cardType] = groupBy(pagesGroupedByType, 'template_id');
      }

      // Populate pagesList if page type and template exists
      pagesList =
        !pagesGroupedByTemplateId[cardType] || !pagesGroupedByTemplateId[cardType][pageTemplateId]
          ? []
          : pagesGroupedByTemplateId[cardType][pageTemplateId];
    } else {
      pagesList = pagesMappedById.map((page) => page);
    }

    // Check if there are pages before starting filtering
    if (pagesList.length > 0) {
      const selectedAuthors = module.cards_selector_filters.page_authors;
      const selectedReviewer = module.cards_selector_filters.page_reviewer;
      const selectedCategories = module.cards_selector_filters.page_categories;

      const pagesFilteredByAuthor = filterPages(pagesList, selectedAuthors, 'author_id');
      // Filter by reviewer
      const pagesFilteredByReviewer = filterPages(
        pagesFilteredByAuthor,
        selectedReviewer,
        'reviewer_id'
      );

      const pagesFilteredByAuthorAndCategory = filterPages(
        pagesFilteredByReviewer,
        selectedCategories,
        'categoryIds',
        pageId
      );

      // Removing any duplicate pages in the final array (because pages may have more than one category)
      const filteredPages = removeDuplicates(pagesFilteredByAuthorAndCategory, 'id');

      // Get limit, if not set 50 as default
      const itemLimit = module.cards_selector_filters_limit || 50;
      let finalizedFilteredPages = [];

      switch (cardType) {
        case 'game':
          finalizedFilteredPages = filterGames(
            filteredPages,
            moduleSelectedCategories,
            moduleSelectedProviders
          );
          break;
        case 'operator':
          finalizedFilteredPages = filterOperators(
            filteredPages,
            moduleSelectedProviders,
            moduleSelectedTypes
          );
          break;
        case 'event':
          finalizedFilteredPages = filterEvents(filteredPages);
          break;
        default:
          finalizedFilteredPages = filteredPages;
      }
      const uniquePages = removeCurrentPage(removeDuplicates(finalizedFilteredPages, 'id'), pageId);

      // Applying sorting
      if (sortType === 'random') {
        module.items = sampleSize(uniquePages, itemLimit);
      } else if (sortType === 'latest') {
        if (uniquePages.length > 0) {
          uniquePages.sort((a, b) => (a.created_at > b.created_at ? -1 : 1));
          module.items = uniquePages.slice(0, itemLimit);
        }
      }
    }
  }

  if (styleName === 'comparison_table' && pageId !== null && cardType === 'operator') {
    shiftFirstOperator(pageId, module, pagesMappedById);
  }

  // Check for module title placeholders
  if (pageId !== null) {
    module.module_title = getModuleTitle(module, pagesMappedById[pageId]);
  }

  // modify page so it doesn't have too much data
  module.items = module.items.map((item) => clonePageForCards(cloneDeep(item), module.style));
}

export function processBonus(module, relations) {
  module.value = relations.operator[module.value];
}

export function processArchiveModule(module, pages) {
  const modelType = module.model_type;
  const limit = pages[modelType].length > 9 ? 9 : pages[modelType].length;
  const items = cloneDeep(pages[modelType].slice(0, limit));
  module.items = items.map((item) => clonePageForCards(item));
  module.currentPage = 1;
  module.numOfPages = 1;
}

export function processTopListModule(module, relations, pages, markets) {
  module.items = module.items.map((listItem) => {
    listItem.items = listItem.items.map((item) => {
      // Remove the ribbons if are empty, will be add ribbons from operator
      if (item.ribbons && item.ribbons.length === 0) delete item.ribbons;
      const clone = pick(cloneDeep(relations.operator[item.operator_id]), topListPickKeys);
      
       // refactor deposit method
       clone.bonus.deposit_methods = clone.bonus.deposit_methods?.map(({ id, name, standardised_logo_filename }) => (
        { id, name, standardised_logo_filename }
        ));


      const operatorPage =
        pages && pages.operator
          ? pages.operator.filter((page) => page.relation_id === item.operator_id)
          : [];
      if (operatorPage[0]?.extra_fields) {
        clone.reviewSummery = getExtraField(operatorPage[0]?.extra_fields, 'operator_review_summary', null);
      }

      if (operatorPage.length >= 1 && operatorPage[0].author) {
        clone.authorName = operatorPage[0].author.name && operatorPage[0].author.name;
        clone.authorPath =
          operatorPage[0].author.profile_page_path && operatorPage[0].author.profile_page_path;

        clone.authorImage = operatorPage[0].author.image && operatorPage[0].author.image;

        clone.authorImageObject =
          operatorPage[0].author.image_object && operatorPage[0].author.image_object;
      }

      // Multiple market fix
      if (
        item.review_link &&
        operatorPage.length >= 1 &&
        markets &&
        markets[operatorPage[0].market] &&
        markets[operatorPage[0].market].path_prefix
      ) {
        item.review_link = `${markets[operatorPage[0].market].path_prefix}/${item.review_link}`;
      }

      delete clone.software;
      return Object.assign(clone, item);
    });
    return listItem;
  });
}

export function shouldSavePrefilled(module = {}, siteName) {
  return (
    module.value_type === ModuleValue.VALUE_TYPE_PREFILLED_MODULE_MARKET &&
    ((settings.dynamic_prefilled_modules[siteName] &&
      !settings.dynamic_prefilled_modules[siteName].includes(module.name)) ||
      module.sort_by !== 'random')
  );
}

export function processModule(
  module,
  pages,
  pagesCloned,
  relations,
  pagesMappedById,
  menus,
  previewMode,
  pageId,
  translations,
  relationData,
  markets
) {
  module.module_title =
    module.module_title &&
    generatePlaceholderString(module.module_title, translations, relationData);
  module.title =
    module.title && generatePlaceholderString(module.title, translations, relationData);

  // See more link
  if (module.see_more_link?.value) {
    module.see_more_link.path =
      module.see_more_link?.type === 'page' ? pagesMappedById[module.see_more_link.value].path : module.see_more_link?.value
  }

  if (module.name === 'cards') {
    processCardsModule(module, pages, pagesCloned, pagesMappedById);
  } else if (module.name === 'cards_v2') {
    processCardsV2(module, pagesCloned, pagesMappedById, pageId);
  } else if (module.name === 'bonus') {
    processBonus(module, relations);
  } else if (module.name === 'archive' && previewMode) {
    processArchiveModule(module, pages);
  } else if (module.name === 'top_list') {
    processTopListModule(module, relations, pages, markets);
  } else if (module.name === 'menu' && menus && menus[module.menu_id]) {
    module = Object.assign(module, menus[module.menu_id]);
  }
}
