import React, { useEffect, useRef, useState } from 'react';
import { Platform } from 'react-native';
import { useSelector } from 'react-redux';
import { WebComponent } from '../../webComponent/WebComponent';
import type { WebViewMessage } from '../../messages/webMessages';
import { HeightEvent, PageMessage } from '../../messages/webMessages/pageMessage';
import { RequestExternalSdkEvent, UnitComponentsMessage } from '../../messages/webMessages/unitComponentsMessages';
import { getCheckDepositParams, getCheckDepositScript, injectUnitVeryfiResponse } from './UNCheckDepositComponent.utils';
import { CheckMessage } from '../../messages/webMessages/checkMessage';
import type { UNCheckDeposit, UNAccount, UNComponentsError, UNComponentsOnLoadResponse, UNComponentsOnLoadResponseData } from '../../types/shared';
import { RESPONSE_KEYS, UnitOnLoadResponseEvent } from '../../messages/webMessages/onLoadMessage';
import { PresentationMode, WebComponentType } from '../../types/internal/webComponent.types';
import { withReduxStore } from '../../helpers/store/helpers';
import { PaymentMessage } from '../../messages/webMessages/paymentsMessage';
import { UNBaseView } from '../../nativeComponents/UNBaseView';
import UNPermissionsModule from '../../nativeModulesHelpers/UNPermissionsHelper/UNPermissionsHelper';
import { isVeryfiAvailable, configureAndShowVeryfiCamera } from '../../services/veryfiService';
import type WebView from 'react-native-webview';
import type { RootState } from '../../store';

export interface UNCheckDepositComponentProps {
  accountId?: string;
  fee?: number;
  theme?: string;
  language?: string;
  initialStageBackButton?: boolean;
  finalStageDoneButton?: boolean;
  onLoad?: (response: UNComponentsOnLoadResponse<UNAccount>) => void;
  onDepositCreated?: (checkData: UNCheckDeposit) => void;
  onRestartRequest?: (checkData: UNCheckDeposit) => void;
  onInitialStageBackButtonClicked?: () => void;
  onFinalStageDoneButtonClicked?: () => void;
}

const UNCheckDepositComponent = (props: UNCheckDepositComponentProps) => {
  const [height, setHeight] = useState<number>(0);
  const [presentationMode, setPresentationMode] = useState<PresentationMode>(PresentationMode.Inherit);
  const webRef = useRef<WebView>(null);
  const veryfiCredentials = useSelector((state: RootState) => state.configuration.veryfiCredentials);

  useEffect(() => {
    const requestCameraAccess = async () => {
      try {
        await UNPermissionsModule.camera();
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
      } catch (error: any) {
        console.error(error);
      }
    };

    if (Platform.OS == 'ios') {
      requestCameraAccess();
    }
  }, []);

  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) {
      // AccountOnLoadResponse;
      props.onLoad(response[RESPONSE_KEYS.account] as UNComponentsOnLoadResponseData<UNAccount>);
      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 CheckMessage.CHECK_DEPOSIT_CREATED:
        props.onDepositCreated && props.onDepositCreated(message.details as UNCheckDeposit);
        break;
      case CheckMessage.CHECK_DEPOSIT_RESTART_REQUEST:
        props.onRestartRequest && props.onRestartRequest(message.details as UNCheckDeposit);
        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;
      }
      case UnitComponentsMessage.UNIT_REQUEST_EXTERNAL_SDK: {
        const externalSdkEvent = message.details as RequestExternalSdkEvent;
        if (externalSdkEvent.type !== 'veryfi') return;
        if (!isVeryfiAvailable()) {
          console.warn('Veryfi SDK is not installed — check deposit will use the default web scanner');
          return;
        }
        if (!veryfiCredentials) {
          console.error('Veryfi credentials not provided in UnitComponentsSdkManager.init()');
          return;
        }
        configureAndShowVeryfiCamera(
          veryfiCredentials,
          externalSdkEvent.bankName,
          (images) => {
            injectUnitVeryfiResponse(webRef.current, images);
          },
          (error) => {
            console.error('Veryfi error:', error);
          }
        );
        break;
      }
    }
  };

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

  return (
    <UNBaseView style={style} onLoadError={ handleUnitOnLoad } fallback={<></>}>
      <WebComponent
        ref={webRef}
        type={WebComponentType.checkDeposit}
        presentationMode={presentationMode}
        params={getCheckDepositParams(props, veryfiCredentials)}
        script={getCheckDepositScript()}
        onMessage={(message: WebViewMessage) => handleWebViewMessage(message)}
        theme={props.theme}
        language={props.language}
        isScrollable={true}
      />
    </UNBaseView>
  );
};

export default withReduxStore<UNCheckDepositComponentProps>(UNCheckDepositComponent);
