import React, { useImperativeHandle, useEffect, useRef, forwardRef, useState } from 'react';
import { SafeAreaView, findNodeHandle, DeviceEventEmitter, NativeEventEmitter, Platform, PixelRatio, StyleSheet, Dimensions } from 'react-native';
import { MapViewManager, CTPEventEmitter } from './MapViewManager';
import { centerMap, createFragment, drawNavigationPath, setFollowBlueDot, setMapVenue, setUserPosition, clearWayfindingPath, wayfindToWaypoint, wayfindBetweenWaypoints, styleUnitsForDestination, addMapIcon, centerMapOnPoint, setMapViewBounds, setMapViewToPath } from './SendCommand';
import Compass from './Compass';
import { PathSimulator } from './PathSimulator';
import { generateGeojsonPath, preProcessPath } from './Instructions';
const MapView = (props, parentRef) => {
  var _props$compassStyle, _props$compassStyle2, _props$compassStyle3, _props$compassStyle4, _props$onMapMessage11;
  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 [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), {
  //         rotation: 0,
  //         zoom: 2,
  //         animationDuration: 100,
  //       });
  //     }
  //   }, [props.style.visible]);

  useEffect(() => {
    if (onNavigationPathGeneratedValue != null) {
      var _props$onMapMessage$o2, _props$onMapMessage2, _props$mapOptions, _props$credentials;
      let pathId, instructions, start, end, jibestreamPath;
      ({
        pathId,
        instructions,
        start,
        end,
        jibestreamPath
      } = onNavigationPathGeneratedValue);
      if (!jibestreamPath || !instructions) {
        var _props$onMapMessage$o, _props$onMapMessage;
        (_props$onMapMessage$o = (_props$onMapMessage = props.onMapMessage).onNavigationPathGenerated) === null || _props$onMapMessage$o === void 0 || _props$onMapMessage$o.call(_props$onMapMessage, pathId, instructions, start, end, jibestreamPath, undefined);
        return;
      }
      const processedInstructions = preProcessPath(jibestreamPath, instructions);
      (_props$onMapMessage$o2 = (_props$onMapMessage2 = props.onMapMessage).onNavigationPathGenerated) === null || _props$onMapMessage$o2 === void 0 || _props$onMapMessage$o2.call(_props$onMapMessage2, pathId, processedInstructions, start, end, jibestreamPath, generateGeojsonPath(processedInstructions, jibestreamPath, ((_props$mapOptions = props.mapOptions) === null || _props$mapOptions === void 0 || (_props$mapOptions = _props$mapOptions.navigation) === null || _props$mapOptions === void 0 ? void 0 : _props$mapOptions.directionsUnit) ?? 'FEET', ((_props$credentials = props.credentials) === null || _props$credentials === void 0 ? void 0 : _props$credentials.locale) ?? 'en-US'));
    }
  }, [onNavigationPathGeneratedValue]);
  useEffect(() => {
    if (onRerouteNavigationPathGeneratedValue != null) {
      var _props$onMapMessage$o4, _props$onMapMessage4, _props$mapOptions2, _props$credentials2;
      let pathId, instructions, start, end, jibestreamPath;
      ({
        pathId,
        instructions,
        start,
        end,
        jibestreamPath
      } = onRerouteNavigationPathGeneratedValue);
      if (!jibestreamPath || !instructions) {
        var _props$onMapMessage$o3, _props$onMapMessage3;
        (_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, undefined);
        return;
      }
      const processedInstructions = preProcessPath(jibestreamPath, instructions);
      (_props$onMapMessage$o4 = (_props$onMapMessage4 = props.onMapMessage).onRerouteNavigationPathGenerated) === null || _props$onMapMessage$o4 === void 0 || _props$onMapMessage$o4.call(_props$onMapMessage4, pathId, processedInstructions, start, end, jibestreamPath, generateGeojsonPath(processedInstructions, jibestreamPath, ((_props$mapOptions2 = props.mapOptions) === null || _props$mapOptions2 === void 0 || (_props$mapOptions2 = _props$mapOptions2.navigation) === null || _props$mapOptions2 === void 0 ? void 0 : _props$mapOptions2.directionsUnit) ?? 'FEET', ((_props$credentials2 = props.credentials) === null || _props$credentials2 === void 0 ? void 0 : _props$credentials2.locale) ?? 'en-US'));
    }
  }, [onRerouteNavigationPathGeneratedValue]);
  useEffect(() => {
    var _props$onMapMessage$o5, _props$onMapMessage5;
    if (onUserPositionUpdatedValue != null) (_props$onMapMessage$o5 = (_props$onMapMessage5 = props.onMapMessage).onUserPositionUpdated) === null || _props$onMapMessage$o5 === void 0 || _props$onMapMessage$o5.call(_props$onMapMessage5, onUserPositionUpdatedValue);
  }, [onUserPositionUpdatedValue]);
  useEffect(() => {
    var _props$onMapMessage$o6, _props$onMapMessage6;
    if (onSearchDestinationsGeneratedValue != null) (_props$onMapMessage$o6 = (_props$onMapMessage6 = props.onMapMessage).onSearchDestinationsGenerated) === null || _props$onMapMessage$o6 === void 0 || _props$onMapMessage$o6.call(_props$onMapMessage6, onSearchDestinationsGeneratedValue);
  }, [onSearchDestinationsGeneratedValue]);
  useEffect(() => {
    var _props$onMapMessage$o7, _props$onMapMessage7;
    if (onMapTappedGenericValue != null) (_props$onMapMessage$o7 = (_props$onMapMessage7 = props.onMapMessage).onMapTappedGeneric) === null || _props$onMapMessage$o7 === void 0 || _props$onMapMessage$o7.call(_props$onMapMessage7, onMapTappedGenericValue);
  }, [onMapTappedGenericValue]);
  useEffect(() => {
    var _props$onMapMessage$o8, _props$onMapMessage8;
    if (onErrorValue != null) (_props$onMapMessage$o8 = (_props$onMapMessage8 = props.onMapMessage).onError) === null || _props$onMapMessage$o8 === void 0 || _props$onMapMessage$o8.call(_props$onMapMessage8, onErrorValue);
  }, [onErrorValue]);
  useEffect(() => {
    var _props$onMapMessage$o9, _props$onMapMessage9;
    if (onVenueLoadedValue != null) (_props$onMapMessage$o9 = (_props$onMapMessage9 = props.onMapMessage).onVenueLoaded) === null || _props$onMapMessage$o9 === void 0 || _props$onMapMessage$o9.call(_props$onMapMessage9, onVenueLoadedValue);
  }, [onVenueLoadedValue]);
  useEffect(() => {
    if (onGeofencesChangedValue != null) {
      var _props$onMapMessage$o10, _props$onMapMessage10;
      let entered, geofences;
      ({
        entered,
        geofences
      } = onGeofencesChangedValue);
      (_props$onMapMessage$o10 = (_props$onMapMessage10 = props.onMapMessage).onGeofencesChanged) === null || _props$onMapMessage$o10 === void 0 || _props$onMapMessage$o10.call(_props$onMapMessage10, entered, geofences);
    }
  }, [onGeofencesChangedValue]);
  useImperativeHandle(parentRef, () => {
    const viewId = findNodeHandle(nodeRef.current);
    const listeners = {
      setMapVenue: (credentials, mapOptions) => {
        setTimeout(function () {
          setMapVenue({
            viewId,
            credentials,
            mapOptions
          });
        }, 500);
      },
      centerMapOnUser: options => {
        centerMap(viewId, {
          ...options,
          animationDuration: options.animationDuration ?? 1000
        });
      },
      centerMapOnPoint: options => {
        centerMapOnPoint(viewId, {
          ...options,
          animationDuration: options.animationDuration ?? 1000,
          format: options.format ?? 'LAT_LONG'
        });
      },
      setMapViewBounds: options => {
        setMapViewBounds(viewId, {
          ...options,
          animationDuration: options.animationDuration ?? 1000,
          rotation: options.rotation ?? 0,
          format: options.format ?? 'LAT_LONG'
        });
      },
      setMapViewToPath: options => {
        setMapViewToPath(viewId, {
          ...options,
          margin: options.margin ?? 0.2,
          animationDuration: options.animationDuration ?? 1000,
          rotation: options.rotation ?? 0
        });
      },
      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);
      },
      startPathSimulation: (path, options) => {
        simRef.current.startPathSimulation(path, options);
      },
      controlSimulation: command => {
        return simRef.current.controlSimulation(command);
      },
      getSimulationStatus: () => {
        return simRef.current.getSimulationStatus();
      }
    };
    return listeners;
  });
  useEffect(() => {
    var _eventEmitter, _eventEmitter2, _eventEmitter3, _eventEmitter4, _eventEmitter5, _eventEmitter6, _eventEmitter7, _eventEmitter8, _eventEmitter9;
    console.info('Registering Event Listeners');
    let eventEmitter = null;
    if (Platform.OS == 'android') {
      eventEmitter = DeviceEventEmitter;
    } else if (Platform.OS == 'ios') {
      eventEmitter = new NativeEventEmitter(CTPEventEmitter);
    }
    (_eventEmitter = eventEmitter) === null || _eventEmitter === void 0 || _eventEmitter.addListener('NAVIGATION_PATH_GENERATED', data => setOnNavigationPathGeneratedValue(data));
    (_eventEmitter2 = eventEmitter) === null || _eventEmitter2 === void 0 || _eventEmitter2.addListener('REROUTE_NAVIGATION_PATH_GENERATED', data => setOnRerouteNavigationPathGeneratedValue(data));
    (_eventEmitter3 = eventEmitter) === null || _eventEmitter3 === void 0 || _eventEmitter3.addListener('USER_POSITION_UPDATED', userPosition => setOnUserPositionUpdatedValue(userPosition));
    (_eventEmitter4 = eventEmitter) === null || _eventEmitter4 === void 0 || _eventEmitter4.addListener('GENERATED_SEARCH_DESTINATIONS', destinations => setOnSearchDestinationsGeneratedValue(destinations));
    (_eventEmitter5 = eventEmitter) === null || _eventEmitter5 === void 0 || _eventEmitter5.addListener('MAP_TAPPED_GENERIC', event => setOnMapTappedGenericValue(event));
    (_eventEmitter6 = eventEmitter) === null || _eventEmitter6 === void 0 || _eventEmitter6.addListener('SCREEN_ROTATED', event => {
      const newTransform = {
        rotate: Math.round(event.degrees).toString() + 'deg'
      };
      setCompassTransform(newTransform);
    });
    (_eventEmitter7 = eventEmitter) === null || _eventEmitter7 === void 0 || _eventEmitter7.addListener('ERROR', msg => setOnErrorValue(msg));
    (_eventEmitter8 = eventEmitter) === null || _eventEmitter8 === void 0 || _eventEmitter8.addListener('VENUE_LOADED', venueId => setOnVenueLoadedValue(venueId));
    (_eventEmitter9 = eventEmitter) === null || _eventEmitter9 === void 0 || _eventEmitter9.addListener('GEOFENCES_CHANGED', data => setOnGeofencesChangedValue(data));
    return () => {
      var _eventEmitter10, _eventEmitter11, _eventEmitter12, _eventEmitter13, _eventEmitter14, _eventEmitter15, _eventEmitter16, _eventEmitter17, _eventEmitter18;
      (_eventEmitter10 = eventEmitter) === null || _eventEmitter10 === void 0 || _eventEmitter10.removeAllListeners('NAVIGATION_PATH_GENERATED');
      (_eventEmitter11 = eventEmitter) === null || _eventEmitter11 === void 0 || _eventEmitter11.removeAllListeners('USER_POSITION_UPDATED');
      (_eventEmitter12 = eventEmitter) === null || _eventEmitter12 === void 0 || _eventEmitter12.removeAllListeners('GENERATED_SEARCH_DESTINATIONS');
      (_eventEmitter13 = eventEmitter) === null || _eventEmitter13 === void 0 || _eventEmitter13.removeAllListeners('MAP_TAPPED_GENERIC');
      (_eventEmitter14 = eventEmitter) === null || _eventEmitter14 === void 0 || _eventEmitter14.removeAllListeners('ERROR');
      (_eventEmitter15 = eventEmitter) === null || _eventEmitter15 === void 0 || _eventEmitter15.removeAllListeners('VENUE_LOADED');
      (_eventEmitter16 = eventEmitter) === null || _eventEmitter16 === void 0 || _eventEmitter16.removeAllListeners('SCREEN_ROTATED');
      (_eventEmitter17 = eventEmitter) === null || _eventEmitter17 === void 0 || _eventEmitter17.removeAllListeners('GEOFENCES_CHANGED');
      (_eventEmitter18 = eventEmitter) === null || _eventEmitter18 === void 0 || _eventEmitter18.removeAllListeners('REROUTE_NAVIGATION_PATH_GENERATED');
    };
  }, []);
  return /*#__PURE__*/React.createElement(SafeAreaView, {
    style: {
      width: props.style.width,
      height: props.style.height,
      top: props.style.visible ? 0 : -(2 * Dimensions.get('window').height + props.style.height + 5),
      left: props.style.visible ? 0 : -(2 * Dimensions.get('window').width + props.style.width + 5),
      position: 'absolute',
      overflow: 'hidden'
    }
  }, /*#__PURE__*/React.createElement(PathSimulator, {
    ref: simRef,
    updateUserLocation: (pos, heading) => {
      setUserPosition(findNodeHandle(nodeRef.current), pos[0], pos[1], heading, 100, null);
    },
    onSimStatusChanged: (_props$onMapMessage11 = props.onMapMessage) === null || _props$onMapMessage11 === void 0 ? void 0 : _props$onMapMessage11.onSimulationStatusChanged
  }), /*#__PURE__*/React.createElement(Compass, {
    style: [compassStyle.compass, {
      transform: [compassTransform]
    }]
  }), MapViewManager ? /*#__PURE__*/React.createElement(MapViewManager, {
    style: Platform.OS == 'android' ? {
      height: PixelRatio.getPixelSizeForLayoutSize(props.style.height),
      width: PixelRatio.getPixelSizeForLayoutSize(props.style.width)
    } : {
      height: props.style.height,
      width: props.style.width
    },
    ref: nodeRef
  }) : null);
};
const mapViewFwRef = /*#__PURE__*/forwardRef(MapView);
export default mapViewFwRef;
//# sourceMappingURL=MapView.js.map