import { Host, h, } from "@stencil/core";
import { _t } from "../i18n/i18n";
import { findOrCreateOnReady } from "../utils";
export class AddressSearchBox {
  constructor() {
    this.callChange = () => this.handleChange();
    this.callFocus = () => this.handleFocus();
    this.callClick = (e) => this.handleClick(e);
    this.mode = undefined;
    this.bboxArray = undefined;
    this.hasFocus = false;
    this.hasValue = false;
    this.results = [];
    this.bbox = undefined;
    this.jobId = "gl-address-search";
    this.limit = 10;
    this.maxZoom = 18;
    this.placeholder = _t("webmapgl.address-search.prompt");
    this.url = undefined;
    this.zoomPadding = 20;
  }
  async componentWillLoad() {
    this.parseBbox();
    if (this.lazyGeocodeCtrl == undefined)
      this.lazyGeocodeCtrl = await findOrCreateOnReady("gl-geocode-controller");
  }
  async handleGeocode(e) {
    if (e.detail.options.jobId === this.jobId)
      this.results = e.detail.response;
  }
  handleBodyClick() {
    this.hasFocus = false;
  }
  handleKey(e) {
    if (e.key === "ArrowUp")
      this.handleUp(e);
    else if (e.key === "ArrowDown")
      this.handleDown(e);
  }
  handleDown(e) {
    let nextItem;
    if (document.activeElement.tagName === "ION-ITEM") {
      this.unsetFocus();
      nextItem = document.activeElement.nextElementSibling;
    }
    if (nextItem == undefined)
      nextItem = this.el.querySelector("ion-item");
    if (nextItem != null) {
      e.preventDefault();
      this.setFocus(nextItem);
    }
  }
  handleUp(e) {
    if (document.activeElement.tagName === "ION-ITEM") {
      e.preventDefault();
      this.unsetFocus();
      let prevItem = document.activeElement.previousElementSibling;
      if (prevItem != undefined) {
        this.setFocus(prevItem);
      }
      else if (this.input != undefined) {
        this.input.querySelector("input").focus();
      }
    }
  }
  parseBbox() {
    this.bboxArray =
      typeof this.bbox === "string"
        ? this.bbox.split(",").map((c) => parseFloat(c))
        : this.bbox;
  }
  setFocus(el) {
    let button = el.shadowRoot.querySelector("button");
    button.focus();
    button.style.color = "#3880ff";
  }
  unsetFocus() {
    let button = document.activeElement.shadowRoot.querySelector("button");
    button.style.color = null;
  }
  formatAddress(address, displayName) {
    let parts = [];
    if (address.name != null && address.name !== address.city)
      parts.push(address.name);
    if (address.street != null) {
      parts.push(address.housenumber != null
        ? address.housenumber + " " + address.street
        : address.street);
    }
    if (address.city != null)
      parts.push(address.city);
    if (parts.length !== 0 && address.county != null)
      parts.push(address.county);
    if (parts.length !== 0)
      return parts.join(", ");
    else
      return displayName;
  }
  async selectResult(result) {
    let mapEl = this.el.closest("gl-map");
    mapEl.map.fitBounds(result.bbox, {
      maxZoom: this.maxZoom,
      padding: this.zoomPadding,
    });
    this.hasFocus = false;
  }
  async geocode() {
    this.lazyGeocodeCtrl.forward({
      address: this.input.value,
      url: this.url,
      bbox: this.bboxArray,
      bounded: true,
      jobId: this.jobId,
      limit: this.limit,
    });
  }
  resultButtonFunction(result) {
    return () => this.selectResult(result);
  }
  renderResults() {
    if (this.results.length === 0 || !this.hasValue || !this.hasFocus)
      return null;
    let items = this.results.map((result) => (h("ion-item", { button: true, onClick: this.resultButtonFunction(result) }, h("ion-icon", { name: "pin", slot: "start" }), h("ion-label", null, this.formatAddress(result.address, result.display)))));
    return h("ion-list", { lines: "full" }, items);
  }
  handleChange() {
    var _a;
    if (((_a = this.input) === null || _a === void 0 ? void 0 : _a.value) != undefined) {
      this.hasValue = true;
      this.geocode();
    }
    else {
      this.hasValue = false;
      if (this.results.length !== 0)
        this.results = [];
    }
  }
  handleFocus() {
    this.hasFocus = true;
  }
  handleClick(e) {
    // Prevent propagation of click events from the searchbar so that
    // it does not lose focus.
    e.stopPropagation();
  }
  render() {
    return (h(Host, null, h("ion-searchbar", { ref: (r) => (this.input = r), placeholder: this.placeholder, onIonChange: this.callChange, onIonFocus: this.callFocus, onClick: this.callClick }), this.renderResults()));
  }
  static get is() { return "gl-address-search"; }
  static get originalStyleUrls() {
    return {
      "ios": ["address-search.ios.css"],
      "md": ["address-search.md.css"]
    };
  }
  static get styleUrls() {
    return {
      "ios": ["address-search.ios.css"],
      "md": ["address-search.md.css"]
    };
  }
  static get properties() {
    return {
      "mode": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "Mode",
          "resolved": "\"ios\" | \"md\"",
          "references": {
            "Mode": {
              "location": "import",
              "path": "@ionic/core",
              "id": ""
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [{
              "name": "virtualProp",
              "text": "{\"ios\" | \"md\"} mode - The mode determines which platform styles to use."
            }],
          "text": ""
        },
        "attribute": "mode",
        "reflect": false
      },
      "bbox": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "[number, number, number, number] | string",
          "resolved": "[number, number, number, number] | string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Bounding box for the search in the format [west, south, east, north]."
        },
        "attribute": "bbox",
        "reflect": false
      },
      "jobId": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Identifier for the geocode operation."
        },
        "attribute": "job-id",
        "reflect": false,
        "defaultValue": "\"gl-address-search\""
      },
      "limit": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Maximum number of results to display."
        },
        "attribute": "limit",
        "reflect": false,
        "defaultValue": "10"
      },
      "maxZoom": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Maximum level the map will zoom to when a result is selected (e.g., for point results)."
        },
        "attribute": "max-zoom",
        "reflect": false,
        "defaultValue": "18"
      },
      "placeholder": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Placeholder text displayed in the input element."
        },
        "attribute": "placeholder",
        "reflect": false,
        "defaultValue": "_t(\"webmapgl.address-search.prompt\")"
      },
      "url": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "URL of the geocoding endpoint."
        },
        "attribute": "url",
        "reflect": false
      },
      "zoomPadding": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Padding in pixels used when zooming to a selected result."
        },
        "attribute": "zoom-padding",
        "reflect": false,
        "defaultValue": "20"
      }
    };
  }
  static get states() {
    return {
      "bboxArray": {},
      "hasFocus": {},
      "hasValue": {},
      "results": {}
    };
  }
  static get elementRef() { return "el"; }
  static get watchers() {
    return [{
        "propName": "bbox",
        "methodName": "parseBbox"
      }];
  }
  static get listeners() {
    return [{
        "name": "glForwardGeocode",
        "method": "handleGeocode",
        "target": "body",
        "capture": false,
        "passive": false
      }, {
        "name": "click",
        "method": "handleBodyClick",
        "target": "body",
        "capture": false,
        "passive": false
      }, {
        "name": "keydown",
        "method": "handleKey",
        "target": undefined,
        "capture": false,
        "passive": false
      }];
  }
}
//# sourceMappingURL=address-search.js.map
