/*
 * Pop Instructions, shows modals to ask user if he completed doing X thing.
 * There Will be total 6 modals for Pre Inspection & Payd it will be 1
 * Pre Inspection
 * 1. Have you found the chasiss number
 * 2. Have you finished shooting the chassis number
 * 3. Now start shooting inside the engine bay
 * 4. Once you've finished shooting the engine bay
 *   a. Please close all doors & bonnet
 * 5. Now you will shoot all sides
 * 6. Have you finished shooting the car from all sides?
 *
 * PAYD
 * 1. Now you will shoot all sides
 * 2. Have you finished shooting the car from all sides?
 */

import {
  View,
  Text,
  Alert,
  Image,
  Animated,
  StyleSheet,
  Easing,
  TouchableOpacity,
} from "react-native";
import React, { useEffect, useState, useRef, useReducer } from "react";
import { PrimaryButton } from "react-native-digitcamera/src/common/ThemedComponents";
import { useSelector } from "react-redux";
import { zIndex_close_bonnet } from "react-native-digitcamera/src/Screens/StencilAnimation";
import MCIcon from "react-native-vector-icons/MaterialCommunityIcons";
import { Ibutton } from "react-native-digitcamera/src/common/ThemedComponents";
import style from "react-native-digitcamera/src/common/CommonStyle";
import Orientation from "react-native-orientation";
import { closebonnet } from "../common/Assets";

// Mini instructions for Pre Inspection flow
//[15184, 11555, 10424, 10360, 9827, 10915, 11427, 10339, 10467, 11107, 9827, 10851, 10744, 11640]
export const PI_DATA = {
  DATA: [
    {
      id: 0,
      key: "chassis",
      description: "Have you finished shooting the chassis number ?", //show this instruction after 10sec on the chassis pose  //ask nitin to remove 25sec delay
      okButtonText: "Yes", // on yes move to engine bay pause
      shouldContinue: true,
      shouldPause: true,
      timeout: 10000, //when to show the pop aka showTimeout
      pauseAnimationTimeout: 0,
      contineAnimationTimeout: 0,
    },
    {
      id: 2,
      key: "engine bay",
      description: "Once you've finished shooting the engine bay", // show this instruction after 10sec on engine bay pose
      okButtonText: "Okay",
      shouldContinue: true,
      shouldPause: true,
      timeout: 9000, //changing it to 1sec, change back to 10000 after discussion with nitin to 10000
      pauseAnimationTimeout: 1000,
      contineAnimationTimeout: 0,
      imageUri: closebonnet,
      subDescription: "Please close all doors & bonnet",
    },
    {
      id: 4,
      key: "front number plate", //Front Passenger Corner
      description: "Now shoot the car from all sides",
      okButtonText: "Okay",
      shouldContinue: true,
      shouldPause: true,
      timeout: 5000,
      pauseAnimationTimeout: 0,
      contineAnimationTimeout: 0,
    },
    {
      id: 5,
      key: "front of the car", //change this instruction based on new one //changed
      description: "Have you finished shooting the car from all sides ?",
      okButtonText: "Yes",
      shouldContinue: true,
      shouldPause: true,
      timeout: 9000,
      pauseAnimationTimeout: 1000,
      contineAnimationTimeout: 0,
    },
    {
      id: 6,
      key: "odometer reading", //change this instruction based on new one //changed
      description: "Shoot odometer reading",
      okButtonText: "Okay",
      shouldContinue: true,
      shouldPause: true,
      timeout: 0,
      pauseAnimationTimeout: 1000,
      contineAnimationTimeout: 0,
    },
  ],
};

/*
* [state schema]

* DATA: array of objects - Array Mini Instructions to show on modal, description, button & image.
* MAPPING: object - Step Instruction for which modal should be shown, step instruction maps to a index where the mini instructions are stored
* CURRENT_DATA:object - Current Mini Instructions which is being shown
* SHOW:boolean - show & hide modal
*
*/

