'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const index = require('./index-0c149d29.js');
const index$1 = require('./index-90d5547f.js');

const mapCss = "fireenjin-map{position:relative;display:block}fireenjin-map #map{display:block;height:0px;width:100%;margin:0 auto;opacity:0;transition:all ease 0.5s}fireenjin-map.map-is-visible #map{height:var(--map-height, 300px);opacity:1}";

let Map = class {
  constructor(hostRef) {
    index.registerInstance(this, hostRef);
    this.fireenjinTrigger = index.createEvent(this, "fireenjinTrigger", 7);
    /**
     * The current list of map markers
     */
    this.mapMarkers = [];
    /**
     * Google Maps options
     */
    this.optins = {};
    /**
     * Should the map be visible?
     */
    this.visible = true;
    /**
     * A list of markers to put onto the map
     */
    this.markers = [];
    /**
     * Is the map currently visible?
     */
    this.isVisible = true;
  }
  /**
   * Add a marker to the map
   * @param location The location information for the marker on the map
   */
  async addMarker(location) {
    const marker = typeof location === "string" ? JSON.parse(location) : location;
    const mapMarker = new google.maps.Marker({
      position: marker.position,
      map: this.map,
      title: (marker === null || marker === void 0 ? void 0 : marker.name) || "",
      icon: (marker === null || marker === void 0 ? void 0 : marker.icon) ? {
        url: marker.icon,
        origin: new google.maps.Point(0, 0),
        anchor: new google.maps.Point(15, 15),
        scaledSize: new google.maps.Size(34, 34),
        shape: { coords: [17, 17, 18], type: "circle" },
        optimized: false,
      } : null,
    });
    mapMarker.addListener("click", () => {
      this.onMarkerClick(mapMarker, marker);
    });
    this.mapMarkers.push(mapMarker);
    return mapMarker;
  }
  async updateMarkers() {
    await this.clearMarkers();
    if (this.markers.length >= 1) {
      this.markers.map(this.addMarker.bind(this));
    }
    return this.markers;
  }
  /**
   * Set the list of map markers
   * @param markers A list of map markers
   */
  async setMarkers(markers = []) {
    this.markers = markers;
    await this.clearMarkers();
    if (this.markers.length >= 1) {
      this.markers.map(this.addMarker.bind(this));
    }
    return this.markers;
  }
  async setZoom(level) {
    return this.map.setZoom(level);
  }
  async setCenter(latLng) {
    return this.map.setCenter(latLng);
  }
  /**
   * Clear the markers off of the map
   */
  async clearMarkers() {
    var _a;
    for (let i = 0; i < this.mapMarkers.length; i++) {
      if (!((_a = this.mapMarkers[i]) === null || _a === void 0 ? void 0 : _a.setMap))
        continue;
      this.mapMarkers[i].setMap(null);
    }
    this.mapMarkers = [];
    return true;
  }
  /**
   * When a marker is clicked set the zoom level,
   * animate to center, and emit an event
   * @param marker The map marker that has been clicked
   * @param location The location information tied to the map marker
   */
  onMarkerClick(marker, location) {
    this.map.setZoom(12);
    this.map.setCenter(marker.getPosition());
    this.fireenjinTrigger.emit({
      trigger: "markerClick",
      payload: {
        marker,
        location,
      }
    });
  }
  /**
   * Get a device's location via Geolocation api and
   * fallback to location based on IP
   * @param callback The function to run when the location is determined
   */
  getLocationCoords(callback) {
    try {
      index$1.Geolocation.getCurrentPosition()
        .then((position) => {
        if (callback && typeof callback === "function") {
          callback(position.coords);
        }
      })
        .catch(async (_error) => {
        fetch("http://ip-api.com/json").then(async (response) => {
          const ISPInfo = await response.json();
          callback({
            latitude: ISPInfo.lat,
            longitude: ISPInfo.lon,
          });
        });
        if (callback && typeof callback === "function") {
          callback(false);
        }
      });
    }
    catch (error) {
      callback(false);
    }
  }
  /**
   * Create the instance of Google Maps
   * @param position The latitude and longitude to center the map on
   */
  createMap(position) {
    this.map = new google.maps.Map(this.mapEl.querySelector("#map"), {
      zoom: 9,
      center: {
        lat: position.latitude,
        lng: position.longitude,
      },
    });
  }
  async loadGoogleMaps() {
    return new Promise((resolve, reject) => {
      try {
        // Create the script tag, set the appropriate attributes
        var script = document.createElement('script');
        script.src = `https://maps.googleapis.com/maps/api/js?key=${this.apiKey}&callback=initMap`;
        script.async = true;
        // Attach your callback function to the `window` object
        window.initMap = () => {
          // JS API is loaded and available
          resolve({});
        };
        // Append the 'script' element to 'head'
        document.head.appendChild(script);
      }
      catch (error) {
        reject(error);
      }
    });
  }
  componentDidLoad() {
    {
      this.isVisible = this.visible;
      this.getLocationCoords(async (coords) => {
        var _a;
        this.position = coords
          ? coords
          : { latitude: 38.6270025, longitude: -90.19940419999999 };
        if (!((_a = window === null || window === void 0 ? void 0 : window.google) === null || _a === void 0 ? void 0 : _a.maps) && this.apiKey)
          await this.loadGoogleMaps();
        this.createMap(this.position);
        await this.setMarkers(this.markers);
      });
    }
  }
  render() {
    return (index.h(index.Host, { class: { "map-is-visible": this.isVisible } }, index.h("div", { id: "map" })));
  }
  get mapEl() { return index.getElement(this); }
  static get watchers() { return {
    "markers": ["updateMarkers"]
  }; }
};
Map.style = mapCss;

exports.fireenjin_map = Map;
