import { getPartnerEngineConfig, getVehicleOptionsSelection, getVehicleOptionsYears, loadYears } 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 BpSdkVehicleYearsContainer {
    constructor() {
        this.handleSubscriptions = () => {
            store.mapDispatchToProps(this, {
                loadYears,
            });
            this.storeUnsubscribe && this.storeUnsubscribe();
            this.storeUnsubscribe = store.mapStateToProps(this, this.mapStateToProps);
        };
        this.mapStateToProps = (state) => {
            return {
                config: getPartnerEngineConfig(state),
                yearOptions: getVehicleOptionsYears(state, this.questionGroupId),
                selectedVehicle: getVehicleOptionsSelection(state, this.questionGroupId),
            };
        };
        this.onFocusOut = () => {
            this.touched = true;
            this.updateErrors(this.pristine, true, this.value);
        };
        this.selectedVehicle = undefined;
        this.yearOptions = {};
        this.questionGroupId = undefined;
        this.isVehicleTrailer = false;
        this.config = undefined;
        this.answerId = undefined;
        this.code = undefined;
        this.answeredBySource = '';
        this.choices = [];
        this.filter = undefined;
        this.filteredChoices = [];
        this.useExternal = false;
        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-years-container');
        customElements.whenDefined('bp-sdk-external-vehicle-years-container').then(() => {
            this.useExternal = true;
        });
        this.handleSubscriptions();
        this.onQuestionGroupIdChange();
    }
    fetchYears() {
        this.loadYears({ config: this.config, questionGroupId: this.questionGroupId });
    }
    onQuestionGroupIdChange() {
        this.handleSubscriptions();
    }
    onYearsChange(years) {
        if (years) {
            this.choices = this.convertYearsToChoices(years);
            this.updateValue(years, this.selectedVehicle);
        }
        else {
            this.fetchYears();
            this.updateValue(undefined, undefined);
        }
    }
    onVehicleSelectionChange(selection) {
        this.updateValue(this.yearOptions, selection);
    }
    updateValue(years, selection) {
        this.value = !!(years && (selection === null || selection === void 0 ? void 0 : selection.yearId) && years[selection.yearId]) ? years[selection.yearId].toString() : undefined;
    }
    onUseExternalChange(useExternal) {
        if (!useExternal) {
            this.unloadFocusEvents();
        }
    }
    loadFocusEvents() {
        if (!this.useExternal) {
            this.el.addEventListener('focusout', this.onFocusOut);
        }
    }
    unloadFocusEvents() {
        this.el.removeEventListener('focusout', this.onFocusOut);
    }
    componentDidLoad() {
        this.loadFocusEvents();
    }
    disconnectedCallback() {
        this.unloadFocusEvents();
        this.storeUnsubscribe && this.storeUnsubscribe();
    }
    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));
    }
    onValueUpdate(evt) {
        var _a;
        if (this.useExternal) {
            return;
        }
        this.pristine = false;
        const value = ((_a = evt.detail) !== null && _a !== void 0 ? _a : [])[0];
        const num = Number(value);
        const isNumber = !Number.isNaN(num);
        this.updateErrors(false, this.touched, value);
        if (this.errors.length === 0 && isNumber && hasValueChanged(value, this.value)) {
            this.value = value;
            this.ymmcUpdate.emit({ type: YmmcUpdateType.Year, value });
            this.filter = '';
        }
    }
    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-years-container", { answerId: this.answerId, code: this.code, config: this.config, isVehicleTrailer: this.isVehicleTrailer, questionGroupId: this.questionGroupId, selectedVehicle: this.selectedVehicle, yearOptions: this.yearOptions }));
    }
    convertYearsToChoices(years) {
        const choices = [];
        for (const year of Object.keys(years)) {
            choices.push({ id: year, value: year });
        }
        choices.sort((a, b) => parseFloat(b.value) - parseFloat(a.value));
        return choices;
    }
    renderInternal() {
        var _a, _b;
        return (this.choices.length > 0 && (h("bp-sdk-vehicle-years", { answerId: this.answerId, code: this.code, errors: this.errors, isVehicleTrailer: this.isVehicleTrailer, label: "Enter vehicle year", pristine: this.pristine, selectedYear: (_b = (_a = this.selectedVehicle) === null || _a === void 0 ? void 0 : _a.yearId) === null || _b === void 0 ? void 0 : _b.toString(), touched: this.touched, years: this.filteredChoices, answeredBySource: this.answeredBySource })));
    }
    static get is() { return "bp-sdk-vehicle-years-container"; }
    static get originalStyleUrls() {
        return {
            "$": ["./bp-sdk-vehicle-years-container.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["bp-sdk-vehicle-years-container.css"]
        };
    }
    static get properties() {
        return {
            "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": "Vehicle selection injected by redux"
                }
            },
            "yearOptions": {
                "type": "unknown",
                "mutable": true,
                "complexType": {
                    "original": "IVehicleYearOptions",
                    "resolved": "IVehicleYearOptions",
                    "references": {
                        "IVehicleYearOptions": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IVehicleYearOptions"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "IVehicleYearOptions 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"
            },
            "config": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "IPartnerEngineConfig",
                    "resolved": "IPartnerEngineConfig",
                    "references": {
                        "IPartnerEngineConfig": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IPartnerEngineConfig"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "IPartnerEngineConfig injected from redux"
                }
            },
            "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": {},
            "filter": {},
            "filteredChoices": {},
            "useExternal": {},
            "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": "yearOptions",
                "methodName": "onYearsChange"
            }, {
                "propName": "selectedVehicle",
                "methodName": "onVehicleSelectionChange"
            }, {
                "propName": "useExternal",
                "methodName": "onUseExternalChange"
            }, {
                "propName": "filter",
                "methodName": "onFilterChange"
            }, {
                "propName": "choices",
                "methodName": "onChoicesChange"
            }, {
                "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
            }];
    }
}
