'use client';

import dynamic from 'next/dynamic';
import plugins from 'plugins';
import logger from '../utils/log';
import { useMemo } from 'react';
import settings from 'settings';

enum Plugin {
  BasketGiftPack = 'pz-basket-gift-pack',
  ClickCollect = 'pz-click-collect',
  OneClickCheckout = 'pz-one-click-checkout',
  PayOnDelivery = 'pz-pay-on-delivery',
  CheckoutGiftPack = 'pz-checkout-gift-pack',
  GPay = 'pz-gpay',
  Otp = 'pz-otp',
  BKMExpress = 'pz-bkm',
  CreditPayment = 'pz-credit-payment',
  Masterpass = 'pz-masterpass',
  B2B = 'pz-b2b',
  Akifast = 'pz-akifast',
  MultiBasket = 'pz-multi-basket',
  SavedCard = 'pz-saved-card',
  FlowPayment = 'pz-flow-payment',
  VirtualTryOn = 'pz-virtual-try-on',
  Hepsipay = 'pz-hepsipay',
  MasterpassRest = 'pz-masterpass-rest',
  SimilarProducts = 'pz-similar-products',
  Haso = 'pz-haso',
  GooglePay = 'pz-google-pay',
  ListHoverImage = 'pz-list-hover-image'
}

export enum Component {
  BasketGiftPack = 'BasketGiftPack',
  ClickCollect = 'ClickCollect',
  OneClickCheckoutButtons = 'OneClickCheckoutButtons',
  OneClickProviderButton = 'OneClickCheckoutButton',
  PayOnDelivery = 'PayOnDelivery',
  CheckoutGiftPack = 'CheckoutGiftPack',
  GPay = 'GPayOption',
  Otp = 'Otp',
  BKMExpress = 'BKMOption',
  CreditPayment = 'CreditPayment',
  MasterpassProvider = 'MasterpassProvider',
  MasterpassCardList = 'MasterpassCardList',
  MasterpassCardRegistration = 'MasterpassCardRegistration',
  MasterpassDeleteConfirmationModal = 'MasterpassDeleteConfirmationModal',
  MasterpassOtpModal = 'MasterpassOtpModal',
  MasterpassLinkModal = 'MasterpassLinkModal',
  MyQuotationsB2B = 'AccountMyQuotations',
  BasketB2B = 'BasketB2b',
  AkifastQuickLoginButton = 'QuickLoginButton',
  AkifastCheckoutButton = 'CheckoutButton',
  MultiBasket = 'MultiBasket',
  SavedCard = 'SavedCardOption',
  VirtualTryOnPlugin = 'VirtualTryOnPlugin',
  BasketVirtualTryOn = 'BasketVirtualTryOn',
  BarcodeScannerPlugin = 'BarcodeScannerPlugin',
  IyzicoSavedCard = 'IyzicoSavedCardOption',
  Hepsipay = 'Hepsipay',
  FlowPayment = 'FlowPayment',
  MasterpassRest = 'MasterpassRestOption',
  SimilarProductsModal = 'SimilarProductsModal',
  SimilarProductsFilterSidebar = 'SimilarProductsFilterSidebar',
  SimilarProductsResultsGrid = 'SimilarProductsResultsGrid',
  SimilarProductsPlugin = 'SimilarProductsPlugin',
  ProductImageSearchFeature = 'ProductImageSearchFeature',
  ImageSearchButton = 'ImageSearchButton',
  HeaderImageSearchFeature = 'HeaderImageSearchFeature',
  HasoPaymentGateway = 'HasoPaymentGateway',
  GooglePay = 'GooglePay',
  ListHoverImage = 'ListHoverImage'
}

const PluginComponents = new Map([
  [Plugin.BasketGiftPack, [Component.BasketGiftPack]],
  [Plugin.ClickCollect, [Component.ClickCollect]],
  [
    Plugin.OneClickCheckout,
    [Component.OneClickCheckoutButtons, Component.OneClickProviderButton]
  ],
  [Plugin.PayOnDelivery, [Component.PayOnDelivery]],
  [Plugin.CheckoutGiftPack, [Component.CheckoutGiftPack]],
  [Plugin.GPay, [Component.GPay]],
  [Plugin.Otp, [Component.Otp]],
  [Plugin.BKMExpress, [Component.BKMExpress]],
  [Plugin.CreditPayment, [Component.CreditPayment]],
  [
    Plugin.Masterpass,
    [
      Component.MasterpassCardList,
      Component.MasterpassProvider,
      Component.MasterpassCardRegistration,
      Component.MasterpassDeleteConfirmationModal,
      Component.MasterpassOtpModal,
      Component.MasterpassLinkModal
    ]
  ],
  [Plugin.B2B, [Component.MyQuotationsB2B, Component.BasketB2B]],
  [
    Plugin.Akifast,
    [Component.AkifastQuickLoginButton, Component.AkifastCheckoutButton]
  ],
  [Plugin.MultiBasket, [Component.MultiBasket]],
  [
    Plugin.SimilarProducts,
    [
      Component.SimilarProductsModal,
      Component.SimilarProductsFilterSidebar,
      Component.SimilarProductsResultsGrid,
      Component.SimilarProductsPlugin,
      Component.ProductImageSearchFeature,
      Component.ImageSearchButton,
      Component.HeaderImageSearchFeature
    ]
  ],
  [Plugin.SavedCard, [Component.SavedCard, Component.IyzicoSavedCard]],
  [Plugin.SavedCard, [Component.SavedCard]],
  [Plugin.FlowPayment, [Component.FlowPayment]],
  [
    Plugin.VirtualTryOn,
    [Component.VirtualTryOnPlugin, Component.BasketVirtualTryOn, Component.BarcodeScannerPlugin]
  ],
  [Plugin.Hepsipay, [Component.Hepsipay]],
  [Plugin.MasterpassRest, [Component.MasterpassRest]],
  [Plugin.Haso, [Component.HasoPaymentGateway]],
  [Plugin.GooglePay, [Component.GooglePay]],
  [Plugin.ListHoverImage, [Component.ListHoverImage]]
]);

