import React, {
  forwardRef,
  useEffect,
  useMemo,
  useReducer,
  useRef,
  useState,
} from "react";
import {
  Text,
  TouchableOpacity,
  StyleSheet,
  View,
  Image,
  Alert,
  Switch,
  Platform,
} from "react-native";

import Colors from "../common/Colors";
import { SCREEN_HEIGHT, SCREEN_WIDTH } from "../common/Constants";
import Database from "../../../../Components/common/DAsyncStorage";
import { PrimaryButton, TextInput } from "../common/ThemedComponents";
import Orientation from "react-native-orientation";
import AnimationEaseLinear, { getStridesArr } from "./AnimationEaseLinear";
import ViewShot, { captureRef } from "react-native-view-shot";
import UploadFile from "react-native-digitcamera/src/Screens/UploadFile";
import Modal from "../common/Modal";
import InstructionsScreen from "./InstructionsScreen";
import Icon from "react-native-vector-icons/dist/FontAwesome";
import MIcon from "react-native-vector-icons/MaterialIcons";
import Steps from "react-native-digitcamera/src/Screens/Steps";
import style from "../../../../Components/common/CommonStyle";
import KeepAwake from "react-native-keep-awake";
import ProcessRawOutput from "react-native-digitcamera/src/Screens/ProcessRawOutput";
import NetInfo from "@react-native-community/netinfo";
import PopInstructions, {
  ACTION_TYPES,
  PI_DATA,
} from "react-native-digitcamera/src/Screens/PopInstructions";
const camera_shutter = require("../../src/common/Image/camera_shutter.png");

import { useSelector, useDispatch } from "react-redux";
import {
  UELogEvent,
  UELogMessage,
} from "../common/libEventLog/UserExperior/LibUserExperior";
import {
  eventOnMediaProceed,
  eventOnMediaRetry,
} from "react-native-digitcamera/src/Screens/Camera";
const iOS = Platform.OS === "ios";
export const zIndex_main_view = 100,
  zIndex_flash_torch = 124,
  zIndex_image_instruction = 125,
  zIndex_snapshot_preview_image = 150,
  zIndex_moving_thumbnail = 250,
  zIndex_bottom_instruction = 300,
  zIndex_steps_instruction = 312,
  zIndex_ml_output = 320,
  zIndex_stop_recording = 325,
  zIndex_flash_torchVDO = 326,
  zIndex_start_recording = 400,
  zIndex_close_bonnet = 450;
const RCB1 = "RCB1",
  RCB2 = "RCB2",
  DBD = "DBD",
  VDO = "VDO";
import {
  play,
  digitPreAudios,
  prepareAudioList,
  digitAudios_Gdd,
  digitAudios_nonGdd,
} from "react-native-digitcamera/src/common/DSound";
import { proceedCallback } from "react-native-digitcamera/src/Screens/Toturial";
import { offlinePIDataToRealm } from "react-native-digitcamera/src/Screens/OfflineFlow/CommonFunc";
import { ACTIVITY_TYPE_MOTOR_4W_OD_NB_PRE_INSPECTION_SELF_SURVEY } from "../common/Constants";
import { initMediaFile } from "react-native-digitcamera/src/Screens/SilentUploadV2/DatabaseHelpers";

export var sensorImageDetails = [];

export var NO_OF_POSES = 13; // 1 is width of thumbnail itself
const STEP_INSTRUCTION_COUNT = 19;
export var OBJ_WIDTH = Math.max(SCREEN_HEIGHT, SCREEN_WIDTH) / NO_OF_POSES;
const newPosePeriod = Math.max(SCREEN_HEIGHT, SCREEN_WIDTH) / NO_OF_POSES;
export var ANIMATION_TRACK = SCREEN_HEIGHT + SCREEN_HEIGHT * 0.1;
export var AUDIO_INSTRUCTIONS_ARR = [];
var ANIM_DURATION_nonGDD = 1.5 * 60 * 1000; // dummy
var ANIM_DURATION_GDD = 1 * 60 * 1000; // dummy
export var ANIM_DURATION = ANIM_DURATION_nonGDD;
// export const ANIM_DURATION = 2 * 6 * 1000 + 1 * 1000; // 10 sec extra
const EXTRA_TIME = 1 * 60 * 1000;
const HOLD_ON_TIME = 5000;
// const CLOSE_BONNET_TIMEOUT = 20 * 1000;
const CLOSE_BONNET_TIMEOUT = 0;
export var DURATION_PERIOD = ANIM_DURATION / NO_OF_POSES; // 19 is the no. of instructions coming from back end
export var WAITING_PERIOD = DURATION_PERIOD;
export var WAITING_PERIOD_PER_POSE_NON_PARALLEL_PROCESSING = DURATION_PERIOD;
export var DURATION_PERIOD_ARR = [];
export const expectedPoseData = {
  0: "CHP",
  1: "ECR",
  2: "FS",
  3: "FLC",
  4: "LS",
  5: "BLC",
  6: "BS",
  7: "BRC",
  8: "RS",
  9: "FRC",
  10: "FS",
  11: "WS",
  12: "DBD",
  13: "DBD", // index issue happening, not moving stride to last index
};
export const expectedPoseDataGDD = {
  0: "FS",
  1: "LS",
  2: "BS",
  3: "RS",
  4: "FS",
  5: "WS",
  6: "DBD", // index issue happening, not moving stride to last index
};
const PAUSE_PART_NAME = "Front Number plate";

var locationRetryCount = 0;

let onBonnetCloseCallback = null;
var isGdd = false;
var voice = true;
var audioCount = 1;
// POP INSTRUCTIONS

const POP_INSTRUCTION_DATA_TO_DISPATCH = PI_DATA.DATA;

