import React, { useState } from 'react';
import { UNAccount, UNComponentsError, UNComponentsOnLoadResponse, UNComponentsOnLoadResponseData } from '../../types/shared';
import { UNCheckPayment } from '../../types/shared/payment';
import { PresentationMode, WebComponentType } from '../../types/internal/webComponent.types';
import { RESPONSE_KEYS, UnitOnLoadResponseEvent } from '../../messages/webMessages/onLoadMessage';
import { ensureArray } from '../../utils/onLoadMessages.utils';
import type { WebViewMessage } from '../../messages/webMessages';
import { PaymentMessage } from '../../messages/webMessages/paymentsMessage';
import { CheckPaymentEvent } from '../../messages/webMessages/checkPaymentMessage';
import { UnitComponentsMessage } from '../../messages/webMessages/unitComponentsMessages';
import { HeightEvent, PageMessage } from '../../messages/webMessages/pageMessage';
import { UNBaseView } from '../../nativeComponents/UNBaseView';
import { WebComponent } from '../../webComponent/WebComponent';
import { withReduxStore } from '../../helpers/store/helpers';
import { getCheckPaymentParams, getCheckPaymentScript } from './UNCheckPaymentComponent.utils';

export interface UNCheckPaymentComponentProps {
  //inputs
  accountId?: string;

  // ui
  theme?: string;
  language?: string;
  initialStageBackButton?: boolean;
  finalStageDoneButton?: boolean;

  // events
  onLoad?: (response: UNComponentsOnLoadResponse<[UNAccount]>) => void;
  onPaymentCreated?: (data: UNCheckPayment) => void;
  onInitialStageBackButtonClicked?: () => void;
  onFinalStageDoneButtonClicked?: () => void;
}

const UNCheckPaymentComponent = (props: UNCheckPaymentComponentProps) => {
  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;
    }

    if (RESPONSE_KEYS.account in response) {
      const account = response[RESPONSE_KEYS.account].data;
      const paymentOnload: UNComponentsOnLoadResponseData<[UNAccount]> = {
        data: ensureArray(account),
      };
      props.onLoad(paymentOnload);
      return;
    }

    console.error('On Load Error: unexpected response type');
    return;
  };

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

    switch (message.type) {
      case PaymentMessage.INITIAL_STAGE_BACK_BUTTON_CLICKED: {
        props.onInitialStageBackButtonClicked && props.onInitialStageBackButtonClicked();
        break;
      }
      case PaymentMessage.FINAL_STAGE_DONE_BUTTON_CLICKED: {
        props.onFinalStageDoneButtonClicked && props.onFinalStageDoneButtonClicked();
        break;
      }
      case PaymentMessage.PAYMENT_CREATED: {
        const checkPaymentEvent = message.details as CheckPaymentEvent;
        props.onPaymentCreated && props.onPaymentCreated(checkPaymentEvent.data as UNCheckPayment);
        break;
      }
      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;
      }
    }
  };

  const style = presentationMode === PresentationMode.Inherit ? { flex: 1 } : { height: height };

  return (
    <UNBaseView style={style} onLoadError={ handleUnitOnLoad } fallback={<></>}>
      <WebComponent
        type={WebComponentType.checkPayment}
        presentationMode={presentationMode}
        params={getCheckPaymentParams(props)}
        script={getCheckPaymentScript()}
        onMessage={(message: WebViewMessage) => handleWebViewMessage(message)}
        isScrollable={true}
        theme={props.theme}
        language={props.language}
      />
    </UNBaseView>
  );
};

export default withReduxStore<UNCheckPaymentComponentProps>(UNCheckPaymentComponent);