import React, { useState } from 'react';
import { UNBaseView } from '../../nativeComponents/UNBaseView';
import { WebComponent } from '../../webComponent/WebComponent';
import { PresentationMode, WebComponentType } from '../../types/internal/webComponent.types';
import { withReduxStore } from '../../helpers/store/helpers';
import { getMultiFactorAuthenticationParams, getMultiFactorAuthenticationScript } from './UNMultiFactorAuthenticationComponent.utils';
import type { WebViewMessage } from '../../messages/webMessages';
import { HeightEvent, PageMessage } from '../../messages/webMessages/pageMessage';
import { MultiFactorAuthenticationFinishedEvent, UnitComponentsMessage } from '../../messages/webMessages/unitComponentsMessages';
import { UNComponentsError, UNComponentsOnLoadResponse, UNCustomerTokenVerification, UNMultiFactorAuthenticationFinished } from '../../types/shared';
import { RESPONSE_KEYS, UnitOnLoadResponseEvent } from '../../messages/webMessages/onLoadMessage';
import { MultiFactorAuthenticationMessage } from '../../messages/webMessages/multiFactorAuthenticationMessage';

export interface UNMultiFactorAuthenticationComponentProps {

  // ui
  theme?: string;
  language?: string;

  // callbacks
  onLoad?: (response: UNComponentsOnLoadResponse<undefined>) => void
  onVerificationTokenCreated?: (data: UNCustomerTokenVerification) => void
  onAuthenticationFinished?: (data: UNMultiFactorAuthenticationFinished) => void
}

const UNMultiFactorAuthenticationComponent = (props: UNMultiFactorAuthenticationComponentProps) => {
  const [height, setHeight] = useState<number>(0);
  const [presentationMode, setPresentationMode] = useState<PresentationMode>(PresentationMode.Inherit);

  const handleUnitOnLoad = (response: UnitOnLoadResponseEvent) => {
    if (!props.onLoad) {
      return;
    }

    if (RESPONSE_KEYS.errors in response) {
      props.onLoad(response as UNComponentsError);
      return;
    }

    props.onLoad({ data: undefined });
  };

  const handleWebViewMessage = (message: WebViewMessage) => {
    if (!message || !message.details) return;

    switch (message.type) {
      case UnitComponentsMessage.UNIT_ON_LOAD:
        handleUnitOnLoad(message.details as UnitOnLoadResponseEvent);
        break;
      case PageMessage.PAGE_HEIGHT: {
        const currentHeight = (message.details as HeightEvent).height;
        setHeight(currentHeight);
        if (presentationMode === PresentationMode.Inherit && currentHeight === 0) {
          setPresentationMode(PresentationMode.Default);
        }
        break;
      }
      case MultiFactorAuthenticationMessage.UNIT_MFA_VERIFICATION_TOKEN_CREATED:
        props.onVerificationTokenCreated && props.onVerificationTokenCreated(message.details as UNCustomerTokenVerification);
        break;
      case UnitComponentsMessage.UNIT_MULTI_FACTOR_AUTH_FINISHED: {
        const data = JSON.parse((message.details as MultiFactorAuthenticationFinishedEvent).tokenString);
        props.onAuthenticationFinished && props.onAuthenticationFinished(data as UNMultiFactorAuthenticationFinished);
        break;
      }
    }
  };

  const style = presentationMode === PresentationMode.Inherit ? { flex: 1 } : { height: height };
  return <UNBaseView style={style} onLoadError={handleUnitOnLoad} fallback={<></>}>
    <WebComponent
      type={WebComponentType.multiFactorAuthentication}
      presentationMode={PresentationMode.Inherit}
      params={getMultiFactorAuthenticationParams()}
      script={getMultiFactorAuthenticationScript()}
      onMessage={(message: WebViewMessage) => handleWebViewMessage(message)}
      theme={props.theme}
      language={props.language}
    />
  </UNBaseView>;
};

export default withReduxStore<UNMultiFactorAuthenticationComponentProps>(UNMultiFactorAuthenticationComponent);
