import { hasRequiredError, hasValueChanged } from "@boldpenguin/sdk-utility";
import { h } from "@stencil/core";
import store from "../../services/redux-store.service";
import { getVehicleOptionsConfigurations, getVehicleOptionsMakes, getVehicleOptionsSelection } from "@boldpenguin/sdk-redux";
import { YmmcUpdateType, } from "@boldpenguin/sdk-types";
export class BpSdkVehicleConfigurationsContainer {
    constructor() {
        this.handleSubscriptions = () => {
            this.storeUnsubscribe && this.storeUnsubscribe();
            this.storeUnsubscribe = store.mapStateToProps(this, this.mapStateToProps);
        };
        this.mapStateToProps = (state) => {
            return {
                configurationOptions: getVehicleOptionsConfigurations(state, this.questionGroupId),
                makeOptions: getVehicleOptionsMakes(state, this.questionGroupId),
                modelOptions: getVehicleOptionsMakes(state, this.questionGroupId),
                selectedVehicle: getVehicleOptionsSelection(state, this.questionGroupId),
            };
        };
        this.onFocusOut = () => {
            this.touched = true;
            this.updateErrors(this.pristine, true, this.value);
        };
        this.configurationOptions = {};
        this.selectedVehicle = {};
        this.makeOptions = {};
        this.modelOptions = {};
        this.questionGroupId = undefined;
        this.checkYmm = true;
        this.answerId = undefined;
        this.code = undefined;
        this.answeredBySource = '';
        this.choices = [];
        this.useExternal = false;
        this.touched = false;
        this.pristine = true;
        this.value = undefined;
        this.showConfig = true;
        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-configurations-container');
        customElements.whenDefined('bp-sdk-external-vehicle-configurations-container').then(() => {
            this.useExternal = true;
        });
        this.onQuestionGroupIdChange();
    }
    onQuestionGroupIdChange() {
        this.handleSubscriptions();
    }
    onMakesMapChange(makeOptions) {
        this.updateShowConfig(this.checkYmm, {
            configurations: this.configurationOptions,
            makes: makeOptions,
            models: this.modelOptions,
        });
    }
    onVehicleModelOptionsChange(modelOptions) {
        this.updateShowConfig(this.checkYmm, {
            configurations: this.configurationOptions,
            makes: this.makeOptions,
            models: modelOptions,
        });
    }
    onConfigurationsChange(configurations) {
        if (configurations) {
            this.choices = this.convertConfigurationsToChoices(configurations);
            this.updateValue(configurations, this.selectedVehicle);
            if (Object.keys(configurations).length === 1) {
                this.ymmcUpdate.emit({ type: YmmcUpdateType.Configuration, value: Object.keys(configurations)[0] });
            }
            this.updateShowConfig(this.checkYmm, {
                configurations,
                makes: this.makeOptions,
                models: this.modelOptions,
            });
        }
        else {
            this.choices = [];
            this.updateValue(undefined, undefined);
        }
    }
    onVehicleSelectionChange(selection) {
        if (!(selection === null || selection === void 0 ? void 0 : selection.configurationId)) {
            this.touched = false;
            this.pristine = true;
        }
        this.updateValue(this.configurationOptions, selection);
    }
    updateValue(configurations, selection) {
        this.value = !!(configurations && (selection === null || selection === void 0 ? void 0 : selection.configurationId)) ? configurations[selection.configurationId] : undefined;
    }
    onCheckYmmChange(checkYmm) {
        this.updateShowConfig(checkYmm, {
            configurations: this.configurationOptions,
            makes: this.makeOptions,
            models: this.modelOptions,
        });
    }
    updateShowConfig(checkYmm, options) {
        this.showConfig = !checkYmm || this.isReadyToConfigure(options);
    }
    isReadyToConfigure(options) {
        var _a, _b, _c;
        const configurations = Object.values((_a = options === null || options === void 0 ? void 0 : options.configurations) !== null && _a !== void 0 ? _a : {});
        const makes = Object.keys((_b = options === null || options === void 0 ? void 0 : options.makes) !== null && _b !== void 0 ? _b : {});
        const models = Object.keys((_c = options === null || options === void 0 ? void 0 : options.models) !== null && _c !== void 0 ? _c : {});
        return !!makes.length && !!models.length && configurations.filter((config) => !!config).length > 1;
    }
    componentDidLoad() {
        this.loadFocusEvents();
    }
    disconnectedCallback() {
        this.unloadFocusEvents();
        this.storeUnsubscribe && this.storeUnsubscribe();
    }
    onUseExternalChange(useExternal) {
        if (!useExternal) {
            this.unloadFocusEvents();
        }
    }
    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);
    }
    loadFocusEvents() {
        if (!this.useExternal) {
            this.el.addEventListener('focusout', this.onFocusOut);
        }
    }
    unloadFocusEvents() {
        this.el.removeEventListener('focusout', this.onFocusOut);
    }
    onValueUpdate(evt) {
        var _a;
        evt.stopPropagation();
        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.Configuration, value });
        }
    }
    onValueChange(value) {
        this.updateErrors(false, this.touched, value);
    }
    render() {
        return [this.useExternal && this.renderExternal(), !this.useExternal && this.renderInternal()];
    }
    renderExternal() {
        return (h("bp-sdk-external-vehicle-configurations-container", { answerId: this.answerId, checkYmm: this.checkYmm, code: this.code, configurationOptions: this.configurationOptions, questionGroupId: this.questionGroupId, makeOptions: this.makeOptions, modelOptions: this.modelOptions, selectedVehicle: this.selectedVehicle }));
    }
    convertConfigurationsToChoices(configurations) {
        const choices = [];
        for (const configId of Object.keys(configurations)) {
            choices.push({ id: configId, value: configurations[configId] });
        }
        return choices;
    }
    renderInternal() {
        var _a;
        return (this.showConfig && (h("bp-sdk-vehicle-configurations", { answerId: this.answerId, code: this.code, configurations: this.choices, errors: this.errors, label: "Choose vehicle configuration", pristine: this.pristine, selectedConfigurationId: (_a = this.selectedVehicle) === null || _a === void 0 ? void 0 : _a.configurationId, touched: this.touched, answeredBySource: this.answeredBySource })));
    }
    static get is() { return "bp-sdk-vehicle-configurations-container"; }
    static get originalStyleUrls() {
        return {
            "$": ["./bp-sdk-vehicle-configurations-container.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["bp-sdk-vehicle-configurations-container.css"]
        };
    }
    static get properties() {
        return {
            "configurationOptions": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "IVehicleConfigurationOptions",
                    "resolved": "IVehicleConfigurationOptions",
                    "references": {
                        "IVehicleConfigurationOptions": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IVehicleConfigurationOptions"
                        }
                    }
                },
                "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": "{}"
            },
            "makeOptions": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "IVehicleMakeOptions",
                    "resolved": "IVehicleMakeOptions",
                    "references": {
                        "IVehicleMakeOptions": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IVehicleMakeOptions"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Vehicle options injected by redux"
                },
                "defaultValue": "{}"
            },
            "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": "{}"
            },
            "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
            },
            "checkYmm": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Is year make model"
                },
                "attribute": "check-ymm",
                "reflect": false,
                "defaultValue": "true"
            },
            "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
            },
            "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": {},
            "touched": {},
            "pristine": {},
            "value": {},
            "showConfig": {},
            "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": "makeOptions",
                "methodName": "onMakesMapChange"
            }, {
                "propName": "modelOptions",
                "methodName": "onVehicleModelOptionsChange"
            }, {
                "propName": "configurationOptions",
                "methodName": "onConfigurationsChange"
            }, {
                "propName": "selectedVehicle",
                "methodName": "onVehicleSelectionChange"
            }, {
                "propName": "checkYmm",
                "methodName": "onCheckYmmChange"
            }, {
                "propName": "useExternal",
                "methodName": "onUseExternalChange"
            }, {
                "propName": "value",
                "methodName": "onValueChange"
            }];
    }
    static get listeners() {
        return [{
                "name": "makeDirty",
                "method": "onMakeDirty",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "valueUpdate",
                "method": "onValueUpdate",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