const getInitialState = (isGdd) => {
  return {
    ...PI_DATA,
    CURRENT_DATA: null,
    SHOW: false,
  };
};

/*
 * Instructions Reducer
 * action.type : SHOW -> render the instruction modal and assingn what data should be rendered
 * action.type : HIDE -> hides the instruction modal
 */

export const ACTION_TYPES = {
  PUSH: "PUSH",
  SHOW: "SHOW",
  HIDE: "HIDE",
  RESET: "RESET",
};

const instructionsReducer = (state, action) => {
  switch (action.type) {
    case ACTION_TYPES.PUSH:
      console.log(
        "[Info] PopInstructions.js . instructionsReducer . SHOW . action.payload ",
        action.payload,
        "\n"
      );
      const item = state.DATA.find(
        (item) =>
          action.payload.toLowerCase().indexOf(item.key.toLowerCase()) >= 0
      );
      // const item = action.payload;
      console.log(
        "[Info] PopInstructions.js . instructionsReducer . SHOW . item ",
        item,
        "\n"
      );
      console.log(
        "[Info] PopInstructions.js . instructionsReducer . SHOW . state ",
        { ...state, CURRENT_DATA: item },
        "\n"
      );
      return { ...state, CURRENT_DATA: item };
    case ACTION_TYPES.SHOW:
      return { ...state, SHOW: true };
    case ACTION_TYPES.HIDE:
      return { ...state, CURRENT_DATA: null, SHOW: false };
    case ACTION_TYPES.RESET:
      return { ...state };
  }
};

// For which instruction should the modal be visible
// Also checks if its PI or PAYD
const shouldShowModal = (instruction) => {
  return (
    PI_DATA.DATA.find(
      (item) => instruction.toLowerCase().indexOf(item.key.toLowerCase()) >= 0
    ) != undefined
  );
};

// Grouped animation functions as name suggests / animated values
let moveUpAndFadeIn, moveDownAndFadeOut, translatedValue, animatedOpacity;

const PopInstructions = (props) => {
  // Animations values & configuration s
  {
    translatedValue = useRef(new Animated.Value(0)).current;
    animatedOpacity = useRef(new Animated.Value(0)).current;

    const moveUp = Animated.timing(translatedValue, {
      toValue: -20,
      duration: 200,
      useNativeDriver: true,
    });

    const moveDown = Animated.timing(translatedValue, {
      toValue: 250,
      duration: 300,
      useNativeDriver: true,
    });

    const fadeIn = Animated.timing(animatedOpacity, {
      toValue: 1,
      duration: 200,
      useNativeDriver: true,
    });

    const fadeOut = Animated.timing(animatedOpacity, {
      toValue: 0,
      duration: 300,
      useNativeDriver: true,
    });

    moveUpAndFadeIn = () => {
      moveUp.start();
      fadeIn.start();
    };

    moveDownAndFadeOut = () => {
      moveDown.start();
      fadeOut.start();
    };
  }

  const { animate, isGdd, continueAnimation, pauseAnimation } = props;

  const [state, dispatch] = useReducer(
    instructionsReducer,
    getInitialState(isGdd)
  );

  const stepInstruction = useSelector(
    (state) => state.popInstructionsData.stepInstruction
  );
  // const stepInstruction = "<b>Embossed Chassis</b> visible on screen";

  useEffect(() => {
    console.log(
      "[Info] . PopInstructions . useEffect . stepInstruction",
      stepInstruction
    );
    // If pause instructions is there, then show the modal
    if (stepInstruction) {
      // Checks if we can show the modal
      const shouldShow = shouldShowModal(stepInstruction);
      if (shouldShow) {
        pushModalInstruction(stepInstruction, false);
      }
    }
  }, [stepInstruction]);

  // useEffect(() => {
  //   Orientation.lockToLandscapeLeft();
  // }, []);

  const pushModalInstruction = (instruction, isAfterTimeout) => {
    const { shouldPause, timeout, pauseAnimationTimeout } = PI_DATA.DATA.find(
      (item) => instruction.toLowerCase().indexOf(item.key.toLowerCase()) >= 0
    );

    const t2 = setTimeout(() => {
      clearTimeout(t2);
      // Pause Animation
      console.log("[Info] . PopInstructions. pauseAnimtion started ..");

      const t3 = setTimeout(() => {
        clearTimeout(t3);
        if (shouldPause) {
          pauseAnimation();
        }
      }, pauseAnimationTimeout);

      console.log("[Info] . PopInstructions. pauseAnimtion ended ..");

      console.log(
        "[Info] . PopInstructions . pushModalInstruction() executed "
      );

      dispatch({
        type: ACTION_TYPES.PUSH,
        payload: instruction,
      });

      showModal();
    }, timeout);
  };

  const showModal = () => {
    console.log("[Info] . PopInstructions . showModal() executed ");

    dispatch({
      type: ACTION_TYPES.SHOW,
    });
    // If animation is enabled
    if (animate) moveUpAndFadeIn();
  };

  const hideModal = (data) => {
    dispatch({
      type: ACTION_TYPES.HIDE,
      // payload: stepInstruction
    });

    if (data.shouldContinue) {
      const { contineAnimationTimeout } = data;
      const t4 = setTimeout(() => {
        clearTimeout(t4);
        continueAnimation();
      }, contineAnimationTimeout);
    }
  };

  return (
    <View style={styles.popInstructionsContainer}>
      {state.SHOW ? (
        <PopItem
          data={state.CURRENT_DATA}
          positiveCallback={hideModal}
          animate={animate}
        />
      ) : null}
    </View>
  );
};

