import _taggedTemplateLiteralLoose from "@babel/runtime/helpers/taggedTemplateLiteralLoose";

var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;

import React, { useEffect, useRef, useState, useMemo, createRef } from 'react';
import ReactDOM from 'react-dom';
import { useStoresPinsToFitInView, useStores, useStoresContext } from '../../stores.context';
import { GoogleApiWrapper, Map, Marker as M, InfoWindow as IWindow } from 'google-maps-react';
import styled, { css } from 'styled-components';
import { Button } from '../../../Common';
import { getDistance } from '@sentecacommerce-theme/lib';
import { useRouter } from 'next/router';
import { useStrings } from '@sentecacommerce-theme/lib';
// >:((
var Marker = M;
var InfoWindow = IWindow;

var MapComponent = (_ref) => {
  var {
    google,
    pinIcon,
    fullWidth
  } = _ref;
  var router = useRouter();
  var labels = useStrings('stores');
  var [map, setMap] = useState();
  var [selectedPin, setSelectedPin] = useState();
  var [storeDistance, setStoreDistance] = useState();
  var [currentPos, setCurrentPos] = useState();
  var {
    selectedStore: selectedStoreFromList,
    setSelectedStore: setSelectedStoreFromList
  } = useStoresContext();
  var markerRefs = useRef([]);
  var [closestLocation, setClosestLocation] = useState();
  var stores = useStores();
  var pinsToFitInMap = useStoresPinsToFitInView();

  var onReady = (_, map) => {
    setMap(map);
  };
  /**
   * Center the map to the current pins
   */


  useEffect(() => {
    var bounds = new google.maps.LatLngBounds();
    pinsToFitInMap.forEach(pin => {
      bounds.extend(pin);
    });
    if (!map) return;
    map.fitBounds(bounds); // set min zoom

    map.setZoom(Math.min(map.getZoom(), 14)); // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pinsToFitInMap]);

  var onMarkerClick = store => (_, marker) => {
    setSelectedStoreFromList(store.name);
    setSelectedPin({
      marker,
      store
    });
  };

  var hideInfoWindow = () => {
    setSelectedStoreFromList(null);
    setSelectedPin(null);
  }; // Attaches the button to the React DOM after the info window has been opened to preserve
  // the event bindings like (onClick) which are otherwise lost and don't bubble up through the iframe
  // if they're put directly in the InfoWindow


  var onInfoWindowOpen = () => {
    var button = /*#__PURE__*/React.createElement(Button, {
      className: "mt-2",
      fullWidth: true,
      borderRadius: "large",
      small: true,
      onClick: () => router.push('/stores/' + selectedStore.slug)
    }, labels.viewStoreLabel);
    ReactDOM.render(React.Children.only(button), document.getElementById('viewStoreBtn'));
  };

  var selectedStore = selectedPin == null ? void 0 : selectedPin.store;
  var selectedMarker = selectedPin == null ? void 0 : selectedPin.marker; // memo markers to prevent unnecessary markers initialization

  var markers = useMemo(() => {
    return stores.map((store, i) => {
      var pin = {
        lat: +store.latitude,
        lng: +store.longitude
      };
      markerRefs.current = Array(stores.length).fill(null).map((_, i) => markerRefs.current[i] || /*#__PURE__*/createRef());
      return /*#__PURE__*/React.createElement(Marker, {
        key: "Marker__" + pin.lat + "x" + pin.lng,
        position: pin,
        icon: (pinIcon == null ? void 0 : pinIcon.trim()) || undefined,
        onClick: onMarkerClick(store),
        ref: markerRefs.current[i]
      });
    });
  }, [stores, pinIcon]);

  var findClosestDistance = pos => {
    var _closestMarker, _closestMarker2;

    var closestDistance = Number.MAX_VALUE;
    var closestMarker = null;

    for (var marker of markers) {
      var posCoords = {
        lat: pos.coords.latitude,
        lng: pos.coords.longitude
      };
      var markerCoords = marker.props.position;
      var distance = getDistance(posCoords, markerCoords);

      if (closestDistance > distance) {
        closestDistance = distance;
        closestMarker = marker;
      }
    }

    setClosestLocation({
      lat: (_closestMarker = closestMarker) == null ? void 0 : _closestMarker.props.position.lat,
      lng: (_closestMarker2 = closestMarker) == null ? void 0 : _closestMarker2.props.position.lng
    });
  };

  var setDistanceFromSelectedStore = () => {
    var pos = {
      lat: currentPos == null ? void 0 : currentPos.coords.latitude,
      lng: currentPos == null ? void 0 : currentPos.coords.longitude
    };
    var storePos = {
      lat: parseFloat(selectedStore == null ? void 0 : selectedStore.latitude),
      lng: parseFloat(selectedStore == null ? void 0 : selectedStore.longitude)
    };
    var distance = getDistance(pos, storePos);
    setStoreDistance(distance);
  };

  var onMapAndGeolocationLoad = () => {
    navigator.geolocation.getCurrentPosition(pos => {
      setCurrentPos(pos);
      findClosestDistance(pos);
      setDistanceFromSelectedStore();
      map == null ? void 0 : map.setZoom(13);
    });
  };

  useEffect(() => {
    map == null ? void 0 : map.setZoom(13);
    setDistanceFromSelectedStore();

    if (selectedStoreFromList !== (selectedPin == null ? void 0 : selectedPin.store.name)) {
      stores.forEach((store, i) => {
        if (selectedStoreFromList === store.name) {
          var marker = markers[i];
          var storeCoords = {
            lat: +store.latitude,
            lng: +store.longitude
          };
          var markerCoords = marker.props.position;

          if (storeCoords.lat === markerCoords.lat && storeCoords.lng === markerCoords.lng) {
            setSelectedPin({
              marker: markerRefs.current[i].current.marker,
              store
            });
          }
        }
      });
    }
  });
  useEffect(() => {
    onMapAndGeolocationLoad();
  }, []);
  return /*#__PURE__*/React.createElement(MapContainer, {
    fullWidth: fullWidth
  }, /*#__PURE__*/React.createElement(Map, {
    google: google,
    initialCenter: closestLocation,
    center: closestLocation,
    onReady: onReady
  }, markers, /*#__PURE__*/React.createElement(InfoWindow, {
    marker: selectedMarker,
    onClose: hideInfoWindow,
    visible: Boolean(selectedMarker),
    onOpen: onInfoWindowOpen
  }, selectedStore && /*#__PURE__*/React.createElement(InfoWindowContentWrapper, null, /*#__PURE__*/React.createElement(InfoWindowTitle, null, selectedStore.name), /*#__PURE__*/React.createElement(InfoWindowText, null, selectedStore.fullAddress), /*#__PURE__*/React.createElement(InfoWindowDistance, null, !isNaN(storeDistance) && storeDistance.toFixed(2) + ' km'), /*#__PURE__*/React.createElement(Button, {
    fullWidth: true,
    borderRadius: "large",
    small: true,
    className: "mt-3",
    bordered: true,
    target: "_blank",
    link: "https://www.google.com/maps/dir/" + selectedStore.latitude + "," + selectedStore.longitude
  }, labels.getDirectionsLabel), /*#__PURE__*/React.createElement("div", {
    id: "viewStoreBtn"
  })))));
};

export var StoresMap = GoogleApiWrapper({
  apiKey: ''
})(MapComponent);
var InfoWindowContentWrapper = styled.div.attrs({
  className: 'p-3'
})(_templateObject || (_templateObject = _taggedTemplateLiteralLoose(["\n  min-width: 14rem;\n  min-height: 10rem;\n  max-width: 25rem;\n\n  position: relative;\n\n  @media (min-width: ", ") {\n    min-height: 4rem;\n  }\n\n  button,\n  a {\n    font-size: 1.2rem !important;\n\n    @media (min-width: ", ") {\n      font-size: 1.6rem !important;\n    }\n  }\n"])), (_ref2) => {
  var _theme$breakpoints;

  var {
    theme
  } = _ref2;
  return (_theme$breakpoints = theme.breakpoints) == null ? void 0 : _theme$breakpoints.md.min;
}, (_ref3) => {
  var _theme$breakpoints2;

  var {
    theme
  } = _ref3;
  return (_theme$breakpoints2 = theme.breakpoints) == null ? void 0 : _theme$breakpoints2.md.min;
});
var InfoWindowTitle = styled.h2.attrs({
  className: 'mb-2'
})(_templateObject2 || (_templateObject2 = _taggedTemplateLiteralLoose(["\n  color: ", ";\n  font-weight: 500;\n  font-size: 1.6rem;\n\n  @media (min-width: ", ") {\n    font-size: 2.2rem;\n  }\n"])), (_ref4) => {
  var _theme$palette;

  var {
    theme
  } = _ref4;
  return (_theme$palette = theme.palette) == null ? void 0 : _theme$palette.primary;
}, (_ref5) => {
  var _theme$breakpoints3;

  var {
    theme
  } = _ref5;
  return (_theme$breakpoints3 = theme.breakpoints) == null ? void 0 : _theme$breakpoints3.md.min;
});
var InfoWindowText = styled.p.attrs({
  className: 'pb-2'
})(_templateObject3 || (_templateObject3 = _taggedTemplateLiteralLoose(["\n  color: ", ";\n  font-size: 1.4rem;\n\n  @media (min-width: ", ") {\n    font-size: 1.6rem;\n  }\n\n  & a {\n    &:hover {\n      text-decoration: underline;\n    }\n  }\n"])), (_ref6) => {
  var _theme$palette2;

  var {
    theme
  } = _ref6;
  return (_theme$palette2 = theme.palette) == null ? void 0 : _theme$palette2.primary;
}, (_ref7) => {
  var _theme$breakpoints4;

  var {
    theme
  } = _ref7;
  return (_theme$breakpoints4 = theme.breakpoints) == null ? void 0 : _theme$breakpoints4.md.min;
});
var InfoWindowDistance = styled.p.attrs({
  className: 'mt-1 mb-1'
})(_templateObject4 || (_templateObject4 = _taggedTemplateLiteralLoose(["\n  color: ", ";\n  font-size: 1.3rem;\n\n  @media (min-width: ", ") {\n    font-size: 1.6rem;\n  }\n"])), (_ref8) => {
  var _theme$palette3;

  var {
    theme
  } = _ref8;
  return (_theme$palette3 = theme.palette) == null ? void 0 : _theme$palette3.hint;
}, (_ref9) => {
  var _theme$breakpoints5;

  var {
    theme
  } = _ref9;
  return (_theme$breakpoints5 = theme.breakpoints) == null ? void 0 : _theme$breakpoints5.md.min;
});
var MapContainer = styled.div(_templateObject5 || (_templateObject5 = _taggedTemplateLiteralLoose(["\n  position: relative;\n  width: 100%;\n  height: 50rem;\n\n  @media (min-width: ", ") {\n    position: relative;\n    width: 100%;\n    max-height: 700px;\n    top: 0;\n    left: 0;\n\n    // the actual map\n    & > div {\n      position: absolute;\n      width: 100%;\n      max-height: 700px;\n      top: 0;\n      left: 0;\n    }\n  }\n\n  ", "\n\n  .gm-style-iw.gm-style-iw-c {\n    border-radius: 0 !important;\n  }\n\n  button.gm-ui-hover-effect {\n    top: 0.2rem !important;\n    right: 1rem !important;\n\n    img {\n      width: 2.2rem !important;\n      height: 2.2rem !important;\n    }\n  }\n"])), (_ref10) => {
  var _theme$breakpoints6;

  var {
    theme
  } = _ref10;
  return (_theme$breakpoints6 = theme.breakpoints) == null ? void 0 : _theme$breakpoints6.md.min;
}, props => props.fullWidth ? css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteralLoose(["\n          height: calc(100vh - 6rem);\n          position: absolute;\n        "]))) : css(_templateObject7 || (_templateObject7 = _taggedTemplateLiteralLoose(["\n          padding-bottom: 100%;\n          position: relative;\n        "]))));
//# sourceMappingURL=index.js.map