import { getVehicleOptionsModels, getVehicleOptionsSelection } from "@boldpenguin/sdk-redux";
import { YmmcUpdateType, } from "@boldpenguin/sdk-types";
import { hasRequiredError, hasValueChanged } from "@boldpenguin/sdk-utility";
import { h } from "@stencil/core";
import store from "../../services/redux-store.service";
export class BpSdkVehicleModelsContainer {
    constructor() {
        this.handleSubscriptions = () => {
            this.storeUnsubscribe && this.storeUnsubscribe();
            this.storeUnsubscribe = store.mapStateToProps(this, this.mapStateToProps);
        };
        this.mapStateToProps = (state) => {
            return {
                modelOptions: getVehicleOptionsModels(state, this.questionGroupId),
                selectedVehicle: getVehicleOptionsSelection(state, this.questionGroupId),
            };
        };
        this.onFocusOut = () => {
            this.touched = true;
            this.updateErrors(this.pristine, true, this.value);
        };
        this.answerId = undefined;
        this.code = undefined;
        this.modelOptions = {};
        this.selectedVehicle = {};
        this.questionGroupId = undefined;
        this.isVehicleTrailer = false;
        this.answeredBySource = '';
        this.choices = [];
        this.useExternal = false;
        this.filter = undefined;
        this.filteredChoices = [];
        this.touched = false;
        this.pristine = true;
        this.value = undefined;
        this.errors = [];
    }
    resetState() {
        this.touched = false;
        this.pristine = true;
        this.value = undefined;
        this.errors = [];
    }
    connectedCallback() {
        this.resetState();
        this.handleSubscriptions();
    }
    componentWillLoad() {
        this.useExternal = !!customElements.get('bp-sdk-external-vehicle-models-container');
        customElements.whenDefined('bp-sdk-external-vehicle-models-container').then(() => {
            this.useExternal = true;
        });
        this.handleSubscriptions();
        this.onQuestionGroupIdChange();
    }
    onQuestionGroupIdChange() {
        this.handleSubscriptions();
    }
    onModelsChange(models) {
        this.choices = this.convertModelsToChoices(models);
        this.updateValue(models, this.selectedVehicle);
    }
    onSelectionChange(selection) {
        if (!(selection === null || selection === void 0 ? void 0 : selection.modelId)) {
            this.touched = false;
            this.pristine = true;
        }
        this.updateValue(this.modelOptions, selection);
    }
    onFilterUpdate({ detail }) {
        var _a;
        this.filter = (_a = detail === null || detail === void 0 ? void 0 : detail.value) !== null && _a !== void 0 ? _a : '';
    }
    onFilterChange(filter) {
        this.updateChoices(this.choices, filter);
    }
    onChoicesChange(choices) {
        this.updateChoices(choices, this.filter);
    }
    updateChoices(choices, filter = '') {
        const regex = new RegExp(`.*${filter}.*`, 'gi');
        this.filteredChoices = choices.filter((choice) => !!choice.value.match(regex));
    }
    updateValue(models, selection) {
        const newValue = !!(models && (selection === null || selection === void 0 ? void 0 : selection.modelId)) ? models[selection.modelId] : undefined;
        this.value = newValue;
    }
    componentDidLoad() {
        this.loadFocusEvents();
    }
    disconnectedCallback() {
        this.unloadFocusEvents();
        this.storeUnsubscribe && this.storeUnsubscribe();
    }
    onUseExternalChange(useExternal) {
        if (!useExternal) {
            this.unloadFocusEvents();
        }
    }
    loadFocusEvents() {
        if (!this.useExternal) {
            this.el.addEventListener('focusout', this.onFocusOut);
        }
    }
    unloadFocusEvents() {
        this.el.removeEventListener('focusout', this.onFocusOut);
    }
    onValueUpdate(evt) {
        var _a;
        if (this.useExternal) {
            return;
        }
        this.pristine = false;
        const value = ((_a = evt.detail) !== null && _a !== void 0 ? _a : [])[0];
        if (hasValueChanged(value, this.value) && (this.errors.length === 0 || !!value)) {
            this.value = value;
            this.ymmcUpdate.emit({ type: YmmcUpdateType.Model, value, freeform: this.modelOptions[value] == null });
        }
    }
    onValueChange(value) {
        this.updateErrors(false, this.touched, value);
    }
    updateErrors(pristine, touched, value) {
        this.errors = hasRequiredError(pristine, touched, value) ? ['required'] : [];
    }
    onMakeDirty() {
        this.touched = true;
        this.pristine = false;
        this.updateErrors(false, this.touched, this.value);
    }
    render() {
        return [this.useExternal && this.renderExternal(), !this.useExternal && this.renderInternal()];
    }
    renderExternal() {
        return (h("bp-sdk-external-vehicle-models-container", { answerId: this.answerId, code: this.code, isVehicleTrailer: this.isVehicleTrailer, modelOptions: this.modelOptions, questionGroupId: this.questionGroupId, selectedVehicle: this.selectedVehicle }));
    }
    convertModelsToChoices(models = {}) {
        const choices = [];
        for (const modelId of Object.keys(models)) {
            choices.push({ id: modelId, value: models[modelId] });
        }
        choices.sort((a, b) => a.value.localeCompare(b.value));
        return choices;
    }
    renderInternal() {
        var _a, _b;
        return ((((_a = this.selectedVehicle) === null || _a === void 0 ? void 0 : _a.makeId) || this.choices.length > 0) && (h("bp-sdk-vehicle-models", { answerId: this.answerId, code: this.code, errors: this.errors, isVehicleTrailer: this.isVehicleTrailer, label: "Enter vehicle model", models: this.filteredChoices, pristine: this.pristine, selectedModelId: (_b = this.selectedVehicle) === null || _b === void 0 ? void 0 : _b.modelId, touched: this.touched, answeredBySource: this.answeredBySource })));
    }
    static get is() { return "bp-sdk-vehicle-models-container"; }
    static get originalStyleUrls() {
        return {
            "$": ["./bp-sdk-vehicle-models-container.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["bp-sdk-vehicle-models-container.css"]
        };
    }
    static get properties() {
        return {
            "answerId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The id of the answer associated with this field"
                },
                "attribute": "answer-id",
                "reflect": false
            },
            "code": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The question code associated with this field"
                },
                "attribute": "code",
                "reflect": false
            },
            "modelOptions": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "IVehicleModelOptions",
                    "resolved": "IVehicleModelOptions",
                    "references": {
                        "IVehicleModelOptions": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IVehicleModelOptions"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Vehicle options injected by redux"
                },
                "defaultValue": "{}"
            },
            "selectedVehicle": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "IVehicleSelection",
                    "resolved": "IVehicleSelection",
                    "references": {
                        "IVehicleSelection": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IVehicleSelection"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Current vehicle selection injected by redux"
                },
                "defaultValue": "{}"
            },
            "questionGroupId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Question Group Id"
                },
                "attribute": "question-group-id",
                "reflect": false
            },
            "isVehicleTrailer": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Is vehicle a trailer"
                },
                "attribute": "is-vehicle-trailer",
                "reflect": false,
                "defaultValue": "false"
            },
            "answeredBySource": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The source a question was answered by, if not answered directly"
                },
                "attribute": "answered-by-source",
                "reflect": false,
                "defaultValue": "''"
            }
        };
    }
    static get states() {
        return {
            "choices": {},
            "useExternal": {},
            "filter": {},
            "filteredChoices": {},
            "touched": {},
            "pristine": {},
            "value": {},
            "errors": {}
        };
    }
    static get events() {
        return [{
                "method": "ymmcUpdate",
                "name": "ymmcUpdate",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "IYearMakeModelConfigurationUpdate",
                    "resolved": "IYearMakeModelConfigurationUpdate",
                    "references": {
                        "IYearMakeModelConfigurationUpdate": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IYearMakeModelConfigurationUpdate"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "questionGroupId",
                "methodName": "onQuestionGroupIdChange"
            }, {
                "propName": "modelOptions",
                "methodName": "onModelsChange"
            }, {
                "propName": "selectedVehicle",
                "methodName": "onSelectionChange"
            }, {
                "propName": "filter",
                "methodName": "onFilterChange"
            }, {
                "propName": "choices",
                "methodName": "onChoicesChange"
            }, {
                "propName": "useExternal",
                "methodName": "onUseExternalChange"
            }, {
                "propName": "value",
                "methodName": "onValueChange"
            }];
    }
    static get listeners() {
        return [{
                "name": "filterUpdate",
                "method": "onFilterUpdate",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "valueUpdate",
                "method": "onValueUpdate",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "makeDirty",
                "method": "onMakeDirty",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
