/* eslint-disable no-prototype-builtins */
/* eslint-disable no-nested-ternary */
/* eslint-disable no-underscore-dangle */
/* eslint-disable import/prefer-default-export */
// eslint-disable-next-line import/no-extraneous-dependencies
import chalk from 'chalk';
import processor from 'gatsby-core-theme/src/resolver/index';
import { fetchSiteSettings } from 'gatsby-core-theme/src/services/fetch.mjs';
import { getApiQueryParams } from './sportstake';
import { getApiBasedNames } from './lotto';
import {
  getResultsById,
  getLatestResults,
  getAvailableDrawDays,
  getLottoUKdata,
  getCalendarData,
} from './services';
import loadSource from '~helpers/search-source';
import { deparam } from '~helpers/strings';
import { groupBy } from '~helpers/getters';

export async function getAPIData(page, url, header, preview) {
  if (preview) {
    const start = new Date();
    const siteName = process.env.GATSBY_SITE_NAME;
    const params = deparam(url.split('?')[1]);

    const {
      siteSettingsData,
      siteGeneralData,
      ribbonsData,
      responsableGamingData,
      toplistData,
      contentData,
      pagesData,
      operatorData,
      paymentData,
      gamesData,
      providersData,
    } = await fetchSiteSettings(siteName, params?.path);

    const processed = processor.run(
      {
        ...siteSettingsData,
        pages: pagesData,
        general: siteGeneralData,
        prefilled_market_modules: siteSettingsData.prefilled_modules,
        responsible_gamings: responsableGamingData,
        toplists: toplistData,
        content: contentData,
        ribbons: ribbonsData,
        relations: {
          operator: operatorData,
          payment_method: paymentData,
          software_provider: providersData,
          game: gamesData,
        },
      },
      {},
      null,
      null,
      parseInt(params?.page_id)
    );

    const pagePreviewProcessed = Object.values(pagesData).filter(
      (value) => parseInt(value.id) === parseInt(params?.page_id)
    );

    if (pagePreviewProcessed.length > 0) {
      const previewPageData = pagePreviewProcessed[0];
      const end = new Date() - start;

      console.log(chalk.green('success') + chalk.whiteBright(` Preview Feature - %ds`), end / 1000);
      return {
        props: {
          marketSections: processed.market_sections[previewPageData.market],
          prefilledModules: processed.prefilled_market_modules[previewPageData.market],
          page: previewPageData,
          allMarkets: processed.site_markets,
          siteInfo: processed.general,
        },
      };
    }

    console.log(chalk.red('error') + chalk.whiteBright(` Preview Page Not Found ${params?.path}`));

    return { props: {} };
  }

  function normalizeString(str) {
    return str
      .normalize('NFD')
      .replace(/[\u0300-\u036f]/g, '')
      .toLowerCase();
  }

  if (page.path.endsWith('/s') || page.path === 's' || page.template === 'search') {
    const results = await loadSource(page.market);
    if (page.path.endsWith('/s') || page.path === 's') {
      let urlParams = null;
      if (url && url.split('?').length === 2) {
        urlParams = deparam(`${url.split('?')[1]}`);
      }

      const searchData = urlParams
        ? urlParams.hasOwnProperty('s')
          ? groupBy(
              results.filter((item) =>
                normalizeString(item.title).includes(normalizeString(urlParams.s))
              ),
              'pageType'
            )
          : null
        : null;

      return {
        props: {
          data: searchData,
          searchParam: urlParams ? urlParams.s : null,
        },
      };
    }
  }

  const sportstakeTemplateBlocks = [
    'sportstake4resultsmidweek',
    'sportstake8resultsmidweek',
    'sportstake8resultsweekend',
    'sportstake13resultsmidweek',
    'sportstake13resultsweekend',
    'sportstakecricketresultsweekend',
    'sportstakerugbyresultsweekend',
    'sportstake4fixturesmidweek',
    'sportstake8fixturesmidweek',
    'sportstake8fixturesweekend',
    'sportstake13fixturesmidweek',
    'sportstake13fixturesweekend',
    'sportstakecricketfixturesweekend',
    'sportstakerugbyfixturesweekend',
    'lotto',
    'daily_lotto',
    'powerball',
  ];

  const containsFixtures =
    (page?.categories &&
      page?.categories.filter((category) => category.short_name === 'fixtures')) ||
    [];
  const containsResults =
    (page?.categories &&
      page?.categories.filter((category) => category.short_name === 'results')) ||
    [];
  const containsLotto =
    (page?.categories && page?.categories.filter((category) => category.short_name === 'lotto')) ||
    [];
  const conatinsLottoUK49 =
    (page?.categories &&
      page?.categories.filter((category) => category.short_name === 'lotto_uk_49')) ||
    [];
  let responseFixtures = {};
  let responseResults = {};
  let responseLotto = {};
  let lottoUK49 = [];

  if (containsFixtures.length >= 1) {
    const filteredArray = page?.sections?.main?.modules.filter(
      (x) => x.value_type === 'template_block' && sportstakeTemplateBlocks.includes(x.name)
    );

    const date = new Date();
    const fixtureData = await Promise.all(
      filteredArray.map(async (module) => {
        const moduleName = module.name;
        // return if fixtures to avoid duplicates
        if (moduleName.includes('results')) return;
        const query = getApiQueryParams(moduleName);
        const month = date.getMonth() + 1;
        const previousMonth = month === 1 ? 12 : month - 1;

        const calendarData = await getCalendarData(query.lotteryName, month, date.getFullYear());
        const prevMonthData =
          calendarData.length <= 2
            ? await getCalendarData(query.lotteryName, previousMonth, date.getFullYear())
            : [];

        const orderedPrevMonth =
          calendarData.length === 0
            ? [prevMonthData[prevMonthData.length - 1], ...prevMonthData.slice(0, prevMonthData.length - 1)]
            : prevMonthData;

        const reorderedResultData = [
          calendarData[calendarData.length - 1],
          ...calendarData.slice(0, calendarData.length - 1),
          ...orderedPrevMonth,
        ].filter((item) => item && !Array.isArray(item) && item._id);

        reorderedResultData.sort((a, b) => {
          const dateA = new Date(a.drawDate);
          const dateB = new Date(b.drawDate);
          return dateB.getTime() - dateA.getTime();
        });

        if (reorderedResultData[0]?._id) {
          const latestResult = await getResultsById(reorderedResultData[0]._id);
          if (latestResult) reorderedResultData[0] = latestResult;
        }

        return { [moduleName]: reorderedResultData };
      })
    );

    responseFixtures = {
      data: Object.assign({}, ...fixtureData.filter(Boolean)),
    };
  } else {
    responseFixtures = { data: [] };
  }

  if (containsResults.length >= 1) {
    const filteredArray = page?.sections?.main?.modules.filter(
      (x) => x.value_type === 'template_block' && sportstakeTemplateBlocks.includes(x.name)
    );

    const date = new Date();
    const resultData = await Promise.all(
      filteredArray.map(async (module) => {
        const moduleName = module.name;
        // return if fixtures to avoid duplicates
        if (moduleName.includes('fixtures')) return;
        const query = getApiQueryParams(moduleName);
        const month = date.getMonth() + 1;
        const previousMonth = month === 1 ? 12 : month - 1;

        const calendarData = await getCalendarData(query.lotteryName, month, date.getFullYear());

        const prevMonthData =
          calendarData.length <= 2
            ? await getCalendarData(query.lotteryName, previousMonth, date.getFullYear())
            : [];

        const orderedPrevMonth =
          calendarData.length === 0
            ? [prevMonthData[prevMonthData.length - 1], ...prevMonthData.slice(0, prevMonthData.length - 1)]
            : prevMonthData;

        const reorderedResultData = [
          calendarData[calendarData.length - 1],
          ...calendarData.slice(0, calendarData.length - 1),
          ...orderedPrevMonth,
        ].filter((item) => item && !Array.isArray(item) && item._id);

        reorderedResultData.sort((a, b) => {
          const dateA = new Date(a.drawDate);
          const dateB = new Date(b.drawDate);
          return dateB.getTime() - dateA.getTime();
        });

        if (reorderedResultData[0]?._id) {
          const latestResult = await getResultsById(reorderedResultData[0]._id);
          if (latestResult) reorderedResultData[0] = latestResult;
        }

        return { [moduleName]: reorderedResultData };
      })
    );

    responseResults = {
      data: Object.assign({}, ...resultData.filter(Boolean)),
    };
  } else {
    responseResults = { data: [] };
  }

  if (containsLotto.length >= 1) {
    const filteredArray = page?.sections?.main?.modules.filter(
      (x) => x.value_type === 'template_block' && sportstakeTemplateBlocks.includes(x.name)
    );

    const responseArray = await Promise.all(
      filteredArray.map(async (module) => {
        const moduleName = module.name;
        const apiBaseNames = getApiBasedNames(moduleName);

        if (apiBaseNames.length === 0) return;

        const date = new Date();
        const month = date.getMonth() + 1;
        const previousMonth = month === 1 ? 12 : month - 1;
        const year = date.getFullYear();

        const availableDates = await getAvailableDrawDays(apiBaseNames[0], 'WEEKEND', month, year);

        const prevMonthData =
          availableDates.length <= 2
            ? await getAvailableDrawDays(apiBaseNames[0], 'WEEKEND', previousMonth, year)
            : [];

        const orderedPrevMonth =
          availableDates.length === 0
            ? [prevMonthData[prevMonthData.length - 1], ...prevMonthData.slice(0, prevMonthData.length - 1)]
            : prevMonthData;

        const reorderedDates = [
          availableDates[availableDates.length - 1],
          ...availableDates.slice(0, availableDates.length - 1),
          ...orderedPrevMonth,
        ].filter((item) => item && !Array.isArray(item));

        reorderedDates.sort((a, b) => {
          const dateA = new Date(a.drawDate);
          const dateB = new Date(b.drawDate);
          return dateB.getTime() - dateA.getTime();
        });

        const latestDrawResults = await Promise.all(
          apiBaseNames.map((name) => getLatestResults(name))
        );

        return { name: moduleName, result: { latestDrawResults, reorderedDates } };
      })
    );

    responseLotto = {
      data: responseArray.filter((n) => n),
    };
  } else {
    responseLotto = { data: [] };
  }

  if (conatinsLottoUK49.length >= 1) {
    const types = ['lunchtime', 'teatime'];
    const date = new Date();
    const month = date.getMonth() + 1;
    const previousMonth = month === 1 ? 12 : month - 1;
    const year = date.getFullYear();

    const responseArray = await Promise.all(
      types.map(async (type) => {
        const data = await getLottoUKdata(true, false, type);
        const calendarData = await getCalendarData(type, month, year);
        const prevMonthData =
          calendarData.length <= 2 ? await getCalendarData(type, previousMonth, year) : [];

        const reorderedDates = [...calendarData, ...prevMonthData].filter(
          (item) => item && !Array.isArray(item)
        );

        return {
          data,
          tabs: reorderedDates,
        };
      })
    );
    lottoUK49 = {
      tabs: [...responseArray[0].tabs, ...responseArray[1].tabs],
      data: [...responseArray[0].data, ...responseArray[1].data],
    };
  } else {
    lottoUK49 = { data: [], tabs: [] };
  }

  return {
    props: {
      fixtures: responseFixtures,
      results: responseResults,
      lotto: responseLotto,
      lottouk49: lottoUK49,
    },
  };
}
