import { FlowCoreMap } from '@emuanalytics/flow-rdf-core';
import { html } from 'lit';
import { state, property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { boolean } from '../../internal/boolean.mjs';
import FlowRdfElement from '../../internal/flow-ui-rdf-element.mjs';
import { watch } from '../../internal/watch.mjs';
import styles from './map.styles.mjs';

var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result)
    __defProp(target, key, result);
  return result;
};
let mapIdCounter = 0;
class FlowUiMap extends FlowRdfElement {
  constructor() {
    super();
    this._mapLoading = false;
    this.baseStyle = "fjord";
    this.center = [-0.1, 51.5];
    this.zoom = 9;
    this.busy = false;
    this.fixed = false;
    this.bearingSnap = 7;
    this.fadeDuration = 300;
    this._initialized = new Promise((resolve) => {
      this._resolveInitialized = resolve;
    });
  }
  /**
   * The underlying core FlowCoreMap instance. Note that this is
   * `undefined` until the map has been initialized.
   */
  get map() {
    return this._map;
  }
  /**
   * A promise that resolves to a map instance when the map has been initialized.
   *
   * This is the safest way to retrieve the underlying core FlowCoreMap instance before
   * using its API.
   */
  get initialized() {
    return this._initialized;
  }
  handleCenterChange() {
    const center = {
      lng: this.center[0],
      lat: this.center[1],
      bearing: this.bearing,
      pitch: this.pitch,
      zoom: this.zoom
    };
    if (this._map) {
      this._map.setCenter(center);
    } else {
      this._pendingCenter = center;
    }
  }
  handleBaseStyleChange() {
    if (this._map) {
      this._map.setBaseStyle(this.baseStyle);
    } else {
      this._pendingBaseStyle = this.baseStyle;
    }
  }
  async connectedCallback() {
    super.connectedCallback();
    this.busy = boolean(this.busy, true);
    this.fixed = boolean(this.fixed, true);
    await this.updateComplete;
    this._map = await this.initializeMap();
    this._resolveInitialized(this._map);
    this.emit("flow-ui-map-load", { detail: { map: this._map } });
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    if (this._map) {
      this._map.destroy();
      this._map = void 0;
    }
  }
  async initializeMap() {
    const mapContainer = document.createElement("div");
    mapContainer.slot = "map";
    this.appendChild(mapContainer);
    const map = new FlowCoreMap({
      id: this.mapId ?? `flow-map-${mapIdCounter++}`,
      container: mapContainer,
      baseStyle: this.baseStyle,
      center: this.center,
      zoom: this.zoom,
      bearingSnap: this.bearingSnap,
      fadeDuration: this.fadeDuration
    });
    await map.initialized;
    if (this._pendingCenter) {
      map.setCenter(this._pendingCenter);
      this._pendingCenter = void 0;
    }
    if (this._pendingBaseStyle) {
      map.setBaseStyle(this._pendingBaseStyle);
      this._pendingBaseStyle = void 0;
    }
    map.on("loading", (ev) => {
      this._mapLoading = ev.loading;
    });
    return map;
  }
  render() {
    const showBusyIndicator = this.busy || this._mapLoading;
    return html`
      <div
        part="base"
        class=${classMap({
      map: true,
      "map--fixed": this.fixed
    })}
      >
        <div class="map__container">
          <slot name="map"></slot>
        </div>

        <div class="map__overlay">
          <flow-ui-progress-bar
            part="busy-indicator"
            class=${classMap({ "map__busy-indicator": true, "map__busy-indicator--busy": showBusyIndicator })}
            indeterminate
          ></flow-ui-progress-bar>
          <div class="map__control-containers">
            <div
              part="control-container control-container--top-left"
              class="map__control-container map__control-container--top-left"
            >
              <slot name="top-left"></slot>
            </div>
            <div
              part="control-container control-container--top-right"
              class="map__control-container map__control-container--top-right"
            >
              <slot name="top-right"></slot>
            </div>
            <div
              part="control-container control-container--bottom-left"
              class="map__control-container map__control-container--bottom-left"
            >
              <slot name="bottom-left"></slot>
            </div>
            <div
              part="control-container control-container--bottom-right"
              class="map__control-container map__control-container--bottom-right"
            >
              <slot name="bottom-right"></slot>
            </div>
          </div>
        </div>
      </div>
    `;
  }
}
FlowUiMap.styles = styles;
__decorateClass([
  state()
], FlowUiMap.prototype, "_mapLoading", 2);
__decorateClass([
  property({ attribute: "map-id" })
], FlowUiMap.prototype, "mapId", 2);
__decorateClass([
  property({ attribute: "base-style" })
], FlowUiMap.prototype, "baseStyle", 2);
__decorateClass([
  property({
    converter: {
      fromAttribute: (value) => value.split(",").map((n) => parseFloat(n)),
      toAttribute: (value) => value.map((n) => n.toString()).join(",")
    }
  })
], FlowUiMap.prototype, "center", 2);
__decorateClass([
  property({ type: Number })
], FlowUiMap.prototype, "zoom", 2);
__decorateClass([
  property({ type: Number })
], FlowUiMap.prototype, "bearing", 2);
__decorateClass([
  property({ type: Number })
], FlowUiMap.prototype, "pitch", 2);
__decorateClass([
  property({ type: Boolean })
], FlowUiMap.prototype, "busy", 2);
__decorateClass([
  property({ type: Boolean })
], FlowUiMap.prototype, "fixed", 2);
__decorateClass([
  property({ type: Number, attribute: "bearing-snap" })
], FlowUiMap.prototype, "bearingSnap", 2);
__decorateClass([
  property({ type: Number, attribute: "fade-duration" })
], FlowUiMap.prototype, "fadeDuration", 2);
__decorateClass([
  watch(["center", "zoom", "bearing", "pitch"])
], FlowUiMap.prototype, "handleCenterChange", 1);
__decorateClass([
  watch(["baseStyle"])
], FlowUiMap.prototype, "handleBaseStyleChange", 1);

export { FlowUiMap as default };