export const StencilAnimation = forwardRef((props, multiRef) => {
  const {
    audioArrRef,
    rawOutputRef,
    pauseResumeRef,
    letsContinueAnimRef,
    voiceRef,
    flashRef,
  } = multiRef.current;
  const {
    instruction,
    toVDO,
    navigation,
    toggleTorch,
    flashState,
    voice,
    startScreenRecording,
    stopScreenRecording,
    supportsParallelVideoProcessing,
    processRawOutput,
    cameraRef,
    enableFrameProcessor,
  } = props;
  const recalculateValues = useMemo(() => {
    console.log("*** StencilAnimation recalculateValues useMemo");
    const getIsGDD = async () => {
      const vehicleDetails = await Database.get("PIVechicleData");
      const activtyTypeId = vehicleDetails?.activityTypeId;
      const strideArr = getStridesArr(instruction);
      console.log("*** StencilAnimation strideArr", strideArr);
      NO_OF_POSES = strideArr.length;
      if (NO_OF_POSES <= 0) {
        return;
      }
      OBJ_WIDTH = Math.max(SCREEN_HEIGHT, SCREEN_WIDTH) / NO_OF_POSES;
      if (
        activtyTypeId &&
        activtyTypeId == ACTIVITY_TYPE_MOTOR_4W_OD_NB_PRE_INSPECTION_SELF_SURVEY
      ) {
        // This is GDD
        isGdd = true;
        const { audioList, totalDuration } = await prepareAudioList(
          digitAudios_Gdd,
          isGdd
        );
        AUDIO_INSTRUCTIONS_ARR = audioList;
        console.log(
          "*** StencilAnimation GDD AUDIO_INSTRUCTIONS_ARR: ",
          AUDIO_INSTRUCTIONS_ARR
        );
        audioArrRef.current = audioList;
        ANIM_DURATION_GDD = totalDuration;
        ANIM_DURATION = ANIM_DURATION_GDD; // 13 is non GDD poses
        DURATION_PERIOD = ANIM_DURATION / NO_OF_POSES;
        WAITING_PERIOD = DURATION_PERIOD;
        const arr = [];
        audioList.map((item) => arr.push(item?.duration));
        console.log("*** StencilAnimation DURATION_PERIOD_ARR", arr);

        DURATION_PERIOD_ARR = arr;
        console.log("*** StencilAnimation NEW MAPPED_DURATION_PERIOD_ARR", arr);
      } else {
        isGdd = false;
        const { audioList, totalDuration } = await prepareAudioList(
          digitAudios_nonGdd,
          isGdd
        );
        AUDIO_INSTRUCTIONS_ARR = audioList;
        console.log(
          "*** StencilAnimation nonGDD AUDIO_INSTRUCTIONS_ARR: ",
          AUDIO_INSTRUCTIONS_ARR
        );
        audioArrRef.current = audioList;
        ANIM_DURATION_nonGDD = totalDuration;
        ANIM_DURATION = ANIM_DURATION_nonGDD;
        DURATION_PERIOD = ANIM_DURATION / NO_OF_POSES;
        WAITING_PERIOD = DURATION_PERIOD;
        const arr = [];
        audioList.map((item) => arr.push(item?.duration));

        DURATION_PERIOD_ARR = arr;
        console.log(
          "*** StencilAnimation DURATION_PERIOD_ARR",
          DURATION_PERIOD_ARR
        );
      }
    };
    getIsGDD();
  }, [cameraRef]);

  // const [pause, setPause] = useState(false)
  if (!supportsParallelVideoProcessing) {
    WAITING_PERIOD = WAITING_PERIOD_PER_POSE_NON_PARALLEL_PROCESSING;
  }
  const [easeAnimation, setEaseAnimation] = useState(true);
  const [startRecording, setStartRecording] = useState(false);
  const [disableStopVideoButton, setDisableStopVideoButton] = useState(true);
  var [currentLatitude, setCurrentLatitude] = useState("");
  var [currentLongitude, setCurrentLongitude] = useState("");
  const [imagePreview, setImagePreview] = useState(false);
  const [imagePreviewUri, setImagePreviewUri] = useState("");
  const [dateTime, setDateTime] = useState("");
  const [odometerReadings, setOdometerReadings] = useState("");
  const [isMoreRCB, setIsMoreRCB] = useState(false);
  const [instructionsModalVisible, setInstructionsModalVisible] = useState(
    false
  );
  const [shouldCloseTheBonnet, setShouldCloseTheBonnet] = useState(false);
  const [isInternetConnected, setIsInternetConnected] = useState(true);

  const [enableClickButton, setEnableClickButton] = useState(false);

  const viewShotRef = useRef();
  const dispatch = useDispatch();

  // const [enableRCBPreview, setEnableRCBPreview] = useState(false);

  // var instructionInDb = await Database.get("PIVechicleInstruction");
  var dbInstr = instruction;
  // if (__DEV__ && (dbInstr === undefined || dbInstr.length <= 0)) {
  // //   console.log("**** dbInstruction not available taking hard coded");
  // dbInstr = JSON.parse('[{"surveyStepsId":1053,"createdDate":"Feb 21, 2020 12:15:05 PM","isLast":false,"lastModifiedDate":"Feb 21, 2020 12:15:05 PM","stepAssests":"https://cdn.godigit.com/digitEdgeAssets/Motor/4W_PI_RCB1_V2.jpg","stepStencilAssests":"","stepTitle":"RC Book/Card","stepTitleHn":"आरसी बुक/कार्ड","imageName":"RCB1","displayOrder":160,"type":"image","TSurveyInstructions":[{"surveyInstructionsId":1740,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Take a picture of the front of your RC book/card.","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":1,"instructionDataHn":"अपनी आरसी बुक/कार्ड के सामने की तस्वीर लें।","displayOrder":1,"type":"","effectiveDate":"Aug 07, 2022 11:20:57 PM"}],"effectiveDate":"Dec 17, 2022 03:18:48 PM"},{"surveyStepsId":1054,"createdDate":"Feb 21, 2020 12:15:05 PM","description":"<b>Note:</b> Odometer reading indicates the <b>total distance the vehicle has travelled!</b> Please ensure the reading reflects that and is not set to display trip reading.","isLast":false,"descriptionHn":"सुनिश्चित करें कि ओडोमीटर किमी रीडिंग लेते समय इंजन चालू है","lastModifiedDate":"Feb 21, 2020 12:15:05 PM","stepAssests":"https://cdn.godigit.com/digitEdgeAssets/Motor/MZBG2T7_Odometer-01_V2.jpg","stepStencilAssests":"","stepTitle":"Please enter the odometer km reading","stepTitleHn":"कृपया ओडोमीटर किमी रीडिंग दर्ज करें","imageName":"DBD","displayOrder":205,"type":"input","TSurveyInstructions":[],"effectiveDate":"Dec 17, 2022 03:18:48 PM"},{"surveyStepsId":1055,"createdDate":"Feb 21, 2020 12:15:05 PM","description":"Shoot video from a distance to capture the entire vehicle","isLast":false,"descriptionHn":"पूरीगाड़ी को फ़ोकस करने के लिए दूर से वीडियो शूट करें","lastModifiedDate":"Feb 21, 2020 12:15:05 PM","stepAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/pi_demo_video_v1.mp4","stepStencilAssests":"","stepTitle":"Take a 360° video","stepTitleHn":"360 ° वीडियो लें \"","imageName":"VDO","displayOrder":220,"type":"video","TSurveyInstructions":[{"surveyInstructionsId":1742,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"We'll record inside the engine bay so make sure the bonnet is kept open.","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":3,"instructionDataHn":"हम इंजन बे के अंदर रिकॉर्ड करेंगे इसलिए सुनिश्चित करें कि बोनट खुला रखा गया है","displayOrder":16,"type":"image","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"Please open the bonnet of the car","okButtonText":"I have opened the bonnet","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/open_bonnet.png"},{"surveyInstructionsId":1743,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"The engine should be ON throughout the inspection.","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":3,"instructionDataHn":"पूरे निरीक्षण के दौरान इंजन चालू रहना चाहिए","displayOrder":17,"type":"image","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"Start your vehicle","okButtonText":"I have started the vehicle","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/key_start.png"},{"surveyInstructionsId":1744,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Take some time & locate your chassis number. Please make sure you find the <b>embossed chassis number</b> & not the sticker.","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":3,"instructionDataHn":"कुछ समय निकालें और अपना चेसिस नंबर खोजें","displayOrder":18,"type":"image","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"Find your chassis number","okButtonText":"I have found the chassis no.","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/chassis_find.png"},{"surveyInstructionsId":1745,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"What is embossed chassis no.?","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":19,"type":"image","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"What is embossed chassis no.?","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/embossed_chassis_video_pi.png"},{"surveyInstructionsId":1746,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"What is embossed chassis no.?","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":20,"type":"image","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"What is embossed chassis no.?","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/sticker_chassis_video_pi.png"},{"surveyInstructionsId":1747,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"<b>Embossed Chassis</b> visible on screen","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":22,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1748,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Look inside the <b>Engine Bay</b>","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":23,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1749,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"<b>Front Number plate & Front Windshield</b> senn","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":24,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1750,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Face the <b>Front Passenger Corner</b>","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":25,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1751,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"<b>Full Passenger-side</b> seen","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":26,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1752,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Face the <b>Back Passenger-side Corner</b>","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":27,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1753,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"<b>Back Number Plate & Back Windshield</b> seen","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":28,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1754,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Face <b>Back Driver-side Corner</b>","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":29,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1755,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"<b>Full Driver-side</b> seen","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":30,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1756,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Face <b>Front Driver-side Corner</b>","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":31,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1757,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Face the <b>Front of the car</b>","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":32,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1758,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Show <b>Full Windshield</b>","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":33,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1759,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"<b>Engine should be on NOW</b>","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":34,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":1760,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"<b>Show the Odometer reading</b>","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":35,"type":"instruction","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":""},{"surveyInstructionsId":2031,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":3,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"CHP","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_1.png"},{"surveyInstructionsId":2032,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":4,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"ECR","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_2.png"},{"surveyInstructionsId":2033,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":5,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"FS","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_3.png"},{"surveyInstructionsId":2034,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":6,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"FLC","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_4.png"},{"surveyInstructionsId":2035,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":7,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"LS","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_5.png\r\n"},{"surveyInstructionsId":2036,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":8,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"BLC","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/Car_angles_6.png"},{"surveyInstructionsId":2037,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":9,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"BS","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_7.png\r\n"},{"surveyInstructionsId":2038,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":10,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"BRC","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_8.png\r\n"},{"surveyInstructionsId":2039,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":11,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"RS","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_9.png\r\n"},{"surveyInstructionsId":2040,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":12,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"FRC","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_10.png\r\n"},{"surveyInstructionsId":2041,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":13,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"FS","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_11.png\r\n"},{"surveyInstructionsId":2042,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":14,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"WS","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_12.png\r\n"},{"surveyInstructionsId":2043,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":15,"type":"stride","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"DBD","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_13.png\r\n"},{"surveyInstructionsId":2044,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Make sure :<li>Bonnet is closed</li><li>All doors are closed</li>","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"displayOrder":21,"type":"image","effectiveDate":"Aug 07, 2022 11:20:57 PM","instructionTitle":"","okButtonText":"Ready!","instructionAssests":"https://d2h44aw7l5xdvz.cloudfront.net/CRM/PRM/car_angles_3.png"}],"effectiveDate":"Dec 17, 2022 03:18:48 PM"},{"surveyStepsId":1056,"createdDate":"Feb 21, 2020 12:15:05 PM","isLast":false,"lastModifiedDate":"Feb 21, 2020 12:15:05 PM","stepAssests":"https://cdn.godigit.com/digitEdgeAssets/Motor/4W_PI_RCB2_V2.jpg","stepStencilAssests":"","stepTitle":"RC Book/Card","stepTitleHn":"आरसी बुक/कार्ड","imageName":"RCB2","displayOrder":180,"type":"image","TSurveyInstructions":[{"surveyInstructionsId":1741,"createdDate":"Aug 07, 2022 11:20:57 PM","instructionData":"Take a picture of the back of your RC book/card.","lastModifiedDate":"Aug 07, 2022 11:20:57 PM","instructionTime":2,"instructionDataHn":"अपनी आरसी बुक/कार्ड के पीछे की तस्वीर लें।","displayOrder":2,"type":"","effectiveDate":"Aug 07, 2022 11:20:57 PM"}],"effectiveDate":"Dec 17, 2022 03:18:48 PM"}]');
  // } else {
  if (dbInstr !== undefined) {
    /*
     * For some reason StencilAnimation rerenders
     * so on thank you screen, instructions are deleted from realm
     *  and in StencilAnimation dbInstr is undefined
     *  so I have added the check so that app wont crash
     */
    dbInstr = JSON.parse(dbInstr);
  }
  // }
  var [instructionArr, setInstructionArr] = useState(dbInstr);
  console.log("*** StencilAnimatin instructionArr ", instructionArr);
  if (!instructionArr || instructionArr.length == 0) {
    Alert.alert(
      "Oops! ",
      "We are unable to fetch guiding instruction for you, please try again"
    );
    navigation.navigate("WithQuote");
    return null;
  }
  const originalState = instructionArr[0];
  const [instructionManager, moveToNextStencil] = useReducer(
    reducer,
    originalState
  );
  /*torch mode*/
  var posePeriodInterval = useRef();
  var animatedRef = useRef();
  var timeoutRef = useRef();
  var resumeTimerRef = useRef();
  var pauseTimerRef = useRef();
  var extraTimeRef = useRef();
  var nextStepRef = useRef();
  var prevStepRef = useRef();
  var resetStepRef = useRef();
  var moveNextRef = useRef(); // TensorFlow ML -> to move for checking next pose
  var mlCompleteRef = useRef();
  let pauseRef = useRef(false);
  var multiRefMl = useRef({
    moveNextRef,
    rawOutputRef,
    pauseResumeRef,
    letsContinueAnimRef,
    mlCompleteRef,
    nextStepRef,
    prevStepRef,
  });

  function reducer(state = originalState, action) {
    let newState;
    switch (action.type) {
      case "init":
        console.log("***** reducer init: ");
        newState = instructionArr[0];
        break;
      case "next":
        const oldIndex = instructionArr.findIndex(
          (obj) => obj.displayOrder === state.displayOrder
        );
        const nextIndex = oldIndex + 1;
        console.log("***** reducer next " + nextIndex);
        const newInstruction = instructionArr[nextIndex];
        newState = newInstruction;
        break;
      case "prev":
        const oldPrevIndex = instructionArr.findIndex(
          (obj) => obj.displayOrder === state.displayOrder
        );
        const nextPrevIndex = oldPrevIndex - 1;
        console.log("***** reducer prev " + nextPrevIndex);
        newState = instructionArr[nextPrevIndex];
        break;
      case "toImageName" /* @NEWORDER */:
        const newInstructions = instructionArr.find(
          (item) => item.imageName === action.payload
        );
        newState = newInstructions;
        break;
    }
    console.log("**** reducer returns: " + newState.imageName);
    return newState;
  }
  useEffect(() => {
    getLatLong();
    getTime();
  }, [instructionManager]);

  /*@NEWORDER*/
  /* Getting RCB data from redux to handle RCB Cases */
  const RCBDATA = useSelector((state) => state.rcbPreviewData);
  /* currentImage represents what photo is being taken, is it Front, Back or Other Pages. */
  const currentImage = RCBDATA.currentImage;

  /* Getting length of the extra images */
  const MoreRCBImages = RCBDATA.rcbPreviewData.filter(
    (item) => item.info === "RC More Pages"
  );

  useEffect(() => {
    Orientation.lockToLandscapeLeft();
    KeepAwake.activate();
    const myFun = async () => {
      await getInstructionsFromDb();
    };
    myFun();
    checkInternet();
    return () => {
      KeepAwake.deactivate();
    };
  }, [isInternetConnected]);

  useEffect(() => {
    setTimeout(() => {
      setEnableClickButton(true);
    }, 2000);
  }, []);
  const checkInternet = () => {
    NetInfo.fetch().then((state) => {
      if (state.isConnected) {
        setIsInternetConnected(true);
      } else {
        setIsInternetConnected(false);
      }
    });
  };
  // pose animation function
  const posePeriodIntervalFun = async () => {
    // This will manage moving stride/stencil position
    if (processRawOutput === false) {
      var strideCount = 1;
      const nextStencil = (duration) => {
        const timer = setTimeout(() => {
          clearTimeout(timer);
          console.log(
            "*** StencilAnimation setTimeout moveNextRef.current - !pauseRef.current - strideCount ",
            moveNextRef.current,
            !pauseRef.current,
            strideCount
          );
          if (moveNextRef.current && !pauseRef.current) {
            moveNextRef.current(strideCount);
            strideCount += 1;
          }
          if (strideCount < NO_OF_POSES) {
            nextStencil(
              pauseRef.current ? 1000 : DURATION_PERIOD_ARR[strideCount]
            ); // if paused execute continuosly without waiting for next cycle
          }
        }, duration);
      };
      nextStencil(DURATION_PERIOD_ARR[strideCount]);

      // Instruction Title displaying top right corner of screen
      const moveSteps = (count) => {
        const stepManager = nextStepRef.current();
      };
      const totalInstr = DURATION_PERIOD_ARR.length;
      var count = 1;
      const call = (duration) => {
        const timer = setTimeout(() => {
          clearTimeout(timer);
          if (nextStepRef.current && !pauseRef.current) {
            // Hotfix as Windshield instruction showing twice at the end before ODOMETER
            if (isGdd && count == totalInstr - 1) {
              moveSteps(count);
            }
            moveSteps(count);
            count += 1;
          }
          if (count < totalInstr) {
            call(pauseRef.current ? 1000 : DURATION_PERIOD_ARR[count]); // if paused execute continuosly without waiting for next cycle
          }
        }, duration);
      };
      call(DURATION_PERIOD_ARR[count]);

      // Audio Instruction playing
      const playTrack = (track) => {
        track.play((success) => {
          if (success) {
            track.release();
          } else {
          }
        });
      };
      const totalAudioCount = AUDIO_INSTRUCTIONS_ARR.length;
      // var audioCount = 1;
      const callAudio = (audio) => {
        if (audio) {
          const { track, duration } = audio;
          const newDuration = audioCount == 0 ? 0 : duration;
          const audioTimer = setTimeout(() => {
            clearTimeout(audioTimer);
            if (nextStepRef.current && !pauseRef.current) {
              console.log("*** StencilAnimation callAudio playing ", track);
              if (track && voice) {
                playTrack(track);
              }
              audioCount = audioCount + 1;
            } else {
              console.log("*** StencilAnimation callAudio NOT playing ", track);
            }
            if (audioCount < totalAudioCount) {
              const audio = pauseRef.current
                ? { track: undefined, duration: 1000 }
                : AUDIO_INSTRUCTIONS_ARR[audioCount];
              callAudio(audio); // if paused execute continuosly without waiting for next cycle
            }
          }, newDuration);
        }
      };
      const { track, duration } = AUDIO_INSTRUCTIONS_ARR[0];
      playTrack(track);
      callAudio(AUDIO_INSTRUCTIONS_ARR[audioCount]);
    }
    // new all in sync
    // var index = 0;
    // var audioCount = AUDIO_INSTRUCTIONS_ARR.length;
    // const nextStencilAudioAndInstruction = (audio) => {
    //    const {track, duration} = audio ? audio : {track:undefined, duration:1000};
    //    const newDuration = (index == 0 ? 0 : duration);
    //     const timer = setTimeout(() => {
    //       clearTimeout(timer);

    //         if (!pause) {
    //           if(processRawOutput === false && moveNextRef.current){ // next stencil
    //             moveNextRef.current(index);
    //           }
    //           moveSteps(index); // next instruction
    //           track.play((success) => { // next audio
    //             if (success) {
    //               track.release();
    //             } else {
    //             }
    //           })
    //           index += 1;
    //         }
    //         if (index < audioCount) {
    //           nextStencilAudioAndInstruction(AUDIO_INSTRUCTIONS_ARR[index]);
    //         }
    //   }, newDuration);
    // };
    // nextStencilAudioAndInstruction(AUDIO_INSTRUCTIONS_ARR[index]);

    return posePeriodInterval.current;
  };

  const getInstructionsFromDb = async () => {
    console.log("**** getInstructionFromDb: " + instructionArr);

    if (toVDO !== undefined && toVDO) {
      toImageName("VDO");
    } else if (currentImage === "RCB1") {
      //   /*
      //     By getting RCB data from redux
      //     I'll know which images have been captured
      //     so that if whichever is missing toImageName(imageName) will
      //     show instruction about it.

      //     I'll also be using length of the total extra rcbook/card images
      //     to name the same.
      //   */
      toImageName("RCB1");
    } else if (currentImage === "RCB2") {
      toImageName("RCB2");
    } else if (currentImage === "MORE") {
      setIsMoreRCB(true);
      toImageName("RCB1");
    }

    // nextStencil("init");
  };
  const nextStencil = (instructionType = "next") => {
    moveToNextStencil({ type: instructionType });
  };

  const prevStencil = (instructionType = "prev") => {
    moveToNextStencil({ type: instructionType });
  };

  /* @NEWORDER */
  const toImageName = (imageName) => {
    moveToNextStencil({ type: "toImageName", payload: imageName });
  };

  const imageInstructionTop = (instruction) => {
    return (
      <View style={styles.topInstructionView}>
        <Text style={styles.topInstructionText}>{instruction.stepTitle}</Text>
      </View>
    );
  };

  const instructionWithImage = (instruction) => {
    return (
      <View style={styles.instructionImageView}>
        {imageInstructionTop(instruction)}
        <Image
          key={instruction.displayOrder}
          style={styles.stencilStyle}
          resizeMode="stretch"
          source={{ uri: instruction.stepAssests }}
        />
        {true && (
          <TextInput
            returnKeyType="done"
            keyboardType={"number-pad"}
            style={{ flex: 0.2, marginHorizontal: 5, marginVertical: 5 }}
            label={"Enter Odometer Reading (in Km)"}
            value={"" + odometerReadings}
            onChangeText={(value) => {
              setOdometerReadings(value);
            }}
            errorMsge={""}
          />
        )}
        {imageInstructionBottom(instruction)}
      </View>
    );
  };

  const imageInstructionBottom = (instruction) => {
    return (
      <View style={styles.bottomInstructionView}>
        <Text style={styles.bottmInstructionText}>{instruction.stepTitle}</Text>
        <PrimaryButton
          style={styles.bottomInstructionButton}
          disabled={false}
          onPress={() => {
            getButtonAction(instruction)();
          }}
        >
          {getButtonName(instruction)}
        </PrimaryButton>
      </View>
    );
  };

  const onRetryCallback = ({ uri, DocumentImageName }) => {
    // UELogEvent("StencilAnimation. onRetryCallback. ", {
    //   "URI": JSON.stringify(uri),
    //   "DocumentImageName": JSON.stringify(DocumentImageName)
    // })
    if (
      DocumentImageName === RCB1 ||
      DocumentImageName === RCB2 ||
      DocumentImageName === DBD
    ) {
    } else if (DocumentImageName === VDO) {
    }
  };

  const onProceedCallback = async (uri, DocumentImageName) => {
    if (isInternetConnected) {
      if (
        DocumentImageName === RCB1 ||
        DocumentImageName === RCB2 ||
        DocumentImageName === DBD ||
        (DocumentImageName && DocumentImageName.includes("RCB"))
      ) {
        console.log("**** ProceedCallback if UploadFile: " + DocumentImageName);
        initMediaFile(uri, DocumentImageName, ext, "pending", () => {});
        // UploadFile(
        //   uri,
        //   DocumentImageName,
        //   ".jpg",
        //   () => {
        //     navigation.navigate("WithQuote");
        //   },
        //   () => {
        //     addSensorImageData(".jpg", true, DocumentImageName);
        //   },
        //   () => {
        //     addSensorImageData(".jpg", true, DocumentImageName);
        //   }
        // );
        nextStencil("next");
      } else if (DocumentImageName === VDO) {
        // ***** IMPORTANT *******
        // this Logic is written in Camera.js
        // considering VDO is last file else we can check array[array.length-1] is last doc.
        // UELogEvent("StencilAnimation. ProceedCallback if UploadFile",
        //   {
        //     "DocumentImageName": JSON.stringify(DocumentImageName)
        //   })
        console.log(
          "**** ProceedCallback else before UploadFile: " + DocumentImageName
        );
        navigation.navigate("VideoPIProgress");
        UploadFile(
          uri,
          DocumentImageName,
          ".mp4",
          () => {
            navigation.navigate("WithQuote");
          },
          () => {
            var ext = DocumentImageName == "VDO" ? ".mp4" : ".jpg";
            addSensorImageData(ext, true, DocumentImageName);
          },
          () => {
            var ext = DocumentImageName == "VDO" ? ".mp4" : ".jpg";
            addSensorImageData(ext, false, DocumentImageName);
          }
        );
        console.log(
          "**** ProceedCallback after UploadFile: " + DocumentImageName
        );
        console.log(
          "**** ProceedCallback after navigate Progress: " + DocumentImageName
        );
      }
    } else {
      var ext = DocumentImageName == "VDO" ? ".mp4" : ".jpg";
      initMediaFile(uri, DocumentImageName, ext, "pending", () => {});
      offlinePIDataToRealm(false);
    }
  };

  const addSensorImageData = async (ext, ImageStatus, DocumentImageName) => {
    const PIRetryCount = await Database.get("PIRetryCount");
    const PIVechicleData = await Database.get("PIVechicleData");
    const PILocation = await Database.get("PILocation");

    var attemptCount = PIRetryCount?.retryCount + 1;
    var activityId = PIVechicleData?.activityId;
    var fileName = activityId + "_" + DocumentImageName + ext;
    const latitude = PILocation?.lat;
    const longitude = PILocation?.long;

    //adding sensor data
    sensorImageDetails.push({
      attemptCount: attemptCount,
      fileName: fileName,
      latitude: latitude,
      longitude: longitude,
      pose: DocumentImageName,
      success: ImageStatus,
      timestamp: new Date().getTime(),
    });
    dispatch({
      type: "SENSOR_DETAILS",
      payload: sensorImageDetails,
    });
  };

  const goToPreviewMedia = (uri, documentImageName) => {
    navigation.navigate("PreviewMedia", {
      uri: uri,
      DocumentImageName: documentImageName,
      OnRetry: onRetryCallback,
      OnProceed: onProceedCallback,
    });
  };

  const getButtonAction = (instruction) => {
    if (instruction.imageName === RCB1 || instruction.imageName === RCB2) {
      const takeSnapshot = async () => {
        var data;
        const options = {
          quality: 100,
          skipMetadata: true,
          flash: flashState ? "on" : "off",
        };
        try {
          if (iOS) {
            data = await cameraRef.current.takePhoto(options);
          } else {
            data = await cameraRef.current.takeSnapshot(options);
          }
        } catch (error) {
          console.log("*** StencilAnimation takeSnapshot: ", error);
        }
        console.log(
          "*** StencilAnimation takeSnapshot after takePictureAsync: " +
            data.path
        );
        setImagePreview(true);
        setImagePreviewUri(
          iOS ? data.path.replace("file://", "") : "file://" + data.path
        );
        // Alert.alert("Uri", data.uri);
        console.log("*** takeSnapshot before captureRef");
        const captureTimeout = setTimeout(() => {
          clearTimeout(captureTimeout);
          captureRef(viewShotRef, {
            format: "jpg",
            quality: 0.8,
          }).then(
            (uri) => {
              // UELogEvent("StencilAnimation. captureRef, uri", {
              //   "uri": JSON.stringify(uri)
              // })
              console.log("*** takeSnapshot in then captureRef: " + uri);
              setImagePreview(false);
              /* @RCB 
                  changing DocumentImageName when there will be Extra RC Book/Card Images
                  I'll be using length of the array of extra images which will determine
                  each image number.
                  so if array is empty I'll using 3 suffix to RCB
                  because there are already two RCB Images.
                  so DocumentImageName = RCB3 if length is 0

                  isMoreRCB checks if we are capturing extra photos
                  it will true if so.
                */
              let imageName = instruction.imageName;
              if (isMoreRCB) {
                imageName = `RCB${MoreRCBImages.length + 3}`;
              }
              goToPreviewMedia(uri, imageName);
            },
            (error) => {
              // UELogEvent("StencilAnimation. getButtonAction, error", {
              //   "error": JSON.stringify(error)
              // })
              console.log("*** takeSnapshot in error captureRef: " + error);
              // Alert.alert("ViewShot Uri Error", "" + error);
              setImagePreview(false);
            }
          );
        }, 700);
      };
      return takeSnapshot;
    } else if (instruction.imageName === VDO) {
      return stopScreenRecordingCallback;
    } else if (instruction.imageName === DBD) {
      const getODO = async () => {
        if (odometerReadings === undefined || odometerReadings.length <= 0) {
          Alert.alert("Enter valid readings");
          return;
        }
        savaDataToRealm(odometerReadings);
        nextStencil("next");
      };
      return getODO;
    } else {
      return () => {
        Alert.alert(
          "Oops!",
          "We are unable to take picture for " + instruction?.imageName
        );
      };
    }
  };
  const savaDataToRealm = async (value) => {
    console.log("**** saveDataToRealm Odometer: " + value);
    console.log("**** saveDataToRealm before Odometer: " + value);
    await Database.update("PIOdometerData", {
      readings: value,
    });
    const odo = await Database.get("PIOdometerData");
    console.log("**** saveDataToRealm after Odometer: " + JSON.stringify(odo));
  };

  const getButtonName = (instruction) => {
    if (instruction.imageName === RCB1 || instruction.imageName === RCB2) {
      return "Capture";
    } else if (instruction.imageName === VDO) {
      return "Stop";
    } else if (instruction.imageName === DBD) {
      return "Submit";
    }
    return "Next";
  };

  const getLatLong = async () => {
    const PILocation = await Database.get("PILocation");
    const latitude = PILocation?.lat;
    const longitude = PILocation?.long;
    if (
      locationRetryCount < 2 &&
      (latitude === undefined || longitude === undefined)
    ) {
      locationRetryCount += 1;
      Alert.alert(
        "Turn Off/On Location",
        "Oops! We are not able to fetch your location details. Please try again after turning Off and then On."
      );
      return;
    } else {
      setCurrentLatitude(latitude);
      setCurrentLongitude(longitude);
    }
  };

  // for gatting time
  const getTime = () => {
    const date = new Date().getDate();
    const month = new Date().getMonth() + 1;
    const year = new Date().getFullYear();

    //Time calulation for the display on preciew Screen
    const hour = new Date().getHours();
    const minute = new Date().getMinutes();
    const seconds = new Date().getSeconds();
    setDateTime(
      date +
        "/" +
        month +
        "/" +
        year +
        " - " +
        hour +
        ":" +
        minute +
        ":" +
        seconds
    );
  };

  const getVoiceIcon = () => {
    const voiceIcon = voice ? "volume-off" : "record-voice-over";
    return (
      <TouchableOpacity
        style={{ marginVertical: 10, marginHorizontal: 8 }}
        onPress={() => {
          var newVoice = !voice;
          if (voiceRef) {
            voiceRef.current(newVoice);
          }
        }}
      >
        <MIcon
          name={voiceIcon}
          size={30}
          color={Colors.white}
          style={{
            backgroundColor: "transparent",
          }}
        />
      </TouchableOpacity>
    );
  };

  const getFlashAndVoiceIcon = () => {
    return (
      <View
        style={{
          height: "45%",
          justifyContent: "flex-end",
          flexDirection: "column",
        }}
      >
        {getFlashView()}
        {/* Voice Icon should only render here when AI is on, otherwise it should go below the */}
        {/* {!enableFrameProcessor && getVoiceIcon()} */} // for hidding the
        icon currently we disabled this
      </View>
    );
  };

  const getStopVideoInstruction = (instruction) => {
    const imageName = instruction?.imageName;
    if (imageName === VDO) {
      return (
        <View style={styles.stopVideoInstructionView}>
          <View style={{}}>
            <TouchableOpacity
              onPress={() => {
                if (!disableStopVideoButton) {
                  stopScreenRecordingCallback(true);
                  /* only able to turn off the torch at the end */
                  if (
                    toggleTorch !== undefined &&
                    flashState !== undefined &&
                    flashState
                  ) {
                    toggleTorch();
                  }
                }
              }}
            >
              <Icon
                name="stop-circle-o"
                size={48}
                color={disableStopVideoButton ? Colors.inactiveText : "red"}
                style={{
                  backgroundColor: "transparent",
                  paddingHorizontal: 5,
                }}
              />
            </TouchableOpacity>
            {/* {!enableFrameProcessor && getVoiceIcon()} */}
          </View>
        </View>
      );
    } else {
      return null;
    }
  };

  const getStepVideoInstruction = (instruction) => {
    const imageName = instruction?.imageName;
    if (imageName === VDO) {
      return (
        <Steps
          navigation={navigation}
          nextStepCallback={nextStepRef}
          prevStepCallback={prevStepRef}
          resetCallback={resetStepRef}
          instructionArr={instructionArr}
          shouldDispatchNow={!startRecording}
        />
      );
    } else {
      return null;
    }
  };

  const Instruction = (instruction) => {
    const title = instruction?.TSurveyInstructions[0]?.instructionData;
    const imageName = instruction?.imageName;
    if (imageName !== VDO) {
      return (
        <View style={styles.instructionViewMain}>
          <View style={styles.instructionView}>
            <Text style={styles.instructionText}>
              {isMoreRCB
                ? "Take a picture of the other pages of the RC book/card"
                : title}
            </Text>
            {false && (
              <PrimaryButton
                style={styles.instructionButton}
                disabled={false}
                onPress={() => {
                  getButtonAction(instruction)();
                }}
              >
                {getButtonName(instruction)}
              </PrimaryButton>
            )}
          </View>
          <View style={styles.dateTimeView}>
            <Text style={styles.instructionDateTimeText}>
              {"Lat:" +
                " " +
                currentLatitude +
                "  " +
                "Lon:" +
                "  " +
                currentLongitude +
                "  " +
                "    |    " +
                "Digit App" +
                "    |    " +
                dateTime}
            </Text>
          </View>
        </View>
      );
    } else {
      return null;
    }
  };

  const isInstructionWithImage = (instruction) => {
    if (instruction == undefined) {
      return false;
    }
    if (instruction.type === "input" || instruction.imageName === DBD) {
      return true;
    } else if (
      instruction.type === "image" &&
      (instruction.imageName === RCB1 || instruction.imageName === RCB2)
    ) {
      return false;
    } else {
      return false;
    }
  };

  const startVideo = () => {
    console.log(
      "**************************** startVideo ************************************************"
    );
    if (startScreenRecording) {
      setDisableStopVideoButton(true);
      // posePeriodIntervalFun();
      console.log("*** 0 startAnim before start");
      const res = startScreenRecording(flashState ? "on" : "off");
      console.log("*** 1 startAnim after start ", res);
      // if (res && animatedRef.current !== undefined) {
      if (res) {
        // const holdOn = setTimeout(() => {
        //   clearTimeout(holdOn);
        posePeriodIntervalFun();
        // animatedRef.current[0].start(() => {
        //   console.log("*** startAnim animation finished");
        // });
        console.log("**** 2 startVideo Animation started");
        const [pauseTimer, resumeTimer] = Timer(() => {
          // Video recording main timeout
          pauseTimerRef.current();
          console.log("*** 4 startAnim animation timeout finished");
          stopScreenRecordingCallback(false);
        }, ANIM_DURATION);
        resumeTimerRef.current = resumeTimer;
        pauseTimerRef.current = pauseTimer;
        // }, HOLD_ON_TIME);
      } else {
        setStartRecording(true);
        Alert.alert(error?.message);
      }

      if (res) {
        console.log(
          "StencilAnimtion startCameraRecording, camera recording started."
        );
        return true;
      } else {
        return false;
      }
    }
  };
  const stopCameraRecording = () => {
    console.log("StencilAnimation stopCameraRecording.");
    myCamera.stopRecording();
  };

  const StartRecordingMainView = () => {
    return (
      <View style={styles.startRecordingView}>
        <View style={styles.startRecordingSubView}>
          <Text style={styles.textTitle}>Please be near chassis number</Text>
          <View style={styles.lineView} />
          <PrimaryButton
            style={styles.startRecordingButton}
            onPress={() => {
              /* I have moved setEaseLinear(true) to dismiss of the instructionModal */
              setStartRecording(false);
              startVideo();
            }}
          >
            {"Start Recording"}
          </PrimaryButton>
          <Text style={styles.textSubTitle}>
            If you exit in the middle of the video shoot you will have to start
            again.
          </Text>

          {/* adding flash support */}
          <View
            style={{
              flexDirection: "row",
              alignItems: "center",
              alignSelf: "center",
            }}
          >
            <Text style={[style.muliBoldDB, { color: Colors.white }]}>
              Flash {flashState !== undefined && flashState ? "On" : "Off"}
            </Text>
            {getFlashView()}
          </View>
        </View>
      </View>
    );
  };

  useEffect(() => {
    // if (instructionManager.imageName === RCB1) {
    //   setEnableRCBPreview(true);
    // } else {
    //   setEnableRCBPreview(false);
    // }
    if (instructionManager.imageName === VDO) {
      setStartRecording(true);
      setInstructionsModalVisible(true);
      setDisableStopVideoButton(true);
      // setInstructionsModalVisible(false);
    } else {
      setStartRecording(false);
      setEaseAnimation(false);
      setInstructionsModalVisible(false);
    }
  }, [instructionManager.imageName]);

  const stopIt = async () => {
    // if(animatedRef.current){
    //   clearTimeout(animatedRef.current)
    // }
    if (extraTimeRef.current) {
      clearTimeout(extraTimeRef.current);
    }
    if (posePeriodInterval.current) {
      clearInterval(posePeriodInterval.current);
    }
    if (resetStepRef.current) {
      resetStepRef.current();
    }
    if (stopScreenRecording) {
      console.log("*** 6 startAnim animation finished");
      await stopScreenRecording();
      setStartRecording(true);
      audioCount = 1;
    }
    /* only able to turn off the torch at the end */
    console.log("^^^^^ TORCH STATE ^^^^", flashState);
    if (toggleTorch !== undefined && flashState !== undefined && flashState) {
      console.log("^^^ TORCH OFF ^^^^");
      toggleTorch();
    }
    setDisableStopVideoButton(true);
  };

  const stopScreenRecordingCallback = (userStopped = true) => {
    if (userStopped) {
      // UELogEvent("StencilAnimation. stopScreenRecordingCallback, user stopped the recording.");
      console.log("*** 5 stopAnim  user finished");
      stopIt();
    } else {
      // UELogEvent("StencilAnimation. stopScreenRecordingCallback, auto stopped the recording.");

      setDisableStopVideoButton(false);
      extraTimeRef.current = setTimeout(() => {
        // allow extra time once ANIM_DURATION finish
        console.log("*** or 5 stopAnim extra timeout finished");
        stopIt();
      }, EXTRA_TIME);
    }
  };

  mlCompleteRef.current = stopScreenRecordingCallback; // controls in AnimationEaseLinear

  const InstructionsScreenModal = () => {
    return (
      <InstructionsScreen
        startRecording={() => {
          /* Stencil Animation re-render if this easeAnimation set true,
              it would set all the state params to their default values hence the 
              camera recording was not starting.
              I am rendering the AnimationEaseLinear component on dismiss of this modal
              so that the values of states should not reset
              */
          setEaseAnimation(true); // Logic to just change the status,
          setInstructionsModalVisible(false);
        }}
        // instruction={instruction} // **&&&
        instruction={JSON.stringify(dbInstr)}
        shouldCloseTheBonnet={shouldCloseTheBonnet}
        onCloseCallback={() => {
          onBonnetCloseCallback();
        }}
      />
    );
  };

  const CloseBonnetModalShow = () => {
    return (
      <View>
        <Modal
          isVisible={true}
          headerImageVisible={false}
          shouldHeaderVisible={false}
        >
          <CloseBonnetModal
            onPress={() => {
              console.log(
                "($) StencilAnimation on press of close bonnet",
                onBonnetCloseCallback
              );
              onBonnetCloseCallback();
            }}
          />
        </Modal>
      </View>
    );
  };

  var Timer = (callback, delay) => {
    var timerId,
      start,
      remaining = delay;

    const pauseTimer = () => {
      clearTimeout(timerId);
      timerId = null;
      remaining -= Date.now() - start;
      return remaining;
    };

    const resumeTimer = () => {
      if (timerId) {
        return;
      }
      start = Date.now();
      timerId = setTimeout(callback, remaining);
    };
    resumeTimer();
    return [pauseTimer, resumeTimer];
  };

  const getFlashView = () => {
    return (
      <TouchableOpacity
        style={styles.flashIconButtonSurface}
        onPress={() => {
          if (toggleTorch !== undefined) {
            toggleTorch();
          }
        }}
      >
        <MIcon
          name={!flashState ? "flash-on" : "flash-off"}
          size={30}
          color={Colors.white}
          style={{ backgroundColor: "transparent", paddingHorizontal: 5 }}
        />
      </TouchableOpacity>
    );
  };

  const getCaptureImageButton = (instruction) => {
    return (
      <TouchableOpacity
        style={{ marginVertical: "10%" }}
        onPress={() => {
          getButtonAction(instruction)();
        }}
      >
        <Image source={camera_shutter} style={styles.captureImage} />
      </TouchableOpacity>
    );
  };

  const getFlashButton = (instruction) => {
    const imageName = instruction?.imageName;
    if (imageName === RCB1 || imageName === RCB2) {
      return (
        <View style={styles.flashView}>
          {getFlashView()}
          {getCaptureImageButton(instruction)}
        </View>
      );
    } else {
      return null;
    }
  };

  const PopInstructionsOverlay = () => {
    if (instructionManager.imageName === VDO) {
      return (
        <PopInstructions
          isGdd={isGdd}
          animate={true}
          continueAnimation={() => {
            continueAnimation();
          }}
          pauseAnimation={() => {
            pauseAnimation();
          }}
        />
      );
    }
    return null;
  };

  const pauseAnimation = () => {
    pauseRef.current = true;
    if (pauseResumeRef && pauseResumeRef.current) {
      pauseResumeRef.current("pause");
    }
    console.log(
      "*** StencilAnimation pauseAnimation pauseRef.current ",
      pauseRef.current
    );
    if (pauseTimerRef && pauseTimerRef.current) {
      pauseTimerRef.current();
    }
  };

  const playTrack = (track) => {
    track.play((success) => {
      if (success) {
        track.release();
      } else {
      }
    });
  };

  const continueAnimation = () => {
    pauseRef.current = false;
    if (pauseResumeRef && pauseResumeRef.current) {
      pauseResumeRef.current("resume");
    }
    console.log(
      "*** StencilAnimation pauseAnimation pauseRef.current continue",
      pauseRef.current
    );
    if (!isGdd) {
      if (
        audioCount == 1 ||
        audioCount == 2 ||
        audioCount == 3 ||
        audioCount == 12
      ) {
        // skipping audio, hence applying this logic
        const { track, duration } = AUDIO_INSTRUCTIONS_ARR[audioCount];
        playTrack(track);
        if (audioCount == 3) {
          setTimeout(() => {
            playTrack(AUDIO_INSTRUCTIONS_ARR[4].track);
          }, 6000);
        }
        console.log(
          "*** StencilAnimation continueAnimation [skipped] track ",
          track
        );
      }
      if (audioCount == 3) {
        audioCount = 4;
        console.log(
          "*** StencilAnimation continueAnimation [skipped] fast forwarding to ",
          audioCount
        );
      }
    }
    if (resumeTimerRef && resumeTimerRef.current) {
      resumeTimerRef.current();
    }
  };

  return (
    <ViewShot style={styles.mainView} ref={viewShotRef}>
      <View style={styles.mainView}>
        {easeAnimation && (
          <AnimationEaseLinear
            onAnimationFinish={() => {}}
            instruction={instruction}
            ref={multiRefMl}
          />
        )}
        {/* {isInstructionWithImage(instructionManager) &&
          instructionWithImage(instructionManager)} */}
        {!isInstructionWithImage(instructionManager) &&
          Instruction(instructionManager)}
        {/* {!isInstructionWithImage(instructionManager) &&
          enableRCBPreview &&
          goToRCBPreview(instructionManager)} */}
        {imagePreview && (
          <Image
            key={instructionManager.displayOrder}
            style={styles.previewImageView}
            resizeMode="cover"
            source={{ uri: imagePreviewUri }}
          />
        )}
        {startRecording && StartRecordingMainView()}
        {getStopVideoInstruction(instructionManager)}
        {!imagePreview &&
          enableClickButton &&
          getFlashButton(instructionManager)}
        {getStepVideoInstruction(instructionManager)}
        {processRawOutput && (
          <ProcessRawOutput voice={voice} isGdd={isGdd} ref={multiRefMl} />
        )}
        {instructionsModalVisible && InstructionsScreenModal()}
        {!startRecording && PopInstructionsOverlay()}
      </View>
    </ViewShot>
  );
});