/*
 * Modal that renders
 */

const OdometerSubview = () => {
  return (
    <View style={{ justifyContent: "center" }}>
      <View
        style={{
          flexDirection: "row",
          justifyContent: "space-between",
          alignItems: "center",
        }}
      >
        <View
          style={{
            flexDirection: "row",
            justifyContent: "space-between",
            alignItems: "center",
          }}
        >
          <MCIcon name="check-bold" size={18} color={"green"} />
          <Text style={[style.muliBoldDB]}> Odometer reading</Text>
        </View>
        <View
          style={{
            flexDirection: "row",
            justifyContent: "space-between",
            alignItems: "center",
          }}
        >
          <MCIcon name="close" size={18} color={"red"} />
          <Text style={[style.muliBoldDB]}> Trip Reading</Text>
        </View>
      </View>
      <View style={styles.infoMainView}>
        <View style={styles.infoMainTextView}>
          <Ibutton />
          <Text style={styles.normalText}>
            {"Odometer reading is total distance vehicle has travelled!"}
          </Text>
        </View>
      </View>
    </View>
  );
};

const PopItem = (props) => {
  const [imagePresent, setImagePresent] = useState(false);
  const { data, positiveCallback, animate } = props;
  const { id, imageUri, description, okButtonText, subDescription, key } = data;

  useEffect(() => {
    setImagePresent(checkIfImagePresent());
  }, [props.data]);

  const checkIfImagePresent = () => {
    if (imageUri) return imageUri.length != 0 ? true : false;
    return false;
  };

  const translatedValueX = useRef(new Animated.Value(0)).current;

  const moveToRight = Animated.timing(translatedValueX, {
    toValue: 300,
    duration: 300,
    useNativeDriver: true,
  });

  const moveToLeft = Animated.timing(translatedValueX, {
    toValue: 0,
    duration: 300,
    useNativeDriver: true,
  });

  const [hidden, setHidden] = useState(false);

  const onHide = () => {
    moveToRight.start(({ finished }) => {
      if (finished) {
        setHidden(true);
      }
    });
  };

  const onShow = () => {
    moveToLeft.start(({ finished }) => {
      if (finished) {
        setHidden(false);
      }
    });
  };

  return (
    <Animated.View
      key={id}
      style={[
        styles.popItemContainer,
        {
          width: imagePresent ? "60%" : "50%",
          height: imagePresent ? "50%" : "50%",
          easing: Easing.inOut,
          transform: animate
            ? [
                { translateX: translatedValueX },
                { translateY: translatedValue },
                { perspective: 1000 },
              ]
            : [{ translateX: 0 }, { translateY: 0 }],
          opacity: animate ? animatedOpacity : 1,
          bottom: "5%",
        },
      ]}
    >
      {/* {hidden ? (
        <GrayedButton onPress={onShow} title="show" />
      ) : (
        <GrayedButton onPress={onHide} title="hide" />
      )} */}
      {imagePresent && (
        <View style={styles.popItemImageContainer}>
          <Image source={imageUri} style={styles.popItemImageStyle} />
        </View>
      )}
      <View
        style={[
          styles.popItemDescriptionContainer,
          {
            flex: imagePresent ? 0.55 : 1,
          },
        ]}
      >
        <View>
          <Text style={[styles.popItemDescription, style.muliboldBB]}>
            {description}
          </Text>
          {subDescription && (
            <Text style={[styles.popItemSubdescription, style.muliRegLG]}>
              {subDescription}
            </Text>
          )}
        </View>
        {key === "odometer reading" && <OdometerSubview />}
        <PrimaryButton
          onPress={() => {
            // If animation is enabled
            if (animate) {
              moveDownAndFadeOut();
              // Hide POPItem component
              const t1 = setTimeout(() => {
                clearTimeout(t1);
                positiveCallback(data);
              }, 300);
            } else {
              positiveCallback(data);
            }
          }}
        >
          {okButtonText}
        </PrimaryButton>
      </View>
    </Animated.View>
  );
};

