/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable react/prop-types */
/* eslint-disable no-else-return */
import React, { useContext, lazy, Suspense } from 'react';
import PropTypes from 'prop-types';
import { anchorLink } from 'gatsby-core-theme/src/helpers/strings';
import { Context } from 'gatsby-core-theme/src/context/MainProvider';
import {
  prettyTracker,
  getSectionExtraField,
  translate,
} from 'gatsby-core-theme/src/helpers/getters';
import Content from 'gatsby-core-theme/src/components/molecules/content';
import Toplist from 'gatsby-core-theme/src/components/organisms/toplist';
import Anchor from 'gatsby-core-theme/src/components/organisms/anchor/template-one';
import Cards from '../../../../components/organisms/cards';
import ModuleTitle from '../../atoms/module-title';
import InfoGrid from '../../../../components/atoms/info-grid/template-one';
import CountrySelector from '../../../../components/atoms/country-selector';
import { getApiQueryParams } from '../../../helpers/sportstake';
import { removeSymbols } from '../../../../helpers/strings';
import { generateCustomHeadings } from '../../../helpers/lotto';

import styles from './module.module.scss';

const Modules = ({ module, pageContext, index, exclOperator, serverData }) => {
  const { translations } = useContext(Context) || {};

  const { page } = pageContext;
  const { siteSchema } = page || {};

  const socialIcons =
    siteSchema &&
    (({ instagram, facebook, twitter, linkedin, youtube }) => ({
      instagram,
      facebook,
      twitter,
      linkedin,
      youtube,
    }))(siteSchema);

  const GetModuleComponent = (moduleItem) => {
    const { items, name } = moduleItem || {};

    switch (name) {
      // Modules
      case 'content':
        return Content;
      case 'top_list':
        return Toplist;
      case 'archive':
        if (!items || items.length === 0) return null;
        return lazy(() => import('gatsby-core-theme/src/components/organisms/archive'));
      case 'counter':
        return lazy(() => import('gatsby-core-theme/src/components/molecules/counter'));
      case 'contact_form':
        return lazy(() => import('gatsby-core-theme/src/components/atoms/contact-form'));
      case 'cards':
      case 'cards_v2':
        return Cards;
      case 'pros_and_cons':
        return lazy(() => import('gatsby-core-theme/src/components/molecules/pros-cons'));
      case 'accordion':
        return lazy(() => import('gatsby-core-theme/src/components/organisms/accordion'));
      case 'anchor':
        if (items && items.length > 0) {
          return Anchor;
        }
        return null;
      case 'carousel':
        if (
          items.length > 0 && // has items
          items.filter((item) => item.image === null).length === 0 // not filled with null items
        ) {
          return lazy(() => import('gatsby-core-theme/src/components/organisms/carousel'));
        }
        return null;
      case 'bonus':
        return lazy(() => import('gatsby-core-theme/src/components/molecules/bonus/template-one'));
      case 'image':
        return lazy(() => import('gatsby-core-theme/src/components/atoms/image'));
      case 'spotlights':
        if (module?.mode === 'image_text') {
          if (module?.style === 'template_two') {
            return lazy(() => import('~molecules/spotlights_v2/image-text/template-two'));
          } else if (module?.style === 'template_three') {
            return lazy(() => import('~molecules/spotlights_v2/image-text/template-three'));
          }
          if (module?.style === 'template_four') {
            return lazy(() => import('~molecules/spotlights_v2/image-text/template-four'));
          }
          return lazy(() => import('~molecules/spotlights_v2/image-text/template-one'));
        } else if (module?.mode === 'icon') {
          return lazy(() => import('~molecules/spotlights_v2/icon/template-one'));
        } else if (module?.mode === 'image') {
          if (module?.style === 'template_two') {
            return lazy(() => import('~molecules/spotlights_v2/image/template-two'));
          }
          return lazy(() => import('~molecules/spotlights_v2/image/template-one'));
        }
        return null;
      case 'faq':
        // eslint-disable-next-line react/destructuring-assignment
        if (moduleItem?.display_front_end === '1') {
          return lazy(() => import('../../../../components/molecules/faq'));
        }
        return null;
      // Template blocks
      case 'country_selector': {
        return CountrySelector;
      }
      case 'horse_racing_calculator':
        return lazy(() => import('../../../../components/molecules/horse-calculator'));
      case 'review_summary':
        return lazy(() => import('../../../../components/molecules/operator-summary'));
      case 'review_disclaimer':
        return lazy(() => import('../../../../components/atoms/disclaimer/review-disclaimer'));
      case 'game_iframe':
      case 'iframe':
        if (moduleItem?.value_type === 'template_block') {
          return lazy(() => import('../../../../components/molecules/game-iframe'));
        }
        return lazy(() => import('gatsby-core-theme/src/components/atoms/iframe'));
      case 'info_grid':
      case 'information_grid':
      case 'operator_information_block':
        if (getSectionExtraField(null, page, 'operator_is_placeholder') === '1') {
          return null;
        }
        return InfoGrid;
      case 'content_box':
        return lazy(() => import('gatsby-core-theme/src/components/atoms/content-box'));
      case 'timeline':
        return lazy(() =>
          import('gatsby-core-theme/src/components/molecules/content-and-custom-module')
        );
      case 'welcome_bonus':
        return lazy(() => import('../../../../components/molecules/operator-welcome-bonus'));
      case 'widget':
        return lazy(() => import('../../../../components/molecules/widget'));
      case 'score_gauges':
        return lazy(() => import('../../../../components/molecules/game-score-gauge'));
      case 'site_contacts':
        if (page?.siteSchema?.email === null) {
          return null;
        }
        return lazy(() => import('../../../../components/atoms/site-contacts'));
      case 'newsletter_optin':
        return lazy(() => import('../../../../components/molecules/newsletter-optin'));
      case 'wagering_calculator':
        return lazy(() => import('../../../../components/molecules/wagering-calculator'));
      case 'social_icons':
        return lazy(() => import('../../../../components/atoms/social-icons'));
      case 'sportstake4fixturesmidweek':
      case 'sportstake8fixturesmidweek':
      case 'sportstake8fixturesweekend':
      case 'sportstake13fixturesmidweek':
      case 'sportstake13fixturesweekend':
      case 'sportstakecricketfixturesweekend':
      case 'sportstakerugbyfixturesweekend':
        if (!serverData?.fixtures?.data?.find((x) => x?.name === module?.name)) return;
        return lazy(() => import('../../../../components/molecules/sportstake/fixtures'));
      case 'sportstake4resultsmidweek':
      case 'sportstake8resultsmidweek':
      case 'sportstake8resultsweekend':
      case 'sportstake13resultsmidweek':
      case 'sportstake13resultsweekend':
      case 'sportstakecricketresultsweekend':
      case 'sportstakerugbyresultsweekend':
        if (!serverData?.results?.data?.find((x) => x?.name === module?.name)) return;
        return lazy(() => import('../../../../components/molecules/sportstake/results'));
      case 'lotto':
      case 'daily_lotto':
      case 'powerball':
        if (!serverData?.lotto?.data?.find((x) => x?.name === module?.name)) return;
        return lazy(() => import('../../../../components/molecules/sportstake/lotto-module'));
      case 'newsletter':
        return lazy(() => import('gatsby-core-theme/src/components/molecules/newsletter'));
      default:
        return null;
    }
  };

  const ModuleComponent = GetModuleComponent(module);

  const homepageFirstModule = index === 0 && page.path === '/';

  // eslint-disable-next-line no-nested-ternary
  const anchorLabel = module.anchor_label
    ? removeSymbols(anchorLink(module.anchor_label))
    : module.name === 'archive'
    ? 'archiveLabel'
    : null;

  const extraProps = () => {
    switch (module.name) {
      case 'bonus':
        return {
          operator: module?.value,
          logo: module?.value?.logo_url,
          hasLink: true,
          prettyLink: prettyTracker(module?.value, 'main', false, page?.template),
          isStickyCta: false,
        };
      case 'newsletter':
        return {
          isSticky: false,
        };
      case 'iframe':
        return {
          src: module?.iframe_source,
        };
      case 'social_icons':
        return Object.values(socialIcons).some((value) => value) ? { socialIcons } : {};
      case 'sportstake4fixturesmidweek':
      case 'sportstake8fixturesmidweek':
      case 'sportstake8fixturesweekend':
      case 'sportstake13fixturesmidweek':
      case 'sportstake13fixturesweekend':
      case 'sportstakecricketfixturesweekend':
      case 'sportstakerugbyfixturesweekend': {
        const moduleName = module?.name;
        const query = getApiQueryParams(moduleName);
        module.module_title = translate(translations, `${moduleName}_title`, query.title);
        module.module_introduction = translate(translations, `${moduleName}_desc`, null);

        return {
          serverData: serverData?.fixtures?.data?.find((x) => x?.name === moduleName)?.result,
        };
      }
      case 'sportstake4resultsmidweek':
      case 'sportstake8resultsmidweek':
      case 'sportstake8resultsweekend':
      case 'sportstake13resultsmidweek':
      case 'sportstake13resultsweekend':
      case 'sportstakecricketresultsweekend':
      case 'sportstakerugbyresultsweekend': {
        const moduleName = module?.name;
        const query = getApiQueryParams(moduleName);
        module.module_title = translate(translations, `${moduleName}_title`, query.title);
        module.module_introduction = translate(translations, `${moduleName}_desc`, null);

        return {
          serverData: serverData?.results?.data?.find((x) => x?.name === moduleName)?.result,
        };
      }
      case 'lotto':
      case 'daily_lotto':
      case 'powerball': {
        const moduleName = module?.name;
        module.module_title = translate(
          translations,
          `${moduleName}_title`,
          generateCustomHeadings(moduleName)
        );
        module.module_introduction = translate(translations, `${moduleName}_desc`, null);

        return { serverData: serverData?.lotto?.data?.find((x) => x?.name === moduleName)?.result };
      }
      case 'info_grid':
      case 'information_grid':
      case 'operator_information_block': {
        return page.type.includes('author') ? { templateThree: true } : { templateThree: false };
      }
      default:
        return {
          anchorLabel,
        };
    }
  };

  const moduleClassName = `${module.name}Module`;

  const moduleBackgroundColor = {
    '--module-background-color': module.background_color,
  };

  const showModuleIntro =
    module.name !== 'top_list' &&
    module.module_introduction &&
    module.module_introduction !== '<p></p>';

  const useSuspense = [
    'cards_v2',
    'content',
    'top_list',
    'anchor',
    'info_grid',
    'information_grid',
    'operator_information_block',
    'country_selector',
  ];

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

  return (
    ModuleComponent && (
      <div
        id={
          module.name === 'archive' && (module.module_title || module.module_title)
            ? null
            : anchorLabel
        }
        style={module.background_color && moduleBackgroundColor}
        className={`${styles[moduleClassName] !== undefined ? styles[moduleClassName] || '' : ''} ${
          module?.name || ''
        } ${showModuleIntro ? '' : styles.noModuleIntro} ${styles?.module || ''} ${
          module?.style ? styles[module.style] || '' : ''
        } module ${homepageFirstModule ? styles?.isHomepageFirstModule || '' : ''}`}
      >
        {module.name !== 'cards_v2' && (
          <>
            {module.name !== 'top_list' && (
              <ModuleTitle
                module={module}
                isHomepageFirstModule={homepageFirstModule}
                anchorLabel={module.name === 'archive' && anchorLabel}
              />
            )}
            {showModuleIntro && (
              <Content
                isModuleIntroduction={module.module_introduction}
                module={{ value: module.module_introduction }}
                isHomepageFirstModule={homepageFirstModule}
              />
            )}
          </>
        )}
        {useSuspense.includes(module.name) ? (
          <ModuleComponent
            module={module}
            page={page}
            pageContext={pageContext}
            noModuleIntro={!showModuleIntro}
            {...extraProps()}
            exclOperator={exclOperator}
            isHomepageFirstModule={homepageFirstModule}
          />
        ) : (
          <Suspense
            fallback={
              <div
                className={`${
                  isSportsStake.includes(module.name) ? styles.sportstake : styles[module.name]
                }`}
              />
            }
          >
            <ModuleComponent
              module={module}
              page={page}
              pageContext={pageContext}
              noModuleIntro={!showModuleIntro}
              {...extraProps()}
              exclOperator={exclOperator}
              isHomepageFirstModule={homepageFirstModule}
            />
          </Suspense>
        )}
      </div>
    )
  );
};

Modules.propTypes = {
  exclOperator: PropTypes.bool,
  module: PropTypes.shape({
    anchor_label: PropTypes.string,
    name: PropTypes.string,
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    module_title_tag: PropTypes.string,
    module_title: PropTypes.string,
    link_label: PropTypes.string,
    link_value: PropTypes.string,
    style: PropTypes.string,
  }),
  page: PropTypes.shape({ id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) }),
  pageContext: PropTypes.shape({}),
};

export default Modules;
