import React, {
  createContext,
  useContext,
  useState,
  useEffect,
  useRef,
} from 'react';
import {getWorkflowInfoByLink, submitKYCRequest} from '../service/facekiAPI';
import {Alert, Linking, NativeModules, PermissionsAndroid, Platform} from 'react-native';
import {HEADINGS, HEADING_TYPE} from '../wrapper/HEADINGS';
import type {PropsWithChildren} from 'react';
import {FacekiApiResponse} from '../service/types/facekiresponse';
import {Camera} from 'react-native-vision-camera';
import {Branding} from '../service/types/interfaces';
import Toast from 'react-native-toast-message';
import {translations, Language, Translation} from '../i18n/translations';
import RNFS from 'react-native-fs';

const Resizer = require('@bam.tech/react-native-image-resizer');

type userStepsType = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13;
export type modeType = 'user' | {exact: 'environment'};

type GeoLocation = {
  latitude: number;
  longitude: number;
};

type GeolocationLike = {
  setRNConfiguration?: (config: {
    skipPermissionRequests?: boolean;
    authorizationLevel?: 'always' | 'whenInUse' | 'auto';
    enableBackgroundLocationUpdates?: boolean;
  }) => void;
  requestAuthorization?: (
    success?: () => void,
    error?: (error: any) => void,
  ) => void;
  getCurrentPosition: (
    success: (position: any) => void,
    error?: (error: any) => void,
    options?: {
      enableHighAccuracy?: boolean;
      timeout?: number;
      maximumAge?: number;
    },
  ) => void;
};

const buildNativeGeolocation = (): GeolocationLike | undefined => {
  const nativeGeo = (NativeModules as any)?.RNCGeolocation;
  if (!nativeGeo?.getCurrentPosition) {
    return undefined;
  }

  return {
    setRNConfiguration: config => {
      nativeGeo.setConfiguration?.(config);
    },
    requestAuthorization: (success, error) => {
      nativeGeo.requestAuthorization?.(
        () => success?.(),
        (nativeError: any) => error?.(nativeError),
      );
    },
    getCurrentPosition: (success, error, options) => {
      nativeGeo.getCurrentPosition?.(
        options ?? {},
        (position: any) => success(position),
        (nativeError: any) => error?.(nativeError),
      );
    },
  };
};

const parseGeolocationEnforce = (value: unknown) => {
  if (typeof value === 'boolean') {
    return value;
  }

  if (typeof value === 'number') {
    return value === 1;
  }

  if (typeof value === 'string') {
    const normalizedValue = value.trim().toLowerCase();
    return normalizedValue === 'true' || normalizedValue === '1' || normalizedValue === 'yes';
  }

  return false;
};

const CONTENT = ['ID Card', 'Passport', 'Driving License'];

type ContentType = (typeof CONTENT)[number];

export type ImgUrlsType = {
  [key in ContentType]: {
    frontImage: {uri: string; path: string; size?: number};
    backImage: {uri: string; path: string; size?: number};
    selfie: {uri: string; path: string; size?: number};
  };
};

// Define the type of the context value
type ContextType = {
  onLivenessError?: (imageBase64: any, response: string) => void;
  onCancel?: () => void;
  userStep: userStepsType;
  handlerUserSteps: () => void;
  goBackUserSteps: (index?: number) => void;
  HEADINGS: HEADING_TYPE;
  findOutStepContent: () => {
    step: number;
    heading: string;
    subHeading: string;
  };
  selectedOption: string;
  handleOptionChange: (event: string) => void;
  webcamRef: React.MutableRefObject<any | null>;
  handleSingleCapturePhoto: (step: number) => void;
  imgUrls: ImgUrlsType;
  finalResult:
    | {
        heading: string;
        subText: string;
        success: boolean;
      }
    | undefined;
  routeOfHandler: () => void;
  allowedKycDocuments: string[];
  isChecked: boolean;
  handleCheckbox: () => void;
  loading: boolean;
  kycRuleError: boolean;
  allowSingle: boolean;
  skipGuidanceScreens?: boolean;
  consenttermofuseLink?: string;
  skipFirstScreen?: boolean;
  skipResultScreen?: boolean;
  branding?: Branding;
  livenessScoreOverride?: number | null;
  resultContent?: {
    success: {
      heading: string;
      subHeading: string;
    };
    fail: {
      heading: string;
      subHeading: string;
    };
    verification: {
      heading: string;
    };
  };
  language: Language;
  t: Translation;
  isRTL: boolean;
};