const GrayedButton = ({ onPress, title }) => {
  return (
    <TouchableOpacity
      onPress={onPress}
      style={{
        backgroundColor: "#F5F5F5",
        borderRadius: 8,
        justifyContent: "center",
        alignItems: "center",
        borderWidth: 1,
        borderColor: "#DDDDDD",
        margin: 8,
      }}
    >
      <MCIcon
        name={title === "hide" ? "arrow-right" : "arrow-left"}
        size={24}
        color={"#999999"}
      />
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  popInstructionsContainer: {
    flex: 0.8,
    position: "absolute",
    top: 0,
    bottom: 0,
    right: "10%",
    left: 0,
    zIndex: zIndex_close_bonnet,
  },
  popItemContainer: {
    position: "absolute",
    bottom: "0%",
    right: "5%",
    backgroundColor: "white",
    borderRadius: 8,
    padding: 16,
    flexDirection: "row",
    justifyContent: "space-between",
    elevation: 4,
  },
  popItemImageContainer: {
    flex: 0.4,
    justifyContent: "center",
    alignItems: "center",
  },
  popItemDescriptionContainer: {
    justifyContent: "space-between",
  },
  popItemImageStyle: {
    width: "100%",
    height: "100%",
    aspectRatio: 1,
    borderRadius: 8,
  },
  popItemDescription: {
    fontSize: 16,
    fontWeight: "700",
    marginBottom: 8,
  },
  popItemSubdescription: {
    fontSize: 14,
    fontWeight: "400",
  },
  infoMainView: {
    backgroundColor: "#FFFAEB",
    flexDirection: "row",
    marginVertical: 8,
    paddingVertical: 8,
  },
  infoIconView: {
    paddingHorizontal: 16,
    flex: 0.05,
    justifyContent: "flex-start",
  },
  infoMainTextView: {
    flex: 0.95,
    flexDirection: "row",
    // justifyContent: "space-between",
    alignItems: "center",
    marginHorizontal: 8,
  },
  normalText: {
    fontFamily: "Muli-Regular",
    fontSize: 11,
    marginLeft: 8,
  },
});

export default PopInstructions;
