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

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

  // ui
  theme?: string;
  language?: string;
  isAutoFocus?: boolean;
  isSameCustomer?: boolean;
  counterPartyAccountId?: string;
  counterPartyName?: string;
  initialStageBackButton?: boolean;
  finalStageDoneButton?: boolean;

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

const UNBookPaymentComponent = (props: UNBookPaymentComponentProps) => {
  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;
      // AccountOnLoadResponse;
      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:
        props.onPaymentCreated && props.onPaymentCreated((message.details as UNBookPayment));
        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.bookPayment}
        presentationMode={presentationMode}
        params={getBookPaymentParams(props)}
        script={getBookPaymentScript()}
        onMessage={(message: WebViewMessage) => handleWebViewMessage(message)}
        isScrollable={true}
        theme={props.theme}
        language={props.language}
      />
    </UNBaseView>
  );
};

export default withReduxStore<UNBookPaymentComponentProps>(UNBookPaymentComponent);