const styles = StyleSheet.create({
  mainView: {
    flex: 1,
    height: "100%",
    zIndex: zIndex_main_view,
    width: "100%",
    position: "absolute",
    backgroundColor: "transparent",
    justifyContent: "flex-end",
  },
  previewImageView: {
    position: "absolute",
    zIndex: zIndex_snapshot_preview_image,
    width: "100%",
    alignSelf: "center",
    height: "100%",
    backgroundColor: "transparent",
  },
  instructionImageView: {
    flex: 1,
    zIndex: zIndex_image_instruction,
    marginHorizontal: "20%",
    flexDirection: "column",
    justifyContent: "center",
    backgroundColor: "white",
  },
  stencilStyle: {
    flex: 0.6,
    width: "100%",
    alignSelf: "center",
    height: "100%",
    backgroundColor: "transparent",
  },
  instructionViewMain: {
    height: "100%",
    width: "100%",
    zIndex: zIndex_bottom_instruction,
    flexDirection: "column",
    justifyContent: "space-between",
    backgroundColor: "transparent",
  },
  dateTimeView: {
    flex: 0.1,
    height: "100%",
    width: "100%",
    flexDirection: "row",
    justifyContent: "flex-start",
    backgroundColor: "transparent",
  },
  instructionView: {
    flex: 0.1,
    height: "100%",
    width: "100%",
    flexDirection: "row",
    justifyContent: "flex-start",
    backgroundColor: "transparent",
  },
  stopVideoInstructionView: {
    position: "absolute",
    height: "100%",
    top: 0,
    bottom: 0,
    right: 0,
    flexDirection: "column",
    zIndex: zIndex_stop_recording,
    // width: "100%",
    alignItems: "center",
    justifyContent: "center",
  },
  flashView: {
    position: "absolute",
    justifyContent: "center",
    alignItems: "center",
    top: 0,
    bottom: 0,
    right: 0,
    zIndex: zIndex_flash_torchVDO,
  },
  flashViewVDO: {
    position: "absolute",
    justifyContent: "center",
    alignItems: "center",
    top: "18%",
    right: 0,
    zIndex: zIndex_flash_torchVDO,
  },
  flashIconButtonSurface: {
    justifyContent: "center",
    alignItems: "center",
    marginVertical: 10,
  },
  instructionText: {
    flex: 0.8,
    color: "white",
    alignSelf: "center",
    marginLeft: 10,
    fontFamily: "Muli-Bold",
    fontSize: 18,
  },
  instructionDateTimeText: {
    color: "white",
    marginLeft: 10,
    fontFamily: "Muli-Regular",
    fontSize: 18,
  },
  instructionButton: {
    flex: 0.2,
    height: "10%",
    marginRight: 10,
    alignSelf: "center",
  },
  bottomInstructionView: {
    flex: 0.2,
    height: "15%",
    width: "100%",
    flexDirection: "row",
    justifyContent: "center",
    backgroundColor: "white",
  },
  bottmInstructionText: {
    flex: 0.7,
    color: "black",
    alignSelf: "center",
    marginLeft: 10,
    fontFamily: "Muli-Bold",
  },
  bottomInstructionButton: {
    flex: 0.3,
    height: "10%",
    marginRight: 10,
    alignSelf: "center",
  },
  topInstructionView: {
    flex: 0.2,
    width: "100%",
    height: "100%",
    justifyContent: "center",
    backgroundColor: "white",
  },
  topInstructionText: {
    color: "black",
    alignSelf: "flex-start",
    marginLeft: 10,
    fontFamily: "Muli-Bold",
  },
  startRecordingView: {
    position: "absolute",
    zIndex: zIndex_start_recording,
    width: "100%",
    height: "100%",
    justifyContent: "center",
    backgroundColor: "transparent",
  },
  startRecordingSubView: {
    width: "60%",
    height: "60%",
    alignSelf: "center",
    borderRadius: 10,
    justifyContent: "center",
    backgroundColor: "rgba(0, 0, 0, 0.8)",
  },
  textTitle: {
    color: "white",
    fontSize: 12,
    fontFamily: "Muli-Bold",
    paddingHorizontal: 10,
    alignSelf: "center",
  },
  textSubTitle: {
    color: Colors.inactiveText,
    fontSize: 10,
    fontFamily: "Muli-Regular",
    alignSelf: "center",
    paddingHorizontal: 10,
    marginVertical: 5,
  },
  lineView: {
    width: "80%",
    height: 0.5,
    marginVertical: 10,
    backgroundColor: Colors.inactiveText,
    alignSelf: "center",
  },
  startRecordingButton: {
    width: "50%",
    height: "10%",
    alignSelf: "center",
  },
  captureImage: {
    width: 56,
    height: 56,
    backgroundColor: "black",
    resizeMode: "contain",
  },
});

export default {
  StencilAnimation,
  ANIM_DURATION,
  DURATION_PERIOD,
  NO_OF_POSES,
  OBJ_WIDTH,
  ANIMATION_TRACK,
};