type VerificationProviderProps = PropsWithChildren<{
  verification_url: string;
  onError: (message: Error) => void;
  onComplete: (message: FacekiApiResponse) => void;
  onCancel?: () => void;
  onLivenessError?: (imageBase64: string, response: string) => void;

  skipGuidanceScreens?: boolean;
  consenttermofuseLink?: string;
  allowSingleOverride?: boolean;
  skipFirstScreen?: boolean;
  skipResultScreen?: boolean;
  resultContent?: {
    success: {
      heading: string;
      subHeading: string;
    };
    fail: {
      heading: string;
      subHeading: string;
    };
    verification: {
      heading: string;
    };
  };
  singleVerificationDoc?: 'Passport' | 'ID Card' | 'Driving License';
  branding?: Branding;
  livenessScoreOverride?: any;
  record_identifier?: string;
  language?: Language;
  geo_location?: GeoLocation;
}>

// Create the context
const VerificationContext = createContext<ContextType>({} as ContextType);

export const VerificationProvider: React.FC<VerificationProviderProps> = ({
  children,
  verification_url,
  onLivenessError,
  onError,
  onComplete,
  onCancel,
  allowSingleOverride,
  skipGuidanceScreens,
  consenttermofuseLink,
  skipFirstScreen,
  skipResultScreen,
  resultContent,
  singleVerificationDoc,
  branding,
  record_identifier,
  language = 'en',
  geo_location,
}) => {
  const t: Translation = translations[language] ?? translations.en;
  const isRTL = language === 'ar';
  const [userStep, setUserStep] = useState<userStepsType>(
    skipFirstScreen ? 2 : 1,
  );
  const webcamRef = useRef<any | null>(null);
  const [allowSingle, setAllowSingle] = useState(false);
  const [allowedKycDocuments, setAllowedKycDocuments] = useState<string[]>([]);
  const [isChecked, setIsChecked] = useState(false);
  const [clientCredentials, setClientCredentials] = useState();
  const [token, setToken] = useState('');
  const [loading, setLoading] = useState(true);
  const [kycRuleError, setKycRuleError] = useState(false);
  const [workflowId, setWorkflowId] = useState(null);
  const [rulesData, setRulesData] = useState(null);
  const [livenessScoreOverrideAPI, setLivenessScoreOverrideAPI] =
    useState(null);
  const [geolocationEnforce, setGeolocationEnforce] = useState(false);
  const [resolvedGeoLocation, setResolvedGeoLocation] = useState<GeoLocation | undefined>(geo_location);

  useEffect(() => {
    if (geo_location) {
      setResolvedGeoLocation(geo_location);
    }
  }, [geo_location]);

  useEffect(() => {
    if (skipFirstScreen) {
      setUserStep(2);
    }
  }, [skipFirstScreen]);

  const handleCheckbox = () => {
    setIsChecked(!isChecked);
  };

  const [finalResult, setFinalResult] = useState<{
    heading: string;
    subText: string;
    success: boolean;
  }>();
  const [selectedOption, setSelectedOption] = useState<
    (typeof CONTENT)[number]
  >(CONTENT[0]);
  const [leftOptions, setLeftOptions] = useState<string[]>([]); // options that are left before moving ahead

  const [imgUrls, setImgUrls] = useState<ImgUrlsType>({
    ['ID Card']: {
      frontImage: {uri: '', path: ''},
      backImage: {uri: '', path: ''},
      selfie: {uri: '', path: ''},
    },
    ['Passport']: {
      frontImage: {uri: '', path: ''},
      backImage: {uri: '', path: ''},
      selfie: {uri: '', path: ''},
    },
    ['Driving License']: {
      frontImage: {uri: '', path: ''},
      backImage: {uri: '', path: ''},
      selfie: {uri: '', path: ''},
    },
  });

  useEffect(() => {
    const requestStartupPermissions = async () => {
      await checkCameraPermission(false);
      await requestGeoLocation(false);
    };

    requestStartupPermissions().catch(() => undefined);
  }, []);

  const showCameraDeclinedPopup = () => {
    Alert.alert(
      'Camera Permission Denied',
      'Camera access is required to continue verification. Please enable it in Settings.',
      [
        {text: 'Cancel', style: 'cancel'},
        {text: 'Open Settings', onPress: () => Linking.openSettings()},
      ],
    );
  };

  const checkCameraPermission = async (showDeniedPopup = true) => {
    const cameraPermission = await Camera.getCameraPermissionStatus();
    if (cameraPermission !== 'granted') {
      const newCameraPermission = await Camera.requestCameraPermission();
      if (newCameraPermission !== 'granted') {
        if (showDeniedPopup) {
          showCameraDeclinedPopup();
        }
        return false;
      }

      return true;
    }

    return true;
  };

  const showLocationDeclinedPopup = (message?: string) => {
    Alert.alert(
      'Location Permission Denied',
      message ??
        (geolocationEnforce
          ? 'Location is required to continue verification. Please enable it in Settings.'
          : 'Location permission is denied. You can continue, or enable it in Settings.'),
      [
        {text: 'Cancel', style: 'cancel'},
        {text: 'Open Settings', onPress: () => Linking.openSettings()},
      ],
    );
  };

  const requestGeoLocation = async (
    showDeniedPopup = false,
  ): Promise<GeoLocation | undefined> => {
    if (resolvedGeoLocation) {
      return resolvedGeoLocation;
    }

    if (geo_location) {
      return geo_location;
    }

    if (Platform.OS === 'android') {
      const fineLocation = PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION;
      const status = await PermissionsAndroid.request(fineLocation);
      if (status !== PermissionsAndroid.RESULTS.GRANTED) {
        if (showDeniedPopup || geolocationEnforce) {
          showLocationDeclinedPopup();
        }
        return undefined;
      }
    }

    let geolocation: GeolocationLike | undefined;

    try {
      const geolocationModule = require('@react-native-community/geolocation');
      geolocation = geolocationModule?.default ?? geolocationModule;
    } catch (_error) {
      geolocation = buildNativeGeolocation();
    }

    if (!geolocation) {
      geolocation = (globalThis as any)?.navigator?.geolocation;
    }

    if (!geolocation?.getCurrentPosition) {
      if (showDeniedPopup || geolocationEnforce) {
        showLocationDeclinedPopup('Unable to access device location. Please enable location services in Settings.');
      }
      return undefined;
    }

    geolocation.setRNConfiguration?.({
      skipPermissionRequests: false,
      authorizationLevel: 'whenInUse',
    });

    if (Platform.OS === 'ios' && geolocation.requestAuthorization) {
      await new Promise<void>(resolve => {
        geolocation.requestAuthorization?.(
          () => resolve(),
          () => {
            if (showDeniedPopup || geolocationEnforce) {
              showLocationDeclinedPopup();
            }
            resolve();
          },
        );
      });
    }

    const currentLocation = await new Promise<GeoLocation | undefined>(resolve => {
      geolocation.getCurrentPosition(
        (position: any) => {
          resolve({
            latitude: position.coords.latitude,
            longitude: position.coords.longitude,
          });
        },
        (error: any) => {
          const isPermissionDenied =
            error?.code === 1 ||
            /denied/i.test(String(error?.message ?? ''));

          if (showDeniedPopup || geolocationEnforce) {
            if (isPermissionDenied) {
              showLocationDeclinedPopup();
            } else {
              showLocationDeclinedPopup('Unable to read your current location. Please try again or check location settings.');
            }
          }

          resolve(undefined);
        },
        {
          enableHighAccuracy: true,
          timeout: 15000,
          maximumAge: 0,
        },
      );
    });

    if (currentLocation) {
      setResolvedGeoLocation(currentLocation);
    }

    return currentLocation;
  };

  const ensureGeoLocationIfRequired = async () => {
    if (!geolocationEnforce) {
      return true;
    }

    const location = await requestGeoLocation();
    if (location) {
      return true;
    }

    Alert.alert('Location Required', 'Please enable GPS location to continue verification.');
    return false;
  };

  const getGeoLocationForSubmission = async () => {
    if (resolvedGeoLocation) {
      return resolvedGeoLocation;
    }

    return requestGeoLocation(true);
  };

  useEffect(() => {
    if (!verification_url) {
      console.error('Please provide verification url for faceki kyc');
    }
  }, []);

  const getKYCRules = async (verificationURL?: any) => {
    try {
      const rulesWorkflows = await getWorkflowInfoByLink(verificationURL);

      if (!rulesWorkflows.result) {
        console.error('Invalid Workflow ID');
        setKycRuleError(true);
        setLoading(false);
        return;
      }
      var resultValues = rulesWorkflows.result;

      setWorkflowId(resultValues.workflowId);
      setRulesData(resultValues);
      setLivenessScoreOverrideAPI(resultValues.threshold_val);
      const geoEnforceFromRule = parseGeolocationEnforce(
        resultValues.geolocation_enforce,
      );
      setGeolocationEnforce(geoEnforceFromRule);
      // Do not block workflow/rules loading on GPS resolution.
      requestGeoLocation().catch(() => undefined);
      setAllowedKycDocuments(resultValues.documents as string[]);
      // CASE OF SINGLE DOCUMENT Choice
      if (resultValues.document_optional) {
        setSelectedOption(resultValues.documents?.[0]);
        setAllowSingle(true);
        if (skipFirstScreen) {
          setUserStep(2);
        }
      }
      // CASE OF No Choice
      else {
        setSelectedOption(resultValues.documents?.[0]);
        if (skipFirstScreen) {
          setUserStep(3);
        }
      }
      setLoading(false);
      const copyLeftOptions = [...resultValues.documents];
      copyLeftOptions.shift(); // remove first element from an array
      setLeftOptions(copyLeftOptions);
    } catch (err) {
      console.log(err);
      setKycRuleError(true);
      setLoading(false);
    }
  };

  useEffect(() => {
    if (verification_url) {
      getKYCRules(verification_url);
    }
  }, [verification_url]);

  const handleSingleCapturePhoto = async (
    step: number,
    image?: any,
    refOverride?: any,
  ) => {
    const allowedToAccessCamera = await checkCameraPermission(true);

    // if not allowed to access camera dont proceed
    if (!allowedToAccessCamera) {
      return;
    }

    if (!image) {
      if (webcamRef.current) {
        var imageSrc = await webcamRef?.current?.takePhoto?.({
          enableShutterSound: false,
          enableAutoStabilization: true,
        });
      } else {
        var imageSrc = await refOverride?.current?.takePhoto?.({
          enableShutterSound: false,
          enableAutoStabilization: true,
        });
      }
    } else {
      var imageSrc = image;
    }

    if (imageSrc?.path) {
      if (step === 5) {
        setImgUrls(prev => ({
          ...prev,
          [selectedOption]: {
            ...prev[selectedOption],
            frontImage: imageSrc,
          },
        }));
      }
      if (step === 7) {
        setImgUrls(prev => ({
          ...prev,
          [selectedOption]: {
            ...prev[selectedOption],
            backImage: imageSrc,
          },
        }));
      }

      if (step === 10) {
          const locationForSubmission = await getGeoLocationForSubmission();
          if (geolocationEnforce && !locationForSubmission) {
            Alert.alert('Location Required', 'Please enable GPS location to continue verification.');
          return;
        }

        //Compressing
        try {
          // 10MB limit per document combo (doc_front + doc_back + selfie)
          // Calculate selfie budget from actual captured document sizes
          const LIMIT_PER_COMBO = 10 * 1024 * 1024; // 10MB
          const DEFAULT_DOC_SIZE = 3 * 1024 * 1024; // assume 3MB if size unknown
          let selfieBudget = LIMIT_PER_COMBO;

          Object.values(imgUrls).forEach(doc => {
            const hasImages = doc.frontImage.path !== '';
            if (hasImages) {
              const frontSize = doc.frontImage.size || DEFAULT_DOC_SIZE;
              const backSize = doc.backImage.path ? (doc.backImage.size || DEFAULT_DOC_SIZE) : 0;
              const available = LIMIT_PER_COMBO - frontSize - backSize;
              selfieBudget = Math.min(selfieBudget, available);
            }
          });

          // Clamp: at least 1MB, at most 4MB
          selfieBudget = Math.max(1 * 1024 * 1024, selfieBudget);
          selfieBudget = Math.min(4 * 1024 * 1024, selfieBudget);
          console.log(`Selfie budget: ${(selfieBudget / 1024 / 1024).toFixed(1)}MB`);

          let quality = 100;
          let result = await Resizer.default.createResizedImage(
            (Platform.OS === 'android' ? 'file://' : '') + imageSrc.path,
            1920,
            1080,
            'JPEG',
            quality,
            0,
            undefined,
            false,
            {mode: 'contain'},
          );

          if (result.size > selfieBudget) {
            quality = Math.max(40, Math.floor((selfieBudget / result.size) * 100));
            result = await Resizer.default.createResizedImage(
              (Platform.OS === 'android' ? 'file://' : '') + imageSrc.path,
              1920,
              1080,
              'JPEG',
              quality,
              0,
              undefined,
              false,
              {mode: 'contain'},
            );
          }
          console.log(`Selfie resized: ${(result.size / 1024).toFixed(0)}KB @ quality ${quality}`);
          imageSrc = result;
          // setResizedImage(result);
        } catch (error) {
          console.log(error);
          // Alert.alert('Unable to resize the photo');
        }

        setImgUrls(prev => ({
          ...prev,
          [selectedOption]: {
            ...prev[selectedOption],
            selfie: imageSrc,
          },
        }));

        setUserStep(prev => (prev + 1) as userStepsType);
        console.log(imgUrls);

        const payload = Object.entries(imgUrls)
          .map(([documentType, documentData]) => {
            return {
              document_type: documentType,
              document_front: documentData.frontImage
                ? documentData.frontImage.path
                : '',
              document_back: documentData?.backImage
                ? documentData?.backImage?.path
                : '',
            };
          })
          .filter(({document_front, document_back, document_type}) => {
            if (document_type == 'Passport') {
              return document_front !== '';
            } else {
              return document_front !== '' && document_back !== '';
            }
          });

        console.log(JSON.stringify(payload), allowSingle);
        if (!allowSingle) {
          if (allowedKycDocuments.length == payload.length) {
            var formData = new FormData();
            for (let index = 0; index < payload.length; index++) {
              const element = payload[index];
              formData.append(`document_${index + 1}_front`, {
                uri:
                  Platform.OS == 'android'
                    ? 'file://' + element.document_front
                    : element.document_front,
                type: 'image/jpeg',
                name: `photo_front_image.jpg`,
              });

              if (element.document_back && element.document_back != '') {
                formData.append(`document_${index + 1}_back`, {
                  uri:
                    Platform.OS == 'android'
                      ? 'file://' + element.document_back
                      : element.document_back,
                  type: 'image/jpeg',
                  name: `photo_front_image.jpg`,
                });
              }
            }

            formData.append('selfie', {
              uri:
                Platform.OS == 'android'
                  ? 'file://' + `${imageSrc.path}`
                  : `${imageSrc.path}`,
              type: 'image/jpeg',
              name: `photo_selfie_image.jpg`,
            });

            formData.append('workflowId', workflowId);
            formData.append('record_identifier', record_identifier);
            formData.append('link', verification_url);
              if (locationForSubmission) {
                formData.append('geo_location', JSON.stringify(locationForSubmission));
            }

            console.log(formData);
            submitKYCRequest(formData)
              .then((res: any) => {
                console.log(res);

                const responseWithType = FacekiApiResponse.createInstance(
                  res.status,
                  res.code,
                  res.message,
                  res.appVersion,
                  res.result,
                );

                onComplete && onComplete(responseWithType);

                handleError(res, imageSrc);
              })
              .catch((err: Error) => {
                console.log(err);

                onError && onError(err);
              });
          }
        } else {
          var formData = new FormData();
          console.log('Starting');
          formData.append(`document_1_front`, {
            uri:
              Platform.OS == 'android'
                ? 'file://' + payload[0].document_front
                : payload[0].document_front,
            type: 'image/jpeg',
            name: `photo_front_image.jpg`,
          });
          if (payload[0].document_back && payload[0].document_back != '') {
            formData.append(`document_1_back`, {
              uri:
                Platform.OS == 'android'
                  ? 'file://' + payload[0].document_back
                  : payload[0].document_back,
              type: 'image/jpeg',
              name: `photo_front_image.jpg`,
            });
          }

          formData.append('selfie', {
            uri:
              Platform.OS == 'android'
                ? 'file://' + `${imageSrc.path}`
                : `${imageSrc.path}`,
            type: 'image/jpeg',
            name: `photo_selfie_image.jpg`,
          });

          formData.append('workflowId', workflowId);
          formData.append('record_identifier', record_identifier);
          formData.append('link', verification_url);
            if (locationForSubmission) {
              formData.append('geo_location', JSON.stringify(locationForSubmission));
          }

          submitKYCRequest(formData)
            .then(res => {
              console.log(res);
              const responseWithType = FacekiApiResponse.createInstance(
                res.status,
                res.code,
                res.message,
                res.appVersion,
                res.result,
              );
              onComplete && onComplete(responseWithType);

              handleError(res, imageSrc);
            })
            .catch(err => {
              console.log(err);
              onError && onError(err);
            });
        }

        return;
      }
      if ([5, 7, 10].includes(step)) {
        setUserStep(prev =>
          prev == step ? ((prev + 1) as userStepsType) : prev,
        );
      }
    }
  };

  const handleError = async (response: any, imageSrc?: any) => {
    if (response.result?.decision == 'ACCEPTED') {
      const result = {
        heading: resultContent?.success.heading || t.successHeading,
        subText: resultContent?.success.subHeading || t.successText,
        success: true,
      };
      setFinalResult(result);
      if (!skipResultScreen) {
        setUserStep(prev => (prev + 1) as userStepsType);
      }
    } else {
      if (
        [8004, 8005, 8006, 8007, 8008, 8009, 5004, 5005].includes(
          response?.code,
        )
      ) {
        // Send liveness error callback with base64 image
        if (onLivenessError && imageSrc?.path) {
          try {
            const base64 = await RNFS.readFile(imageSrc.path, 'base64');
            onLivenessError(
              'data:image/jpeg;base64,' + base64,
              JSON.stringify(response),
            );
          } catch (readErr) {
            console.error('base64 read failed (handleError):', readErr);
          }
        }

        let errorText2: string;
        switch (response?.code) {
          case 5005:
            errorText2 = t.faceNoMatch;
            break;
          case 5004:
            errorText2 = t.livenessTestFail;
            break;
          case 8004:
            errorText2 = t.faceCropped;
            break;
          case 8005:
            errorText2 = t.faceTooClose;
            break;
          case 8006:
            errorText2 = t.faceNotFound;
            break;
          case 8007:
            errorText2 = t.faceNearBorder;
            break;
          case 8008:
            errorText2 = t.faceTooSmall;
            break;
          case 8009:
            errorText2 = t.poorLighting;
            break;
          default:
            errorText2 = t.livenessTestFail;
        }

        Toast.show({
          type: 'error',
          text2: t.pleaseRetakeSelfie,
          text1: errorText2,
        });

        setUserStep(prev => (prev - 1) as userStepsType);
      } else {
        const result = {
          heading: resultContent?.fail.heading || t.failHeading,
          subText: resultContent?.fail.subHeading || t.failText,
          success: false,
        };
        setFinalResult(result);
        if (!skipResultScreen) {
          setUserStep(prev => (prev + 1) as userStepsType);
        }
      }
    }
  };

  const handlerUserSteps = () => {
    if (geolocationEnforce && !resolvedGeoLocation) {
      requestGeoLocation(true).then(location => {
        if (!location) {
          showLocationDeclinedPopup(
            'Location is required to continue verification. Please enable it in Settings.',
          );
        }
      });
      return;
    }

    if (loading && userStep == 1) {
      return;
    }
    if ([3, 8].includes(userStep) && skipGuidanceScreens) {
      setUserStep(prev => (prev + 2) as userStepsType);
      return;
    }

    if (!allowSingle && userStep === 1) {
      setUserStep(prev => (prev + 2) as userStepsType);
      return;
    }
    if (userStep === 2) {
      if (loading || kycRuleError) {
        Alert.alert(t.selectKycType, '', [
          {
            text: t.cancel,
            onPress: () => {},
            style: 'cancel',
          },
          {text: t.ok, onPress: () => {}},
        ]);
        return;
      }
    }
    if (userStep === 3) {
      if (!isChecked) {
        Alert.alert(t.agreeTerms, '', [
          {
            text: t.cancel,
            onPress: () => {},
            style: 'cancel',
          },
          {text: t.ok, onPress: () => {}},
        ]);
        return;
      }
    }

    setUserStep(prev => (prev + 1) as userStepsType);
  };

  const routeOfHandler = () => {
    if (userStep === 6 && selectedOption === 'Passport') {
      setUserStep(prev => (prev + 1) as userStepsType);
      moveForwardonlyIfNoLeftOption();
    }

    if (userStep === 8) {
      moveForwardonlyIfNoLeftOption();
    } else {
      handlerUserSteps();
    }
  };

  const moveForwardonlyIfNoLeftOption = () => {
    if (leftOptions.length === 0 || allowSingle) {
      if (skipGuidanceScreens) {
        setUserStep(prev => (prev + 2) as userStepsType);
      } else {
        setUserStep(prev => (prev + 1) as userStepsType);
      }
      return;
    }
    setUserStep(prev => (prev - 3) as userStepsType);

    // make the left option to be selected
    setSelectedOption(leftOptions[0]);

    // remove left option
    const copyLeftOptions = [...leftOptions];
    copyLeftOptions.shift();
    setLeftOptions(copyLeftOptions);
  };

  const goBackUserSteps = (index?: number) => {
    setUserStep((prev: any) => {
      if (index) {
        return (prev - index) as userStepsType;
      } else {
        return (prev - 1) as userStepsType;
      }
    });
  };

  // Function for getting Content
  const findOutStepContent = () => {
    const stepData = t.steps[userStep] ?? { step: userStep, heading: '', subHeading: '' };
    if (userStep === 4 || userStep === 5 || userStep === 6 || userStep === 7) {
      const docLabel = t.docLabels[selectedOption] || selectedOption;
      return { ...stepData, heading: `${stepData.heading} ${docLabel}` };
    }
    return stepData;
  };

  // Function for selecting document
  const handleOptionChange = (event: string) => {
    setSelectedOption(event);

    const targetIndex = allowedKycDocuments.indexOf(event);

    const copyLeftOptions = [...allowedKycDocuments];

    // sort them based on new selection
    if (targetIndex !== -1) {
      copyLeftOptions.sort((a, b) => {
        if (a === event) {
          return -1; // a should come before b
        } else if (b === event) {
          return 1; // b should come before a
        } else {
          return 0; // leave the order unchanged
        }
      });
    }

    copyLeftOptions.shift();
    setLoading(false);
    // copyLeftOptions.shift(); // remove first element from an array
    setLeftOptions(copyLeftOptions);
  };

  return (
    <VerificationContext.Provider
      value={{
        onLivenessError,
        onCancel,
        userStep,
        handlerUserSteps,
        goBackUserSteps,
        HEADINGS,
        findOutStepContent,
        selectedOption,
        handleOptionChange,
        allowedKycDocuments,
        handleSingleCapturePhoto,
        webcamRef,
        imgUrls,
        finalResult,
        routeOfHandler,
        isChecked,
        handleCheckbox,
        loading,
        kycRuleError,
        skipGuidanceScreens,
        allowSingle,
        consenttermofuseLink,
        skipFirstScreen,
        branding,
        resultContent,
        livenessScoreOverride: livenessScoreOverrideAPI,
        language,
        t,
        isRTL,
      }}>
      {children}
    </VerificationContext.Provider>
  );
};

export const useMyStepsVerification = () => useContext(VerificationContext);
