import React, { useImperativeHandle, useEffect, useRef, forwardRef, useState } from 'react';
import { SafeAreaView, findNodeHandle, DeviceEventEmitter, NativeEventEmitter, Platform, PixelRatio, StyleSheet } from 'react-native';
import { MapViewManager, CTPEventEmitter } from './MapViewManager';
import { centerMap, createFragment, drawNavigationPath, setFollowBlueDot, setMapVenue, setUserPosition, clearWayfindingPath, wayfindToWaypoint, wayfindBetweenWaypoints, styleUnitsForDestination, addMapIcon } from './SendCommand';
import Compass from './Compass';
import { PathSimulator } from './PathSimulator';
const updateGeojsonTimestamps = geojson => {
  if (Platform.OS == 'android') {
    geojson.startTime = geojson.startTime * 1000;
    geojson.endTime = geojson.endTime * 1000;
  }
  return geojson;
};
const MapView = (props, parentRef) => {
  var _props$compassStyle, _props$compassStyle2, _props$compassStyle3, _props$compassStyle4, _props$onMapMessage10;
  const nodeRef = useRef(null);
  const compassStyle = StyleSheet.create({
    compass: {
      height: props.style.visible ? (props === null || props === void 0 || (_props$compassStyle = props.compassStyle) === null || _props$compassStyle === void 0 ? void 0 : _props$compassStyle.size) ?? 0 : 0,
      width: props.style.visible ? (props === null || props === void 0 || (_props$compassStyle2 = props.compassStyle) === null || _props$compassStyle2 === void 0 ? void 0 : _props$compassStyle2.size) ?? 0 : 0,
      borderRadius: 5,
      alignItems: 'center',
      justifyContent: 'center',
      zIndex: 1,
      position: 'absolute',
      right: props === null || props === void 0 || (_props$compassStyle3 = props.compassStyle) === null || _props$compassStyle3 === void 0 ? void 0 : _props$compassStyle3.right,
      top: props === null || props === void 0 || (_props$compassStyle4 = props.compassStyle) === null || _props$compassStyle4 === void 0 ? void 0 : _props$compassStyle4.top,
      flex: 1,
      resizeMode: 'contain'
    }
  });
  const [compassTransform, setCompassTransform] = useState({
    rotate: '0deg'
  });

  // CALLBACK DATA
  const [onNavigationPathGeneratedValue, setOnNavigationPathGeneratedValue] = useState(null);
  const [onRerouteNavigationPathGeneratedValue, setOnRerouteNavigationPathGeneratedValue] = useState(null);
  const [onDestinationSelectedValue, setOnDestinationSelectedValue] = useState(null);
  const [onUserPositionUpdatedValue, setOnUserPositionUpdatedValue] = useState(null);
  const [onSearchDestinationsGeneratedValue, setOnSearchDestinationsGeneratedValue] = useState(null);
  const [onMapTappedGenericValue, setOnMapTappedGenericValue] = useState(null);
  const [onGeofencesChangedValue, setOnGeofencesChangedValue] = useState(null);
  const [onErrorValue, setOnErrorValue] = useState(null);
  const [onVenueLoadedValue, setOnVenueLoadedValue] = useState(null);

  // STATE VARIABLES
  // const [pathSimulator, _] = useState<PathSimulator>(new PathSimulator((loc: number[]) => {setUserPosition(findNodeHandle(nodeRef.current), loc[0]!, loc[1]!, 0, 5, null);}));

  const simRef = useRef(null);
  useEffect(() => {
    if (Platform.OS == 'android') {
      createFragment(findNodeHandle(nodeRef.current));
    }
    setTimeout(function () {
      setMapVenue({
        viewId: findNodeHandle(nodeRef.current),
        credentials: props.credentials,
        mapOptions: props.mapOptions
      });
    }, 500);
  }, []);
  useEffect(() => {
    if (props.style.visible) {
      centerMap(findNodeHandle(nodeRef.current), 0, 5, 100);
    }
  }, [props.style.visible]);
  useEffect(() => {
    var _props$onMapMessage$o, _props$onMapMessage;
    if (onDestinationSelectedValue != null) (_props$onMapMessage$o = (_props$onMapMessage = props.onMapMessage).onDestinationSelected) === null || _props$onMapMessage$o === void 0 || _props$onMapMessage$o.call(_props$onMapMessage, onDestinationSelectedValue);
  }, [onDestinationSelectedValue]);
  useEffect(() => {
    if (onNavigationPathGeneratedValue != null) {
      var _props$onMapMessage$o2, _props$onMapMessage2;
      let pathId, instructions, start, end, jibestreamPath, path;
      ({
        pathId,
        instructions,
        start,
        end,
        jibestreamPath,
        path
      } = onNavigationPathGeneratedValue);
      (_props$onMapMessage$o2 = (_props$onMapMessage2 = props.onMapMessage).onNavigationPathGenerated) === null || _props$onMapMessage$o2 === void 0 || _props$onMapMessage$o2.call(_props$onMapMessage2, pathId, instructions, start, end, jibestreamPath, updateGeojsonTimestamps(path));
    }
  }, [onNavigationPathGeneratedValue]);
  useEffect(() => {
    if (onRerouteNavigationPathGeneratedValue != null) {
      var _props$onMapMessage$o3, _props$onMapMessage3;
      let pathId, instructions, start, end, jibestreamPath, path;
      ({
        pathId,
        instructions,
        start,
        end,
        jibestreamPath,
        path
      } = onRerouteNavigationPathGeneratedValue);
      (_props$onMapMessage$o3 = (_props$onMapMessage3 = props.onMapMessage).onRerouteNavigationPathGenerated) === null || _props$onMapMessage$o3 === void 0 || _props$onMapMessage$o3.call(_props$onMapMessage3, pathId, instructions, start, end, jibestreamPath, updateGeojsonTimestamps(path));
    }
  }, [onRerouteNavigationPathGeneratedValue]);
  useEffect(() => {
    var _props$onMapMessage$o4, _props$onMapMessage4;
    if (onUserPositionUpdatedValue != null) (_props$onMapMessage$o4 = (_props$onMapMessage4 = props.onMapMessage).onUserPositionUpdated) === null || _props$onMapMessage$o4 === void 0 || _props$onMapMessage$o4.call(_props$onMapMessage4, onUserPositionUpdatedValue);
  }, [onUserPositionUpdatedValue]);
  useEffect(() => {
    var _props$onMapMessage$o5, _props$onMapMessage5;
    if (onSearchDestinationsGeneratedValue != null) (_props$onMapMessage$o5 = (_props$onMapMessage5 = props.onMapMessage).onSearchDestinationsGenerated) === null || _props$onMapMessage$o5 === void 0 || _props$onMapMessage$o5.call(_props$onMapMessage5, onSearchDestinationsGeneratedValue);
  }, [onSearchDestinationsGeneratedValue]);
  useEffect(() => {
    var _props$onMapMessage$o6, _props$onMapMessage6;
    if (onMapTappedGenericValue != null) (_props$onMapMessage$o6 = (_props$onMapMessage6 = props.onMapMessage).onMapTappedGeneric) === null || _props$onMapMessage$o6 === void 0 || _props$onMapMessage$o6.call(_props$onMapMessage6, onMapTappedGenericValue);
  }, [onMapTappedGenericValue]);
  useEffect(() => {
    var _props$onMapMessage$o7, _props$onMapMessage7;
    if (onErrorValue != null) (_props$onMapMessage$o7 = (_props$onMapMessage7 = props.onMapMessage).onError) === null || _props$onMapMessage$o7 === void 0 || _props$onMapMessage$o7.call(_props$onMapMessage7, onErrorValue);
  }, [onErrorValue]);
  useEffect(() => {
    var _props$onMapMessage$o8, _props$onMapMessage8;
    if (onVenueLoadedValue != null) (_props$onMapMessage$o8 = (_props$onMapMessage8 = props.onMapMessage).onVenueLoaded) === null || _props$onMapMessage$o8 === void 0 || _props$onMapMessage$o8.call(_props$onMapMessage8, onVenueLoadedValue);
  }, [onVenueLoadedValue]);
  useEffect(() => {
    if (onGeofencesChangedValue != null) {
      var _props$onMapMessage$o9, _props$onMapMessage9;
      let entered, geofences;
      ({
        entered,
        geofences
      } = onGeofencesChangedValue);
      console.log('Geofences Changed: ', entered, geofences);
      (_props$onMapMessage$o9 = (_props$onMapMessage9 = props.onMapMessage).onGeofencesChanged) === null || _props$onMapMessage$o9 === void 0 || _props$onMapMessage$o9.call(_props$onMapMessage9, entered, geofences);
    }
  }, [onGeofencesChangedValue]);
  useImperativeHandle(parentRef, () => {
    const viewId = findNodeHandle(nodeRef.current);
    const listeners = {
      setMapVenue: (credentials, mapOptions) => {
        setTimeout(function () {
          setMapVenue({
            viewId,
            credentials,
            mapOptions
          });
        }, 500);
      },
      centerMapOnUser: function (orientation) {
        let zoom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5;
        let animationDuration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000;
        centerMap(viewId, orientation, zoom, animationDuration);
      },
      setFollowBlueDot: function (enabled) {
        let rotate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
        let interval = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 500;
        setFollowBlueDot(viewId, enabled, rotate, interval);
      },
      setUserPosition: (lat, long, heading, confidence) => {
        setUserPosition(viewId, lat, long, heading, confidence, null);
      },
      setUserPositionXY: (x, y, heading, confidence) => {
        setUserPosition(viewId, x, y, heading, confidence, 'xy');
      },
      clearWayfindingPath: () => {
        clearWayfindingPath(viewId);
      },
      wayfindToWaypoint: waypointId => {
        wayfindToWaypoint(viewId, waypointId);
      },
      wayfindBetweenWaypoints: (originId, destinationId) => {
        wayfindBetweenWaypoints(viewId, originId, destinationId);
      },
      drawNavigationPath: (pathId, _ref) => {
        let {
          shouldFocus,
          style,
          originIcon,
          destinationIcon
        } = _ref;
        drawNavigationPath(viewId, pathId, shouldFocus ?? true, style ?? {}, originIcon, destinationIcon);
      },
      styleUnitsForDestination: (destinationId, style) => {
        styleUnitsForDestination(viewId, destinationId, style);
      },
      addMapIcon: (coordinates, coordType, icon) => {
        addMapIcon(viewId, coordinates, coordType, icon);
      },
      // Path Simulator
      startPathSimulation: (path, options) => {
        simRef.current.startPathSimulation(path, options);
      },
      controlSimulation: command => {
        return simRef.current.controlSimulation(command);
      },
      getSimulationStatus: () => {
        return simRef.current.getSimulationStatus();
      },
      getSimulationsPaths: () => {
        return simRef.current.getSimulationsPaths();
      }
    };
    return listeners;
  });
  useEffect(() => {
    var _eventEmitter, _eventEmitter2, _eventEmitter3, _eventEmitter4, _eventEmitter5, _eventEmitter6, _eventEmitter7, _eventEmitter8, _eventEmitter9, _eventEmitter10;
    console.log('Initializing Event Emitter');
    let eventEmitter = null;
    if (Platform.OS == 'android') {
      eventEmitter = DeviceEventEmitter;
    } else if (Platform.OS == 'ios') {
      console.log(CTPEventEmitter);
      eventEmitter = new NativeEventEmitter(CTPEventEmitter);
    }
    (_eventEmitter = eventEmitter) === null || _eventEmitter === void 0 || _eventEmitter.addListener('DESTINATION_SELECTED', data => setOnDestinationSelectedValue(data));
    (_eventEmitter2 = eventEmitter) === null || _eventEmitter2 === void 0 || _eventEmitter2.addListener('NAVIGATION_PATH_GENERATED', data => setOnNavigationPathGeneratedValue(data));
    (_eventEmitter3 = eventEmitter) === null || _eventEmitter3 === void 0 || _eventEmitter3.addListener('REROUTE_NAVIGATION_PATH_GENERATED', data => setOnRerouteNavigationPathGeneratedValue(data));
    (_eventEmitter4 = eventEmitter) === null || _eventEmitter4 === void 0 || _eventEmitter4.addListener('USER_POSITION_UPDATED', userPosition => setOnUserPositionUpdatedValue(userPosition));
    (_eventEmitter5 = eventEmitter) === null || _eventEmitter5 === void 0 || _eventEmitter5.addListener('GENERATED_SEARCH_DESTINATIONS', destinations => setOnSearchDestinationsGeneratedValue(destinations));
    (_eventEmitter6 = eventEmitter) === null || _eventEmitter6 === void 0 || _eventEmitter6.addListener('MAP_TAPPED_GENERIC', event => setOnMapTappedGenericValue(event));
    (_eventEmitter7 = eventEmitter) === null || _eventEmitter7 === void 0 || _eventEmitter7.addListener('SCREEN_ROTATED', event => {
      const newTransform = {
        rotate: Math.round(event.degrees).toString() + 'deg'
      };
      setCompassTransform(newTransform);
    });
    (_eventEmitter8 = eventEmitter) === null || _eventEmitter8 === void 0 || _eventEmitter8.addListener('ERROR', msg => setOnErrorValue(msg));
    (_eventEmitter9 = eventEmitter) === null || _eventEmitter9 === void 0 || _eventEmitter9.addListener('VENUE_LOADED', venueId => setOnVenueLoadedValue(venueId));
    (_eventEmitter10 = eventEmitter) === null || _eventEmitter10 === void 0 || _eventEmitter10.addListener('GEOFENCES_CHANGED', data => setOnGeofencesChangedValue(data));
    return () => {
      var _eventEmitter11, _eventEmitter12, _eventEmitter13, _eventEmitter14, _eventEmitter15, _eventEmitter16, _eventEmitter17, _eventEmitter18, _eventEmitter19, _eventEmitter20;
      console.log('Removing Event Emitters');
      (_eventEmitter11 = eventEmitter) === null || _eventEmitter11 === void 0 || _eventEmitter11.removeAllListeners('DESTINATION_SELECTED');
      (_eventEmitter12 = eventEmitter) === null || _eventEmitter12 === void 0 || _eventEmitter12.removeAllListeners('NAVIGATION_PATH_GENERATED');
      (_eventEmitter13 = eventEmitter) === null || _eventEmitter13 === void 0 || _eventEmitter13.removeAllListeners('USER_POSITION_UPDATED');
      (_eventEmitter14 = eventEmitter) === null || _eventEmitter14 === void 0 || _eventEmitter14.removeAllListeners('GENERATED_SEARCH_DESTINATIONS');
      (_eventEmitter15 = eventEmitter) === null || _eventEmitter15 === void 0 || _eventEmitter15.removeAllListeners('MAP_TAPPED_GENERIC');
      (_eventEmitter16 = eventEmitter) === null || _eventEmitter16 === void 0 || _eventEmitter16.removeAllListeners('ERROR');
      (_eventEmitter17 = eventEmitter) === null || _eventEmitter17 === void 0 || _eventEmitter17.removeAllListeners('VENUE_LOADED');
      (_eventEmitter18 = eventEmitter) === null || _eventEmitter18 === void 0 || _eventEmitter18.removeAllListeners('SCREEN_ROTATED');
      (_eventEmitter19 = eventEmitter) === null || _eventEmitter19 === void 0 || _eventEmitter19.removeAllListeners('GEOFENCES_CHANGED');
      (_eventEmitter20 = eventEmitter) === null || _eventEmitter20 === void 0 || _eventEmitter20.removeAllListeners('REROUTE_NAVIGATION_PATH_GENERATED');
    };
  }, []);
  return /*#__PURE__*/React.createElement(SafeAreaView, {
    style: {
      flex: 1,
      width: props.style.visible ? props.style.width : 0,
      height: props.style.visible ? props.style.height : 0
    }
  }, /*#__PURE__*/React.createElement(PathSimulator, {
    ref: simRef,
    updateUserLocation: (pos, heading) => {
      setUserPosition(findNodeHandle(nodeRef.current), pos[0], pos[1], heading, 100, null);
    },
    onSimStatusChanged: (_props$onMapMessage10 = props.onMapMessage) === null || _props$onMapMessage10 === void 0 ? void 0 : _props$onMapMessage10.onSimulationStatusChanged
  }), /*#__PURE__*/React.createElement(Compass, {
    style: [compassStyle.compass, {
      transform: [compassTransform]
    }]
  }), MapViewManager ? /*#__PURE__*/React.createElement(MapViewManager, {
    style: Platform.OS == 'android' ? {
      height: props.style.visible ? PixelRatio.getPixelSizeForLayoutSize(props.style.height) : 0,
      width: props.style.visible ? PixelRatio.getPixelSizeForLayoutSize(props.style.width) : 0
    } : {
      height: props.style.visible ? props.style.height / 1 : 0,
      width: props.style.visible ? props.style.width / 1 : 0
    },
    ref: nodeRef
  }) : null);
};
const mapViewFwRef = /*#__PURE__*/forwardRef(MapView);
export default mapViewFwRef;
//# sourceMappingURL=MapView.js.map