import { LISTENERS } from './../../scripts/html/bodyScript';
import type WebView from 'react-native-webview';
import type { RequestRenderingEvent } from '../../messages/webMessages/unitMessages';
import { webViewId } from '../../scripts/html/bodyHtml';
import {
  BottomSheetNativeACHCreditComponentType,
  BottomSheetNativeACHDebitComponentType,
  BottomSheetNativeAddToWalletComponentType,
  BottomSheetNativeBookPaymentComponentType,
  BottomSheetNativeCheckDepositComponentType,
  BottomSheetNativeComponentType,
  BottomSheetNativePlaceType,
  BottomSheetSlotData,
} from '../../types/internal/bottomSheet.types';
import { WebComponentType } from '../../types/internal/webComponent.types';

export const getBottomSheetScript = () => {
  return LISTENERS.requestRefresh;
};

export const renderingBottomSheetRequest = (currentWebView: WebView, renderingRequest: RequestRenderingEvent) => {
  currentWebView?.injectJavaScript(`
    document.activeElement && document.activeElement.blur();
    dispatchRenderingEvent('${JSON.stringify(renderingRequest.data)}');
  `);
};

export const resetHtml = (currentWebView: WebView) => {
  currentWebView?.injectJavaScript(`
    document.activeElement && document.activeElement.blur();
    document.getElementById('${webViewId}').style.height = null;
  `);
};

export const injectHtmlFullScreenHeight = (currentWebView: WebView | null, bottomSheetHeight: number) => {
  currentWebView && currentWebView?.injectJavaScript(`
    document.getElementById('${webViewId}').style.height = '${bottomSheetHeight}px';
  `);
};

const getParamsFromRequestRenderingEvent = (event: RequestRenderingEvent): string | null => {
  const eventString = event.data.nativeComponent;
  const componentName = event.data.nativeComponentName;
  const regexStringParams = `(<${componentName})(.*?)(><\\/${componentName}>)`;
  const regexParams = new RegExp(regexStringParams);
  const matchParams = eventString?.match(regexParams);
  if (matchParams && matchParams[2]) {
    return matchParams[2];
  }
  return null;
};

const extractValueFromRequestRenderingEvent = (event: RequestRenderingEvent, key: string): string | undefined => {
  const paramsString = getParamsFromRequestRenderingEvent(event);

  const regexString = `${key}=([^\\ \\s]+)`;
  const regex = new RegExp(regexString);
  const match = paramsString?.match(regex);
  if (match && match[1]) {
    return match[1];
  } else {
    return undefined;
  }
};

const getAddToWalletComponentDataFromEvent = (event: BottomSheetSlotData, customerToken: string): BottomSheetNativeAddToWalletComponentType | null => {
  const cardId = event.componentResourceId ?? extractValueFromRequestRenderingEvent(event.requestRenderingEvent, 'card-id');
  if (!cardId) {
    console.error('componentResourceId is missing in getAddToWalletComponentDataFromEvent and no cardId in requestRenderingEvent');
    return null;
  }
  return {
    type: BottomSheetNativeComponentType.AddToWalletComponent,
    props: {
      cardId: cardId,
      customerToken: customerToken,
    },
  };
};

const getACHCreditComponentDataFromEvent = (event: BottomSheetSlotData, customerToken: string): BottomSheetNativeACHCreditComponentType | null => {
  const accountId = extractValueFromRequestRenderingEvent(event.requestRenderingEvent, 'account-id');
  if (!accountId) {
    console.error('accountId is missing in getACHCreditComponentDataFromEvent');
    return null;
  }
  return {
    type: BottomSheetNativeComponentType.ACHCreditComponent,
    props: {
      accountId: accountId,
      customerToken: customerToken,
    },
  };
};

const getACHDebitComponentDataFromEvent = (event: BottomSheetSlotData, customerToken: string): BottomSheetNativeACHDebitComponentType | null => {
  const accountId = extractValueFromRequestRenderingEvent(event.requestRenderingEvent, 'account-id');
  if (!accountId) {
    console.error('accountId is missing in getACHDebitComponentDataFromEvent');
    return null;
  }
  return {
    type: BottomSheetNativeComponentType.ACHDebitComponent,
    props: {
      accountId: accountId,
      customerToken: customerToken,
    },
  };
};

const getCheckDepositComponentDataFromEvent = (event: BottomSheetSlotData, customerToken: string): BottomSheetNativeCheckDepositComponentType | null => {
  const accountId = extractValueFromRequestRenderingEvent(event.requestRenderingEvent, 'account-id');
  const fee = extractValueFromRequestRenderingEvent(event.requestRenderingEvent, 'fee');
  if (!accountId || !fee) {
    console.error('accountId or fee is missing in getCheckDepositComponentDataFromEvent');
    return null;
  }
  return {
    type: BottomSheetNativeComponentType.CheckDepositComponent,
    props: {
      accountId: accountId,
      fee: parseInt(fee),
      customerToken: customerToken,
    },
  };
};

const getBookPaymentComponentDataFromEvent = (event: BottomSheetSlotData, customerToken: string): BottomSheetNativeBookPaymentComponentType | null => {
  const accountId = extractValueFromRequestRenderingEvent(event.requestRenderingEvent, 'account-id');
  const counterPartyAccountId = extractValueFromRequestRenderingEvent(event.requestRenderingEvent, 'counterparty-account-id');
  const counterPartyName = extractValueFromRequestRenderingEvent(event.requestRenderingEvent, 'counterparty-name');
  if (!accountId) {
    console.error('accountId is missing in getBookPaymentComponentDataFromEvent');
    return null;
  }
  return {
    type: BottomSheetNativeComponentType.BookPaymentComponent,
    props: {
      accountId: accountId,
      counterPartyAccountId: counterPartyAccountId,
      counterPartyName: counterPartyName,
      customerToken: customerToken,
    },
  };
};

export const getNativeComponentDataFromEvent = (event: BottomSheetSlotData) => {
  let componentData = null;
  let nativePlace = BottomSheetNativePlaceType.modal;
  const requestRenderingEventData = event.requestRenderingEvent.data;

  const customerToken = extractValueFromRequestRenderingEvent(event.requestRenderingEvent, 'customer-token');
  if (!customerToken) {
    console.error('customerToken is missing in getNativeComponentDataFromEvent');
    return null;
  }

  switch (requestRenderingEventData.nativeComponentName) {
    case WebComponentType.cardAction:
      if (requestRenderingEventData.nativeComponent?.includes('action=AddToWallet')) {
        nativePlace = BottomSheetNativePlaceType.overFullScreen;
        componentData = getAddToWalletComponentDataFromEvent(event, customerToken);
      }
      break;
    case WebComponentType.achCreditPayment:
      componentData = getACHCreditComponentDataFromEvent(event, customerToken);
      break;

    case WebComponentType.achDebitPayment:
      componentData = getACHDebitComponentDataFromEvent(event, customerToken);
      break;

    case WebComponentType.checkDeposit:
      componentData = getCheckDepositComponentDataFromEvent(event, customerToken);
      break;

    case WebComponentType.bookPayment:
      componentData = getBookPaymentComponentDataFromEvent(event, customerToken);
      break;

    default:
      break;
  }

  if (!componentData) {
    return null;
  }
  return {
    component: componentData,
    nativePlace: nativePlace,
  };
};
