import { h } from "@stencil/core";
import { LazyMapsAPILoader } from "../../utils/google-maps-loader";
import { buildDescribedByString, listToObject } from "@boldpenguin/sdk-utility";
export class BpSdkGooglePlacesAutocomplete {
    constructor() {
        this.handlePlaceChanged = () => this.onPlaceChanged();
        this.onChange = (e) => {
            this.valueUpdate.emit(e.target.value);
        };
        this.answerId = undefined;
        this.autoComplete = undefined;
        this.code = undefined;
        this.labelId = undefined;
        this.placeholder = '';
        this.googleApiKey = undefined;
        this.filter = undefined;
        this.label = undefined;
        this.labelledBy = undefined;
        this.required = undefined;
        this.errors = [];
        this.errorText = undefined;
        this.touched = false;
        this.pristine = true;
        this.isCompleted = false;
        this.isReadOnly = false;
        this.questionId = undefined;
        this.fieldType = undefined;
        this.min = -1;
        this.max = -1;
        this.helpText = undefined;
        this.answeredBySource = undefined;
        this.autocomplete = undefined;
        this._labelledBy = undefined;
        this.placeChangedEvent = undefined;
        this.value = undefined;
        this.isLoaded = false;
        this.useExternal = false;
    }
    setupAutocomplete() {
        this.autocomplete = new google.maps.places.Autocomplete(this.el.querySelector('.bp-sdk-google-places-autocomplete__input'), {
            componentRestrictions: { country: 'us' },
            types: ['premise', 'street_address'],
            fields: ['address_component'],
        });
        this.placeChangedEvent = this.autocomplete.addListener('place_changed', this.handlePlaceChanged);
    }
    resetState() {
        this.value = undefined;
    }
    connectedCallback() {
        this.resetState();
    }
    componentWillLoad() {
        this.useExternal = !!customElements.get('bp-sdk-external-google-places-autocomplete');
        customElements.whenDefined('bp-sdk-external-google-places-autocomplete').then(() => {
            this.useExternal = true;
        });
        this.onAriaLabelledByChange(this.labelId);
        this.onLabelledByChange(this.labelledBy);
    }
    getAutocompletePacContainer(autocomplete) {
        // https://stackoverflow.com/questions/21024090/google-places-autocomplete-how-to-clean-up-pac-container
        const place = autocomplete.gm_accessors_.place;
        const placeKey = Object.keys(place).find((value) => ((typeof (place[value]) === 'object') && Object.prototype.hasOwnProperty.call(place[value], 'gm_accessors_')));
        const input = place[placeKey].gm_accessors_.input[placeKey];
        const inputKey = Object.keys(input).find((value) => ((input[value].classList && input[value].classList.contains('pac-container'))));
        return input[inputKey];
    }
    disconnectedCallback() {
        if (this.placeChangedEvent) {
            window.google.maps.event.removeListener(this.placeChangedEvent);
        }
        if (this.autocomplete) {
            const pacContainer = this.getAutocompletePacContainer(this.autocomplete);
            if (pacContainer && pacContainer.remove) {
                pacContainer.remove();
            }
            this.autocomplete.unbindAll();
        }
    }
    componentDidLoad() {
        this.isLoaded = true;
    }
    onAriaLabelledByChange(labelId) {
        this.updateLabelledBy(labelId, this.labelledBy);
    }
    onLabelledByChange(labelledBy) {
        this.updateLabelledBy(this.labelId, labelledBy);
    }
    updateLabelledBy(aria, ids) {
        const prefix = ids ? `${ids} ` : '';
        this._labelledBy = `${prefix}${aria !== null && aria !== void 0 ? aria : ''}` || undefined;
    }
    onIsLoadedChange(isLoaded) {
        if (isLoaded) {
            this.onGoogleApiKeyChange(this.googleApiKey);
        }
    }
    async onGoogleApiKeyChange(token) {
        if (token && this.isLoaded) {
            const loader = new LazyMapsAPILoader();
            loader.apiKey = this.googleApiKey;
            loader.libraries = ['places'];
            await loader.load();
            if (!this.isReadOnly) {
                this.setupAutocomplete();
            }
        }
    }
    onPlaceChanged() {
        if (this.useExternal) {
            return;
        }
        const place = this.autocomplete.getPlace();
        if (JSON.stringify(this.value) !== JSON.stringify(place)) {
            this.value = place;
            if (place.name) {
                this.valueUpdate.emit(place.name);
            }
            this.placesUpdate.emit(this.value);
        }
    }
    render() {
        return [this.useExternal && this.renderExternal(), !this.useExternal && this.renderInternal()];
    }
    renderExternal() {
        return (h("bp-sdk-external-google-places-autocomplete", { answeredBySource: this.answeredBySource, answerId: this.answerId, autoComplete: this.autoComplete, code: this.code, errorText: this.errorText, errors: this.errors, fieldType: this.fieldType, filter: this.filter, googleApiKey: this.googleApiKey, helpText: this.helpText, isCompleted: this.isCompleted, isReadOnly: this.isReadOnly, labelId: this.labelId, label: this.label, labelledBy: this.labelledBy, max: this.max, min: this.min, pristine: this.pristine, placeholder: this.placeholder, questionId: this.questionId, required: this.required, touched: this.touched }));
    }
    renderLabel() {
        return (h("label", { id: this.labelId, htmlFor: `bp-sdk-google-places-autocomplete__${this.labelId}__input`, class: "bp-sdk-label bp-sdk-google-places-autocomplete__label", innerHTML: this.label }));
    }
    renderHiddenInput() {
        var _a, _b;
        return (h("input", { "aria-hidden": true, autocomplete: this.autoComplete, tabindex: "-1", class: "bp-sdk-hidden", maxLength: (_a = this.max) !== null && _a !== void 0 ? _a : -1, minLength: (_b = this.min) !== null && _b !== void 0 ? _b : -1, name: this.code, onChange: this.onChange, onInput: this.onChange, onPaste: this.onChange, placeholder: this.placeholder || '', type: "text", value: this.filter }));
    }
    renderVisibleInput() {
        var _a, _b;
        return (h("input", { "aria-describedby": buildDescribedByString(listToObject(this.errors)) || undefined, "aria-label": this.placeholder && !this.label ? this.placeholder : null, "aria-labelledby": this._labelledBy, class: "bp-sdk-google-places-autocomplete__input", id: `bp-sdk-google-places-autocomplete__${this.labelId}__input`, maxLength: (_a = this.max) !== null && _a !== void 0 ? _a : -1, minLength: (_b = this.min) !== null && _b !== void 0 ? _b : -1, name: this.code, onChange: this.onChange, onInput: this.onChange, onPaste: this.onChange, placeholder: this.placeholder || '', required: this.required, type: "text", value: this.filter }));
    }
    renderInput() {
        return [this.renderHiddenInput(), this.renderVisibleInput()];
    }
    renderInternal() {
        var _a;
        const input = this.isReadOnly ? this.renderReadOnlyElement(this.filter) : this.renderInput();
        return (h("div", { class: "bp-sdk-google-places-autocomplete__container" }, this.renderLabel(), input, this.touched && !this.pristine && ((this.errorText && !this.isCompleted) || !!((_a = this.errors) === null || _a === void 0 ? void 0 : _a.length)) && (h("bp-sdk-errors-container", { answerId: this.answerId, questionId: this.questionId, fieldType: this.fieldType, min: this.min, max: this.max, errors: this.errors, errorText: this.errorText }))));
    }
    renderReadOnlyElement(value) {
        return h("span", { class: "read-only-value" }, value);
    }
    static get is() { return "bp-sdk-google-places-autocomplete"; }
    static get originalStyleUrls() {
        return {
            "$": ["bp-sdk-google-places-autocomplete.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["bp-sdk-google-places-autocomplete.css"]
        };
    }
    static get properties() {
        return {
            "answerId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Answer id"
                },
                "attribute": "answer-id",
                "reflect": false
            },
            "autoComplete": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Autocomplete attribute value for input"
                },
                "attribute": "auto-complete",
                "reflect": false
            },
            "code": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Question code"
                },
                "attribute": "code",
                "reflect": false
            },
            "labelId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Aria label by id"
                },
                "attribute": "label-id",
                "reflect": false
            },
            "placeholder": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "placeholder text"
                },
                "attribute": "placeholder",
                "reflect": false,
                "defaultValue": "''"
            },
            "googleApiKey": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "google api key, if no key library is not loaded"
                },
                "attribute": "google-api-key",
                "reflect": false
            },
            "filter": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Filter text"
                },
                "attribute": "filter",
                "reflect": false
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Label to use"
                },
                "attribute": "label",
                "reflect": false
            },
            "labelledBy": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Labels that describe group"
                },
                "attribute": "labelled-by",
                "reflect": false
            },
            "required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Is required"
                },
                "attribute": "required",
                "reflect": false
            },
            "errors": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "string[]",
                    "resolved": "string[]",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Error messages"
                },
                "defaultValue": "[]"
            },
            "errorText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Error text"
                },
                "attribute": "error_text",
                "reflect": false
            },
            "touched": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "is touched"
                },
                "attribute": "touched",
                "reflect": false,
                "defaultValue": "false"
            },
            "pristine": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "is pristine"
                },
                "attribute": "pristine",
                "reflect": false,
                "defaultValue": "true"
            },
            "isCompleted": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Is answer in complete state"
                },
                "attribute": "is_completed",
                "reflect": false,
                "defaultValue": "false"
            },
            "isReadOnly": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "When true, the field will be readonly. It will display only the label and value as plain text."
                },
                "attribute": "is-read-only",
                "reflect": false,
                "defaultValue": "false"
            },
            "questionId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Question id"
                },
                "attribute": "question_id",
                "reflect": false
            },
            "fieldType": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Field type"
                },
                "attribute": "field_type",
                "reflect": false
            },
            "min": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "minimum length of input"
                },
                "attribute": "min_value",
                "reflect": false,
                "defaultValue": "-1"
            },
            "max": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "maximum length of input"
                },
                "attribute": "max_value",
                "reflect": false,
                "defaultValue": "-1"
            },
            "helpText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Help text"
                },
                "attribute": "help-text",
                "reflect": false
            },
            "answeredBySource": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string | undefined",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Specifically how the question was answered (ie. \"ACORD 126\")"
                },
                "attribute": "answered-by-source",
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "autocomplete": {},
            "_labelledBy": {},
            "placeChangedEvent": {},
            "value": {},
            "isLoaded": {},
            "useExternal": {}
        };
    }
    static get events() {
        return [{
                "method": "valueUpdate",
                "name": "valueUpdate",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                }
            }, {
                "method": "placesUpdate",
                "name": "placesUpdate",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "any",
                    "resolved": "any",
                    "references": {}
                }
            }];
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "labelId",
                "methodName": "onAriaLabelledByChange"
            }, {
                "propName": "labelledBy",
                "methodName": "onLabelledByChange"
            }, {
                "propName": "isLoaded",
                "methodName": "onIsLoadedChange"
            }, {
                "propName": "googleApiKey",
                "methodName": "onGoogleApiKeyChange"
            }];
    }
    static get listeners() {
        return [{
                "name": "place_changed",
                "method": "onPlaceChanged",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
