import { RequestRefreshEvent } from '../../messages/webMessages/unitMessages';
import type WebView from 'react-native-webview';
import type { UNAccountMenuAction } from '../../types/shared';
import { WebComponentType } from '../../types/internal/webComponent.types';
import { UNPayeeManagementComponentProps } from './UNPayeeManagementComponent';
import { DISPATCH_OPEN_PLAID, DISPATCH_PLAID_EXIT, DISPATCH_PLAID_RESPONSE, DISPATCH_REQUEST_REFRESH, LISTENERS } from '../../scripts/html/bodyScript';
import { LinkError, LinkSuccess } from 'react-native-plaid-link-sdk';
import { OpenPlaidEvent } from '../../messages/webMessages/plaidMessages';

export const getPayeeParams = (props: UNPayeeManagementComponentProps) => {
  const menuItemsParam = props.menuItems ? `menu-items="${props.menuItems.join()}"` : '';
  const queryFilterParam = props.queryFilter ? `query-filter="${props.queryFilter}"` : '';
  const paginationTypeParam = props.paginationType ? `pagination-type="${props.paginationType}"` : '';

  const plaidAccountFiltersParam = props.plaidAccountFilters ? `plaid-account-filters="${props.plaidAccountFilters.join()}"` : '';
  const plaidLinkCustomizationNameParam = props.plaidLinkCustomizationName ? `plaid-link-customization-name="${props.plaidLinkCustomizationName}"` : '';

  const counterPartiesPerPageParam = props.counterPartiesPerPage ? `counterparties-per-page="${props.counterPartiesPerPage}"` : '';

  const menuPlaceholderParam = props.menuPlaceholder ? `menu-placeholder="${props.menuPlaceholder}"` : '';
  const flowPlaceholderParam = props.flowPlaceholder ? `flow-placeholder="${props.flowPlaceholder}"` : '';
  const payeeCreationPlaceholderParam = props.payeeCreationPlaceholder ? `payee-creation-placeholder="${props.payeeCreationPlaceholder}"` : '';
  const microDepositConnectionPlaceholderParam = props.microDepositConnectionPlaceholder ? `micro-deposit-connection-placeholder="${props.microDepositConnectionPlaceholder}"` : '';
  return `
    customer-token="${props.customerToken}"
    ${menuItemsParam}
    ${queryFilterParam}
    ${paginationTypeParam}
    ${counterPartiesPerPageParam}
    hide-title="${props.hideTitle || false}"
    hide-counterparty-actions-button="${props.hideCounterpartyActionsButton || false}"
    ${menuPlaceholderParam}
    ${flowPlaceholderParam}
    ${payeeCreationPlaceholderParam}
    ${microDepositConnectionPlaceholderParam}
    ${plaidAccountFiltersParam}
    ${plaidLinkCustomizationNameParam}
    style="height: 100%"
  `;
};

export const getPayeeManagementScript = () => {
  return `
    ${LISTENERS.unitCounterpartyCreated}
    ${LISTENERS.unitConnectedAccountCreated}
    ${LISTENERS.unitMicroDepositConnectionCreated}
    ${LISTENERS.unitMicroDepositConnectionRejected}
    ${LISTENERS.requestRefresh}
    ${DISPATCH_PLAID_RESPONSE}
    ${DISPATCH_PLAID_EXIT}
    ${DISPATCH_OPEN_PLAID}
    ${DISPATCH_REQUEST_REFRESH}
  `;
};

export const injectOpenActionsMenuScript = (currentWeb: WebView | null) => {
  currentWeb?.injectJavaScript(`dispatchOpenActionsMenu('${WebComponentType.account}')`);
};

export const injectRequestAccountActionScript = (currentWeb: WebView | null, action: UNAccountMenuAction) => {
  currentWeb?.injectJavaScript(`dispatchRequestAccountAction('${action}')`);
};

export const injectRefreshEventIfNeeded = (currentWeb: WebView | null, requestRefreshEvent: RequestRefreshEvent | null) => {
  if (requestRefreshEvent && requestRefreshEvent.dependencies.includes(WebComponentType.payeeManagement.valueOf())) {
    currentWeb?.injectJavaScript(`dispatchRefreshEvent('${JSON.stringify(requestRefreshEvent)}')`);
  }
};

export const injectUnitOpenPlaid = (currentWeb: WebView | null, openPlaidData: OpenPlaidEvent) => {
  currentWeb?.injectJavaScript(`dispatchOpenPlaidEvent(${JSON.stringify({ data: openPlaidData })})`);
};

export const injectUnitPlaidResponse = (currentWeb: WebView | null, success: LinkSuccess) => {
  const successObj = { data: { publicToken: success.publicToken, metadata: JSON.parse(success.metadata.metadataJson ?? '{}') } };
  currentWeb?.injectJavaScript(`dispatchPlaidEvent(${JSON.stringify(successObj)})`);
};

export const injectUnitPlaidExit = (currentWeb: WebView | null, plaidLinkError: LinkError | null | undefined) => {
  // Android & iOS are not consist - we will extract the needed fields from the LinkError/errorJson
  const errorJson = JSON.parse(plaidLinkError?.errorJson ?? '{}');
  const type = plaidLinkError?.errorType ?? errorJson['error_type'] ?? '';
  const code = plaidLinkError?.errorCode ?? errorJson['error_code'] ?? '';
  const message = plaidLinkError?.errorMessage ?? errorJson['error_message'] ?? '';
  const error = { error_type: type, error_code: code, error_message: message };
  currentWeb?.injectJavaScript(`dispatchPlaidExit(${JSON.stringify(error)})`);
};