const getPlugin = (component: Component) => {
  for (const [key, value] of Array.from(PluginComponents.entries())) {
    if (value.includes(component)) return key;
  }

  return '';
};

export default function PluginModule({
  component,
  props,
  children
}: {
  component: Component;
  props?: any;
  children?: React.ReactNode;
}) {
  const plugin = getPlugin(component);
  const pluginSettings = settings.plugins?.[plugin];

  if (pluginSettings) {
    props = {
      ...props,
      settings: pluginSettings
    };
  }

  const Component = useMemo(
    () =>
      dynamic(
        () => {
          let promise: any;

          try {
            if (plugin === Plugin.BasketGiftPack) {
              promise = import(`${'@akinon/pz-basket-gift-pack'}`);
            } else if (plugin === Plugin.ClickCollect) {
              promise = import(`${'@akinon/pz-click-collect'}`);
            } else if (plugin === Plugin.OneClickCheckout) {
              promise = import(`${'@akinon/pz-one-click-checkout'}`);
            } else if (plugin === Plugin.PayOnDelivery) {
              promise = import(`${'@akinon/pz-pay-on-delivery'}`);
            } else if (plugin === Plugin.CheckoutGiftPack) {
              promise = import(`${'@akinon/pz-checkout-gift-pack'}`);
            } else if (plugin === Plugin.GPay) {
              promise = import(`${'@akinon/pz-gpay'}`);
            } else if (plugin === Plugin.Otp) {
              promise = import(`${'@akinon/pz-otp'}`);
            } else if (plugin === Plugin.BKMExpress) {
              promise = import(`${'@akinon/pz-bkm'}`);
            } else if (plugin === Plugin.CreditPayment) {
              promise = import(`${'@akinon/pz-credit-payment'}`);
            } else if (plugin === Plugin.Masterpass) {
              promise = import(`${'@akinon/pz-masterpass'}`);
            } else if (plugin === Plugin.B2B) {
              promise = import(`${'@akinon/pz-b2b'}`);
            } else if (plugin === Plugin.Akifast) {
              promise = import(`${'@akinon/pz-akifast'}`);
            } else if (plugin === Plugin.MultiBasket) {
              promise = import(`${'@akinon/pz-multi-basket'}`);
            } else if (plugin === Plugin.SavedCard) {
              promise = import(`${'@akinon/pz-saved-card'}`);
            } else if (plugin === Plugin.Hepsipay) {
              promise = import(`${'@akinon/pz-hepsipay'}`);
            } else if (plugin === Plugin.FlowPayment) {
              promise = import(`${'@akinon/pz-flow-payment'}`);
            } else if (plugin === Plugin.VirtualTryOn) {
              promise = import(`${'@akinon/pz-virtual-try-on'}`);
            } else if (plugin === Plugin.MasterpassRest) {
              promise = import(`${'@akinon/pz-masterpass-rest'}`);
            } else if (plugin === Plugin.SimilarProducts) {
              promise = import(`${'@akinon/pz-similar-products'}`);
            } else if (plugin === Plugin.Haso) {
              promise = import(`${'@akinon/pz-haso'}`);
            } else if (plugin === Plugin.GooglePay) {
              promise = import(`${'@akinon/pz-google-pay'}`);
            } else if (plugin === Plugin.ListHoverImage) {
              promise = import(`${'@akinon/pz-list-hover-image'}`);
            }
          } catch (error) {
            logger.error(error);
          }

          return promise
            ? promise.then((mod) => mod[component]).catch(() => () => null)
            : new Promise<any>((resolve) => resolve(() => null));
        },
        { ssr: false }
      ),
    [plugin, component]
  );

  if (!(plugins as string[]).includes(plugin)) {
    return <>{children}</>;
  }

  if (children) {
    return <Component {...props}>{children}</Component>;
  }

  return <Component {...props} />;
}
