import { Ionicons } from "@expo/vector-icons";
import { useFocusEffect, useNavigation } from "@react-navigation/native";
import { Camera } from "expo-camera";
import * as FileSystem from "expo-file-system";
import React, { useEffect, useRef, useState } from "react";
import { SafeAreaView, Text, TouchableOpacity, View } from "react-native";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import {
  selectCurrentCameraJob,
  selectCurrentCameraJobId,
} from "../../redux/app/app.selectors";
import { addPhoto } from "../../redux/photos/photos.actions";
import CameraControls from "../camera-controls/camera-controls.component";

const mapStateToProps = createStructuredSelector({
  cameraJobId: selectCurrentCameraJobId,
  cameraJob: selectCurrentCameraJob,
});
const mapDispatchToProps = (dispatch) => ({
  addPhoto: (photo) => dispatch(addPhoto(photo)),
});

export function ScreenCamera({ cameraJobId, cameraJob, addPhoto }) {
  const navigation = useNavigation();
  const [hasPermission, setHasPermission] = useState(null);
  const [state, setState] = useState({
    flashMode: Camera.Constants.FlashMode.off,
    capturing: null,
    cameraType: Camera.Constants.Type.back,
    tabHasFocus: null,
  });
  const cameraRef = useRef(null);

  useFocusEffect(
    React.useCallback(() => {
      // Do something when the screen is focused
      setState({ ...state, tabHasFocus: true });
      return () => {
        // Do something when the screen is unfocused
        // Useful for cleanup functions
        setState({ ...state, tabHasFocus: false });
      };
    }, [])
  );

  useEffect(() => {
    (async () => {
      const { status } = await Camera.requestPermissionsAsync();
      setHasPermission(status === "granted");
    })();
  }, []);

  const setFlashMode = (flashMode) => setState({ ...state, flashMode });
  const setCameraType = (cameraType) => setState({ ...state, cameraType });
  const handleCaptureIn = () => setState({ ...state, capturing: true });

  const handleCaptureOut = () => {
    if (state.capturing) cameraRef.current.stopRecording();
  };

  const handleShortCapture = async () => {
    if (cameraRef.current) {
      const options = {
        //quality: 0.5,
        //base64: true,
        //skipProcessing: true,
      };

      let photo = await cameraRef.current.takePictureAsync(options);

      console.log("ScreenCamera -> photo", photo);
      const filename = photo.uri.substring(photo.uri.lastIndexOf("/") + 1);

      const newUri = FileSystem.documentDirectory + "photos/" + filename;

      await FileSystem.moveAsync({
        from: photo.uri,
        to: newUri,
      });
      setState({ ...state, capturing: false });

      addPhoto({
        ...photo,
        id: filename,
        uri: newUri,
        jobId: cameraJobId,
        video: false,
      });
    }
  };

  const handleLongCapture = async () => {
    console.log("Taking a video!");
    if (cameraRef.current) {
      let video = await cameraRef.current.recordAsync();

      const filename = video.uri.substring(video.uri.lastIndexOf("/") + 1);
      const newUri = FileSystem.documentDirectory + "photos/" + filename;

      await FileSystem.moveAsync({
        from: video.uri,
        to: newUri,
      });
      setState({ ...state, capturing: false });

      addPhoto({
        ...video,
        id: filename,
        uri: newUri,
        jobId: cameraJobId,
        video: true,
      });
    }
  };

  if (hasPermission === null || !state.tabHasFocus) {
    return <View />;
  }

  if (hasPermission === false) {
    return <Text>No access to camera</Text>;
  }

  const { flashMode, cameraType, capturing } = state;

  return (
    <View style={{ display: "flex", flex: 1 }}>
      <Camera
        style={{ flex: 1, display: "flex" }}
        type={state.cameraType}
        ref={cameraRef}
      >
        <SafeAreaView
          style={{
            flex: 1,
          }}
        >
          <TouchableOpacity
            onPress={() => navigation.push("CameraJobSearch")}
            style={{
              display: "flex",
              width: "100%",
              alignSelf: "flex-start",
              alignItems: "center",
              backgroundColor: "rgba(112, 128, 144, 0.3)",
              fontSize: 20,
              fontWeight: "bold",
            }}
          >
            <Text
              style={{
                fontSize: 20,
                fontWeight: "bold",
              }}
            >
              {cameraJob && cameraJob.ro_number}
            </Text>
            <Text>
              {cameraJob &&
                `${cameraJob && cameraJob.ownr_fn} ${
                  cameraJob && cameraJob.ownr_ln
                }`}
            </Text>
            <Text>{cameraJobId}</Text>
          </TouchableOpacity>
          <TouchableOpacity
            onPress={() => {
              navigation.push("MediaCache");
            }}
            style={{
              alignSelf: "flex-start",
              alignItems: "center",
              fontSize: 20,
              fontWeight: "bold",
            }}
          >
            <Ionicons
              name="ios-photos"
              style={{ color: "#fff", fontSize: 40 }}
            />
          </TouchableOpacity>

          <CameraControls
            capturing={capturing}
            flashMode={flashMode}
            cameraType={cameraType}
            setFlashMode={setFlashMode}
            setCameraType={setCameraType}
            onCaptureIn={handleCaptureIn}
            onCaptureOut={handleCaptureOut}
            onLongCapture={handleLongCapture}
            onShortCapture={handleShortCapture}
          />
        </SafeAreaView>
      </Camera>
    </View>
  );
}
export default connect(mapStateToProps, mapDispatchToProps)(ScreenCamera);
