import React, { useState, useEffect, useRef } from "react";
import {
  ScrollView,
  StyleSheet,
  Text,
  View,
  Image,
  StatusBar,
  TouchableOpacity,
  Platform,
  PermissionsAndroid,
  BackHandler,
  Alert,
} from "react-native";
import {
  SCREEN_WIDTH,
  SCREEN_HEIGHT,
  SELFI_IMAGE,
  VIDEO_TITLE_HN,
  VIDEO_TITLE,
  SELFI_IMAGE_HN,
} from "../common/Constants";
import Colors from "../common/Colors";
import { RNCamera } from "react-native-camera";
import Orientation from "../../../react-native-orientation";
import reactotron from "reactotron-react-native";
import { translate } from "react-native-digitcamera/src/common/localize/i18n";
import DeviceInfo from "react-native-device-info";
import { SafeAreaView } from "react-native-safe-area-context";
import ViewShot, { captureRef } from "react-native-view-shot";
import UploadFile from "react-native-digitcamera/src/Screens/UploadFile";
import Database from "../../../../Components/common/Database";

let realm = Database.getRealm();
var PIRetryCount = realm.objects("PIRetryCount");
var PIVechicleData = realm.objects("PIVechicleData");
import {
  accelerometer,
  gyroscope,
  magnetometer,
  gravity,
  setUpdateIntervalForType,
  SensorTypes,
} from "react-native-sensors";
const iOS = Platform.OS === "ios";
import { ProgressBar } from "react-native-paper";
import BackgroundTimer from "react-native-background-timer";
import { StencilAnimation, sensorImageDetails } from "./StencilAnimation";
import RecordScreen from "react-native-record-screen";
import {
  UELogEvent,
  UELogMessage,
} from "../common/libEventLog/UserExperior/LibUserExperior";
import { async } from "validate.js";
import { useDispatch } from "react-redux";
const camera_shutter = require("../../src/common/Image/camera_shutter.png");
const left_bottom = require("../../src/common/Image/left_bottom.png");
const left_top = require("../../src/common/Image/left_top.png");
const right_bottom = require("../../src/common/Image/right_bottom.png");
const right_top = require("../../src/common/Image/right_top.png");
const start_recording = require("../../src/common/Image/start_recording.png");
const stop_recording = require("../../src/common/Image/stop_recording.png");
const flashOn = require("../../src/common/Image/flash_on.png");
const flashOff = require("../../src/common/Image/flash_off.png");
//sensors
let accSubscription;
// const SHOW_CORNERS = false;
const SHOW_CONTROLS = false;

