import { _t } from '../i18n/i18n';
export class AddressSearchBox {
    constructor() {
        this.hasFocus = false;
        this.hasValue = false;
        this.results = [];
        this.jobId = 'gl-address-search';
        this.limit = 10;
        this.maxZoom = 18;
        this.placeholder = _t('webmapgl.address-search.prompt');
        this.zoomPadding = 20;
    }
    async componentWillLoad() {
        this.parseBbox();
        this.geocodeCtrl = await this.lazyGeocodeCtrl.componentOnReady();
    }
    async handleGeocode(e) {
        if (e.detail.options.jobId === this.jobId)
            this.results = e.detail.response;
    }
    handleBodyClick() {
        this.hasFocus = false;
    }
    handleDown(e) {
        let nextItem;
        if (document.activeElement.tagName === 'ION-ITEM') {
            this.unsetFocus();
            nextItem = document.activeElement.nextElementSibling;
        }
        if (!nextItem)
            nextItem = this.el.querySelector('ion-item');
        if (nextItem) {
            e.preventDefault();
            this.setFocus(nextItem);
        }
    }
    handleUp(e) {
        if (document.activeElement.tagName === 'ION-ITEM') {
            e.preventDefault();
            this.unsetFocus();
            let prevItem = document.activeElement.previousElementSibling;
            if (prevItem) {
                this.setFocus(prevItem);
            }
            else if (this.input) {
                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) {
        let parts = [];
        if (address.name &&
            address.name != address.city)
            parts.push(address.name);
        if (address.street) {
            let part = address.street;
            if (address.housenumber)
                part = address.housenumber + ' ' + part;
            parts.push(part);
        }
        if (address.city)
            parts.push(address.city);
        if (!parts.length && address.county)
            parts.push(address.county);
        if (parts.length)
            return parts.join(', ');
        return address.display;
    }
    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.geocodeCtrl.forward({
            address: this.input.value,
            url: this.url,
            bbox: this.bboxArray,
            bounded: true,
            jobId: this.jobId,
            limit: this.limit
        });
    }
    renderResults() {
        if (!this.results.length || !this.hasValue || !this.hasFocus)
            return null;
        let items = this.results.map((result) => (h("ion-item", { button: true, onClick: () => this.selectResult(result) },
            h("ion-icon", { name: "pin", slot: "start" }),
            h("ion-label", null, this.formatAddress(result.address)))));
        return (h("ion-list", { lines: "full" }, items));
    }
    handleChange() {
        if (this.input && this.input.value) {
            this.hasValue = true;
            this.geocode();
        }
        else {
            this.hasValue = false;
            if (this.results.length)
                this.results = [];
        }
    }
    handleFocus() {
        this.hasFocus = true;
    }
    handleClick(e) {
        e.stopPropagation();
    }
    render() {
        return ([
            h("ion-searchbar", { ref: (r) => this.input = r, placeholder: this.placeholder, onIonChange: () => this.handleChange(), onIonFocus: () => this.handleFocus(), onClick: (e) => this.handleClick(e) }),
            this.renderResults()
        ]);
    }
    static get is() { return "gl-address-search"; }
    static get properties() { return {
        "bbox": {
            "type": String,
            "attr": "bbox",
            "watchCallbacks": ["parseBbox"]
        },
        "bboxArray": {
            "state": true
        },
        "el": {
            "elementRef": true
        },
        "hasFocus": {
            "state": true
        },
        "hasValue": {
            "state": true
        },
        "jobId": {
            "type": String,
            "attr": "job-id"
        },
        "lazyGeocodeCtrl": {
            "connect": "gl-geocode-controller"
        },
        "limit": {
            "type": Number,
            "attr": "limit"
        },
        "maxZoom": {
            "type": Number,
            "attr": "max-zoom"
        },
        "placeholder": {
            "type": String,
            "attr": "placeholder"
        },
        "results": {
            "state": true
        },
        "url": {
            "type": String,
            "attr": "url"
        },
        "zoomPadding": {
            "type": Number,
            "attr": "zoom-padding"
        }
    }; }
    static get listeners() { return [{
            "name": "body:glForwardGeocode",
            "method": "handleGeocode"
        }, {
            "name": "body:click",
            "method": "handleBodyClick"
        }, {
            "name": "keydown.down",
            "method": "handleDown"
        }, {
            "name": "keydown.up",
            "method": "handleUp"
        }]; }
    static get style() { return "/**style-placeholder:gl-address-search:**/"; }
    static get styleMode() { return "/**style-id-placeholder:gl-address-search:**/"; }
}
