import Browser from "../modules/browser";
import getService from "../libs/get-service";
import findClosestMarker from "../libs/closest-marker";

class NEAREST_CASINO
{
  constructor($el)
  {
    this.$el = $el;
    this.$casinoCityLabelElement = $el.find(".js-nearest-casino-city");
    this.$casinoAnchorElement = $el.find(".js-nearest-casino-url");
    this.form = $el.find(".loc1-form").get(0);
    this.searchInput = $el.find(".loc1-form-search").get(0);
    this.markers = [];

    this.initGooglePlaceAutoComplete();
    this.getCasinoMarkers().then(markers => {

      this.markers = markers;
      this.getMyPosition(markers);
    });
    this.form.addEventListener("submit", e => e.preventDefault());
  }

  findClosestCasino(coordinates, options = { redirectToMap: false })
  {
    const { redirectToMap } = options;
    const closestMarker = findClosestMarker(coordinates, this.markers);
    const urlType = this.$casinoAnchorElement.data("url-type") || "casino"; // casino, gamesCategories, shows, restaurantsandbars
    const url = redirectToMap ? Browser.appendQueryParamsToURL(this.$el.data("map-url"), coordinates) : closestMarker.url[urlType];

    this.$casinoAnchorElement.attr("href", url);
    this.$casinoCityLabelElement.html(closestMarker.city);
    this.showNearestCasinoFoundBlock();

    // show all blocks with geolocation needed
    $('.js-has-geoloc').show();
    $('.js-has-not-geoloc').hide();
  }

  getCasinoMarkers()
  {
    return new Promise(resolve => {

      getService("casinos").done(casinos => {

        const markers = casinos.map(c => ({
          city: c.city,
          lat: c.latitude,
          lng: c.longitude,
          url: c.links
        }));

        resolve(markers);
      });
    });
  }

  // TODO: refactor this method
  getMyPosition()
  {
    if ("geolocation" in navigator)
    {
      // let's go
      navigator.geolocation.getCurrentPosition(
        position => {

          this.findClosestCasino({
            lat: position.coords.latitude,
            lng: position.coords.longitude
          });
        },
        this.errorCallback.bind(this));
    }
    else
    {
      alert("Le service de géolocalisation n'est pas disponible sur votre ordinateur.");
      this.showNearestCasinoSearchBlock();
    }
  }

  initGooglePlaceAutoComplete()
  {
    const googleSearchBox = new google.maps.places.SearchBox(this.searchInput);

    // Listen for the event fired when the user selects a prediction and retrieve
    // more details for that place.
    googleSearchBox.addListener("places_changed", () => {

      const places = googleSearchBox.getPlaces();

      if (places.length === 0)
      {
        return;
      }

      const location = places[0].geometry.location;
      const coordinates = { lat: location.lat(), lng: location.lng() };
      const options = { redirectToMap: true };

      this.findClosestCasino(coordinates, options);
    });
  }

  // TODO: refactor this method
  showNearestCasinoFoundBlock()
  {
    $('.js-nearest-casino-found').show();
    $('.js-nearest-casino-search').hide();
  }

  // TODO: refactor this method
  showNearestCasinoSearchBlock()
  {
    $('.js-nearest-casino-found').hide();
    $('.js-nearest-casino-search').show();
  }

  // TODO: refactor this method
  errorCallback()
  {
    this.showNearestCasinoSearchBlock();
  }
}

export default NEAREST_CASINO;