const Camera = ({ navigation, route }) => {
  const imageref = useRef();
  const [cameraState, SetCameraState] = useState("");
  const [staincil, SetStaincil] = useState("");
  const [date, SetDate] = useState("");
  const [flashState, SetFlashState] = useState(false);
  const [camera, SetCamera] = useState("");
  const [imageData, SetImageData] = useState("");
  const [stopRecording, SetStopRecording] = useState(false);
  const [isAllignment, SetIsAllignment] = useState(true);
  const [screenWidth, SetScreenWidth] = useState(SCREEN_WIDTH);

  const [counter, setCounter] = useState(0);
  const [showCounter, setShowCounter] = useState(false);
  const [intervals, setIntervals] = useState();

  const dispatch = useDispatch();

  const {
    title,
    stepStencilAssests,
    DocumentImageName,
    subTitle,
    totalSteps,
    points,
    image,
    titleHn,
    subTitleHn,
    TotalImage,
    currentIndex,
    retryCount,
    licensePlateNumber,
    activityTypeId,
    activityId,
    isLast,
    imageName,
    toVDO /*@NEWORDER*/,
  } = route.params;

  /*@OLDFLOW*/
  const NEW_PI_VIDEO = activityTypeId === 5 || activityTypeId === 63;
  const SHOW_CORNERS = !NEW_PI_VIDEO;

  const animationRef = useRef();

  const startScreenRecording = async () => {
    // UELogEvent("Camera. startScreenRecording, recording started")
    const res = await RecordScreen.startRecording().catch((error) => {
      console.warn(error);
      // UELogEvent("Camera. startScreenRecording, recording start,caught error", {
      //   "error": JSON.stringify(error)
      // })
      console.log("**** startScreenRecording: ", error);
      // Go for existing video capture
    });
    if (res) {
      // true
      // recording started
    } else {
      // undefined
      // recording did not start
    }
    return res;
  };

  const stopScreenRecording = async () => {
    // UELogEvent("Camera. startScreenRecording, recording stopped")
    const recording = await RecordScreen.stopRecording().catch((error) => {
      // UELogEvent("Camera. startScreenRecording, recording stop, caught error", {
      //   "error": JSON.stringify(error)
      // })
      console.warn(error);
      console.log("**** stopScreenRecording: ", error);
      // Go for existing video capture
    });
    console.log("**** stopScreenRecording: " + JSON.stringify(recording));
    if (recording) {
      // UELogEvent("Camera. startScreenRecording, recording stop, recording generate success.", {
      //   "URL": JSON.stringify(recording.result.outputURL)
      // })
      const goToPreviewMedia = (uri, documentImageName) => {
        navigation.navigate("PreviewMedia", {
          uri: uri,
          DocumentImageName: documentImageName,
          onRetry: (uri, documentImageName) => {},
          onProceed: (uri, documentImageName) => {
            const myTimeout = setTimeout(() => {
              clearTimeout(myTimeout);
              Orientation.lockToPortrait();
              navigation.navigate("Odometer");
              UploadFile(
                uri,
                documentImageName,
                ".mp4",
                () => {
                  navigation.navigate("WithQuote");
                },
                () => {
                  addSensorImageData(".mp4", true, documentImageName);
                },
                () => {
                  addSensorImageData(".mp4", false, documentImageName);
                }
              );
            }, 1000);
          },
        });
      };
      goToPreviewMedia(recording.result.outputURL, "VDO");
    }
  };

  const addSensorImageData = (ext, ImageStatus, DocumentImageName) => {
    var attemptCount = PIRetryCount[0]?.retryCount + 1;
    var activityId = PIVechicleData[0]?.activityId;
    var fileName = activityId + "_" + DocumentImageName + ext;
    const PILocation = realm.objects("PILocation");
    const latitude = PILocation[0]?.lat;
    const longitude = PILocation[0]?.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 getPermission = async () => {
    if (Platform.OS === "android") {
      await getAndroidPermission();
    }
  };

  const getAndroidPermission = async () => {
    const grantedCamera = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.CAMERA
    );
    const grantedAudio = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.RECORD_AUDIO
    );

    const grantedWrite = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
    );
    const grantedRead = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE
    );

    const grantedPhoneState = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE
    );

    UELogEvent("Camera.js, Permissions. ", {
      "External Storage Write": JSON.stringify(grantedWrite),
      "External Storage Read": JSON.stringify(grantedRead),
      "Phone State": JSON.stringify(grantedPhoneState),
      Camera: JSON.stringify(grantedCamera),
      Audio: JSON.stringify(grantedAudio),
    });

    if (
      grantedWrite !== PermissionsAndroid.RESULTS.GRANTED ||
      grantedRead !== PermissionsAndroid.RESULTS.GRANTED ||
      grantedPhoneState !== PermissionsAndroid.RESULTS.GRANTED ||
      grantedCamera !== PermissionsAndroid.RESULTS.GRANTED ||
      grantedAudio !== PermissionsAndroid.RESULTS.GRANTED
    )
      Alert.alert(
        translate("Permission denied"),
        "We will be not able to proceed your vehicle inspection"
      );
  };

  useEffect(
    () => {
      getPermission();

      // setTimeout(() => {
      //   startScreenRecording()
      // }, 2000);

      // setTimeout(() => {
      //   stopScreenRecording();
      // }, 10000);

      let Immersive = undefined;
      let restoreImmersive = undefined;
      if (!iOS) {
        Immersive = require("react-native-immersive").Immersive;
        Immersive.setImmersive(true);
        restoreImmersive = () => {
          __DEV__ && console.log("Immersive state changed!");
          Immersive.setImmersive(true);
        };
        Immersive.addImmersiveListener(restoreImmersive);
      }
      if (DeviceInfo.isEmulatorSync()) {
        Alert.alert(
          "Emulator detected!",
          "Camera capture/recording may not work"
        );
      }
      setUpdateIntervalForType(SensorTypes.accelerometer, 1000); // defaults to 100ms
      if (accelerometer) {
        accSubscription = accelerometer.subscribe(({ x, y, z, timestamp }) => {
          if (x >= -3.5 && z >= -5 && y <= 4.5 && y >= -4.5) {
            SetIsAllignment(true);
          } else {
            SetIsAllignment(true);
          }
        });
      }

      changeCameraState();
      let unsubscribe = navigation.addListener("focus", () => {
        Orientation.lockToLandscapeLeft();
      });

      // disabled back handler
      const backHandler = BackHandler.addEventListener(
        "hardwareBackPress",
        () => {
          return true;
        }
      );
      if (showCounter) {
        setCounter(0);
        if (iOS) {
          BackgroundTimer.start();
        }
        const interval = BackgroundTimer.setInterval(() => {
          let newCounter = counter + 0.25;
          if (newCounter < 0) {
            newCounter = 0;
          }
          setIntervals(interval);
          setCounter((counter) => counter + 0.25);
        }, 250);
        return () => BackgroundTimer.clearInterval(intervals);
      }
      return () => {
        // if (Immersive !== undefined) {
        //   Immersive.off();
        //   Immersive.removeImmersiveListener(restoreImmersive);
        // }
        unsubscribe();
        backHandler.remove();
        accSubscription && accSubscription.unsubscribe();
      };
    },
    [showCounter],
    []
  );

  useEffect(() => {
    if (counter == 60) {
      BackgroundTimer.clearInterval(intervals);
      setShowCounter(false);
      SetStopRecording(false);
    }
  }, [counter]);

  // for change camera
  const changeCameraState = () => {
    if (title == SELFI_IMAGE || titleHn == SELFI_IMAGE_HN) {
      SetCameraState(RNCamera.Constants.Type.front);
      SetStaincil(stepStencilAssests);
    } else {
      SetCameraState(RNCamera.Constants.Type.back);
      SetStaincil(stepStencilAssests);
    }
    // UELogMessage("Camera State Changed", {
    //   "state": JSON.stringify(cameraState),
    // })
  };

  //Calculate image size using base64

  const getImageSize = (base64String) => {
    const n = base64String.length;
    let y = 1;
    // if (base64String.charAt(s.length - 1) === "=") {
    //   y = 1;
    // }
    // if (base64String.charAt(base64String.length - 1) === "=" && base64String.charAt(base64String.length - 1) === "=") {
    //   y = 2;
    // }
    return n * (3 / 4) - y;
  };

  // take pic
  const takePicture = async function (camera) {
    UELogMessage(
      `^^^^ Camera.js, takePicture. Started Taking Pictures ${DocumentImageName}`
    );
    const options = {
      quality: 0.2,
      base64: true,
      orientation: "landscapeLeft",
    };
    const data = await camera.takePictureAsync(options);
    const imageSizeInBytes = getImageSize(data.base64);
    // UELogEvent("Picture Captured...", {
    //   imageSize: `${imageSizeInBytes} bytes`,
    // });
    // console.log("%%%%%%% DATA OF IMAGE %%%%%%", data)

    // setting image data
    SetImageData(data);

    navigation.navigate("PreviewImage", {
      uri: data.uri,
      ImageData: data,
      ImageSize: `${getImageSize(data.base64)} bytes`,
      ext: ".jpg",
      DocumentImageName,
      title,
      titleHn,
      subTitle,
      subTitleHn,
      totalSteps,
      stepStencilAssests,
      points,
      image,
      points,
      TotalImage,
      currentIndex,
      retryCount,
      licensePlateNumber,
      activityTypeId,
      activityId,
      isLast,
    });
  };

  //start recording
  const startRecording = async (camera) => {
    setShowCounter(true);
    console.log("recording sterted");
    SetStopRecording(true);
    // default to mp4 for android as codec is not set
    const options = {
      orientation: "landscapeLeft",
      base64: true,
      maxDuration: 60,
      quality: "480p",
      videoBitrate: 64000 * 5,
    };

    camera
      .recordAsync(options)
      .then(({ uri, codec = "mp4" }) => {
        console.log("URI", uri);
        showPreview(uri);
      })

      .catch((error) => {
        Alert.alert(error?.message);
      });
  };

  const showPreview = (uri, title = VIDEO_TITLE) => {
    navigation.navigate("PreviewImage", {
      ImageData: uri,
      ext: ".mp4",
      DocumentImageName,
      title,
      subTitle,
      totalSteps,
      stepStencilAssests,
      points,
      image,
      points,
      TotalImage,
      currentIndex,
      retryCount,
      licensePlateNumber,
      activityTypeId,
      activityId,
      isLast,
    });
  };

  //Stop Recording
  const stopVideoRecording = (camera) => {
    // UELogMessage("Video Recording Stopped via stopVideoRecording Function")
    setShowCounter(false);
    BackgroundTimer.clearInterval(intervals);
    console.log("Recording stops");
    camera.stopRecording();
    SetStopRecording(false);
  };

  // for torch
  const toggleTorch = () => {
    console.log("^^^ TOGGLE TORCH ^^^^");
    SetFlashState(!flashState);
  };
  const captureImage =
    imageName === "VDO" || title == VIDEO_TITLE || titleHn == VIDEO_TITLE_HN
      ? stopRecording
        ? stop_recording
        : start_recording
      : camera_shutter;
  return (
    <SafeAreaView
      edges={iOS ? ["top", "bottom", "right"] : []}
      style={styles.safeArea}
    >
      <View style={styles.container}>
        <StatusBar hidden={true} />
        {NEW_PI_VIDEO && (
          <StencilAnimation
            navigation={navigation}
            myCamera={camera}
            startScreenRecording={startScreenRecording}
            stopScreenRecording={stopScreenRecording}
            ref={animationRef}
            toVDO={toVDO} /*@newOrder*/
            toggleTorch={toggleTorch} /* flashmode*/
            flashState={flashState}
          />
        )}
        {/* camera */}
        <View style={{ flex: 1 }}>
          <RNCamera
            style={styles.preview}
            type={cameraState}
            flashMode={
              flashState
                ? RNCamera.Constants.FlashMode.torch
                : RNCamera.Constants.FlashMode.off
            }
            autoFocus={RNCamera.Constants.AutoFocus.on}
            androidCameraPermissionOptions={{
              title: "Permission to use camera",
              message: "We need your permission to use your camera",
              buttonPositive: "Ok",
              buttonNegative: "Cancel",
            }}
            androidRecordAudioPermissionOptions={{
              title: "Permission to use audio recording",
              message: "We need your permission to use your audio",
              buttonPositive: "Ok",
              buttonNegative: "Cancel",
            }}
            // pausePreview={true}
            // pauseAfterCapture={true}
            // autoFocus={true}
          >
            {({ camera, status, recordAudioPermissionStatus }) => {
              // if (status !== 'READY') return <PendingView />;
              {
                SetCamera(camera);
              }
              return (
                <View style={styles.camera}>
                  {!isAllignment && (
                    <Text style={styles.landscapeTextStyle}>
                      {"Please align your device to landscape"}
                    </Text>
                  )}
                  {SHOW_CORNERS && (
                    <>
                      <Image source={left_top} style={styles.left_top} />
                      <Image source={left_bottom} style={styles.left_bottom} />
                    </>
                  )}
                  {console.log("COUNTER : ", counter)}
                  {showCounter && (
                    <ProgressBar
                      progress={counter / 75}
                      color={"#F5F5F5"}
                      style={styles.progressBarStyle}
                    />
                  )}
                  {showCounter && (
                    <Text style={styles.counterText}>
                      {((60.0 - counter) * -1)
                        .toString()
                        .substring(
                          0,
                          ((60.0 - counter) * -1).toString().indexOf(".")
                        )}
                    </Text>
                  )}
                  {SHOW_CORNERS && (
                    <>
                      <Image
                        source={right_bottom}
                        style={styles.right_bottom}
                      />
                      <Image source={right_top} style={styles.right_top} />
                    </>
                  )}
                  <Image
                    source={{ uri: stepStencilAssests }}
                    style={styles.stepStencilAssests}
                  />
                </View>
              );
            }}
          </RNCamera>
        </View>
        {/* Button */}
        {!NEW_PI_VIDEO && isAllignment && (
          <View style={{ flex: 0.15, backgroundColor: "black" }}>
            <View style={styles.controls}>
              {/* <View style={{ flex: 0.4 }}> */}
              <TouchableOpacity
                onPress={() => {
                  toggleTorch();
                }}
                style={styles.torch}
              >
                <Image
                  source={flashState ? flashOff : flashOn}
                  style={styles.flash}
                />
              </TouchableOpacity>
              {/* </View>
          <View style={{ flex: 0.6 }}> */}
              <TouchableOpacity
                onPress={() => {
                  setCounter(0);
                  imageName === "VDO" ||
                  title == VIDEO_TITLE ||
                  titleHn == VIDEO_TITLE_HN
                    ? stopRecording == true
                      ? stopVideoRecording(camera)
                      : startRecording(camera)
                    : takePicture(camera);
                }}
                style={styles.capture}
              >
                <Image source={captureImage} style={styles.captureImage} />
              </TouchableOpacity>
              {/* </View> */}
            </View>
          </View>
        )}
      </View>
    </SafeAreaView>
  );
};
const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
    backgroundColor: Colors.darkBlack,
  },
  main: {
    flex: 1,
    flexDirection: "row",
  },
  productImageView: {
    flex: 0.475,
  },
  blankView: {
    flex: 0.05,
  },
  productInfoView: {
    flex: 0.475,
    marginRight: 16,
    width: SCREEN_WIDTH,
    height: SCREEN_HEIGHT,
  },
  headerView: {
    backgroundColor: "#C6AFFF",
    height: 40,
    justifyContent: "center",
  },
  headerText: {
    marginLeft: 16,
    fontSize: 20,
    fontFamily: "Muli-Black",
  },
  productImageStyle: {
    marginTop: 8,
    marginLeft: 16,
    marginBottom: 40,
    height: SCREEN_HEIGHT - 70,
  },
  backButtonImageStyle: {
    marginLeft: 32,
    height: 24,
    width: 24,
    backgroundColor: "red",
  },
  subHeaderText: {
    fontFamily: "Mulli-Regular",
    fontSize: 16,
    marginLeft: 16,
  },
  instructionText: {
    fontFamily: "Mulli-Regular",
    fontSize: 16,
    marginLeft: 16,
    marginBottom: 20,
  },
  captureImageButtonView: {
    height: 48,
    borderRadius: 4,
    backgroundColor: Colors.digitYellow,
    marginTop: 2,
    flexDirection: "row",
    justifyContent: "center",
  },
  captureImageButtonText: {
    fontSize: 16,
    fontFamily: "Muli-Black",
    alignSelf: "center",
  },
  container: {
    flex: 1,
    flexDirection: "row",
    // backgroundColor: 'black',
  },
  preview: {
    flex: 1,
    justifyContent: "flex-end",
    alignItems: "center",
  },
  capture: {
    flex: 1,
    alignItems: "flex-start",
    alignSelf: "center",
    justifyContent: "flex-start",
  },
  flash: {
    flex: 0,
    backgroundColor: "#fff",
    borderRadius: 5,
    padding: 15,
    paddingHorizontal: 20,
    alignSelf: "flex-end",
    margin: 20,
    position: "absolute",
  },
  previewImageStyle: {
    width: SCREEN_WIDTH,
    height: SCREEN_HEIGHT,
  },
  dateAndTimeText: {
    position: "absolute",
    fontSize: 20,
    color: Colors.digitYellow,
    left: 1,
    bottom: 1,
  },
  previewImageIconMainView: {
    flex: 0.05,
    backgroundColor: "black",
  },
  tickMarkImageView: {
    flex: 0.6,
    justifyContent: "flex-end",
  },
  tickMarkImageStyle: {
    width: 30,
    height: 30,
    backgroundColor: "white",
    alignContent: "flex-end",
    marginBottom: 20,
  },
  crossImageView: {
    flex: 0.4,
    justifyContent: "flex-end",
    marginBottom: 20,
  },
  crossImageStyle: {
    width: 30,
    height: 30,
    backgroundColor: "white",
    alignContent: "flex-end",
  },
  cameraIconView: {
    flexDirection: "row",
    justifyContent: "center",
    width: SCREEN_WIDTH,
    position: "absolute",
  },
  infoScrollView: {
    marginTop: 40,
    height: SCREEN_HEIGHT - 200,
  },
  subHeaderTextView: {
    height: 40,
    marginTop: 8,
  },
  backButtonImageView: {
    backgroundColor: "#C6AFFF",
    height: 40,
    justifyContent: "center",
    marginLeft: 16,
  },
  latLongText: {
    position: "absolute",
    fontSize: 20,
    color: Colors.digitYellow,
    left: 1,
  },
  digitEdgeText: {
    position: "absolute",
    fontSize: 20,
    color: Colors.digitYellow,
    right: 1,
  },
  landscapeTextStyle: {
    width: "100%",
    position: "absolute",
    height: "100%",
    alignSelf: "center",
    textAlignVertical: "center",
    textAlign: "center",
    color: Colors.digitYellow,
    fontFamily: "Muli-ExtraBold",
    fontSize: 22,
  },
  progressBarStyle: {
    borderRadius: 6,
    backgroundColor: "#FFBB00",
    position: "absolute",
    width: "80%",
    marginTop: 2,
    height: 8,
    alignSelf: "center",
  },
  counterText: {
    width: "100%",
    position: "absolute",
    height: "100%",
    alignSelf: "center",
    textAlignVertical: "top",
    textAlign: "right",
    color: Colors.digitYellow,
    fontFamily: "Muli-ExtraBold",
    marginTop: 10,
    marginLeft: "45%",
  },
  captureImage: {
    width: 56,
    height: 56,
    backgroundColor: "black",
    resizeMode: "contain",
  },
  flash: {
    width: 30,
    height: 30,
    backgroundColor: "black",
    marginTop: 32,
    resizeMode: "contain",
  },
  torch: {
    width: 30,
    height: 30,
    backgroundColor: "black",
    resizeMode: "center",
    marginTop: 32,
    resizeMode: "contain",
    flex: 1,
    alignItems: "flex-start",
    alignSelf: "center",
  },
  controls: {
    flex: 1,
    backgroundColor: "black",
    flexDirection: "column",
  },
  stepStencilAssests: {
    width: "100%",
    height: "100%",
    position: "absolute",
    resizeMode: "contain",
    alignSelf: "center",
  },
  right_top: {
    width: 50,
    height: 50,
    position: "absolute",
    right: 1,
  },
  right_bottom: {
    width: 50,
    height: 50,
    position: "absolute",
    right: 1,
    bottom: 1,
  },
  left_bottom: {
    width: 50,
    height: 50,
    position: "absolute",
    left: 1,
    bottom: 1,
  },
  left_top: {
    width: 50,
    height: 50,
    position: "absolute",
    left: 1,
    resizeMode: "contain",
  },
  camera: {
    flex: 1,
    width: "95%",
    height: "100%",
    margin: 10,
  },
});
export default Camera;
