import { h } from "@stencil/core";
import { QuestionFieldType, QuestionTag, } from "@boldpenguin/sdk-types";
import { buildClassList, upsertQuestionPoolGroups, removePoolAnswers, getParentIds, answersForAQuestionGroupWithAnsAsKey, } from "@boldpenguin/sdk-utility";
export class BpSdkQuestionSet {
    constructor() {
        this.preventRefresh = (e) => {
            e.preventDefault();
            return false;
        };
        this.saveHandler = undefined;
        this.questionSet = undefined;
        this.areResourcesReady = undefined;
        this.locked = undefined;
        this.canSave = true;
        this.shouldRenderQuestionGroup = undefined;
        this.questionGroupsWithAnswersAsKey = new Map();
        this.useExternal = false;
        this.questions = undefined;
        this.questionGroups = {};
        this.parentIds = [];
        this.answers = [];
        this.deletedPool = undefined;
        this._answers = [];
    }
    onQuestionSetChange(questionSet) {
        var _a;
        this.questionGroups = upsertQuestionPoolGroups(questionSet, this.questionGroups);
        this.parentIds = getParentIds(this.questionGroups);
        const questionSetAnswers = (_a = questionSet === null || questionSet === void 0 ? void 0 : questionSet.answers) !== null && _a !== void 0 ? _a : [];
        this.answers = questionSetAnswers;
    }
    onAnswersChange(answers) {
        const answersWithPoolAnswersRemoved = removePoolAnswers(answers, this.deletedPool);
        this._answers = this.sortAnswers(answersWithPoolAnswersRemoved);
    }
    onDeletedPoolChange(poolId) {
        this._answers = removePoolAnswers(this.answers, poolId);
    }
    onSaveQuestionSet() {
        this.saveHandler(this.questionSet);
    }
    componentWillLoad() {
        this.useExternal = !!customElements.get('bp-sdk-external-question-set');
        customElements.whenDefined('bp-sdk-external-question-set').then(() => {
            this.useExternal = true;
        });
        this.onQuestionSetChange(this.questionSet);
    }
    /**
     * Moves any coverage limit anchors to the last position in the answer list
     */
    sortAnswers(answers) {
        return answers.sort((answer1, answer2) => {
            const isCoverageLimitAnchor1 = this.isCoverageAnswer(answer1);
            const isCoverageLimitAnchor2 = this.isCoverageAnswer(answer2);
            let comparisonResult = 0;
            if (!isCoverageLimitAnchor1 && isCoverageLimitAnchor2) {
                comparisonResult = -1;
            }
            else if (isCoverageLimitAnchor1 && !isCoverageLimitAnchor2) {
                comparisonResult = 1;
            }
            return comparisonResult;
        });
    }
    isCoverageAnswer(answer) {
        return answer.question.field_type === QuestionFieldType.Anchor && answer.question.tags.includes(QuestionTag.CoverageLimit);
    }
    inQuestionGroup(answer) {
        return this.questionSet.question_set.question_groups.some((qg) => {
            return qg.question_ids.some((id) => id === answer.question.id);
        });
    }
    getAnswerPool(parentGroupId, poolId = '') {
        var _a, _b;
        const groupMap = (_a = this.questionGroups[poolId]) !== null && _a !== void 0 ? _a : {};
        return (_b = groupMap[parentGroupId]) !== null && _b !== void 0 ? _b : { answers: [] };
    }
    onDeletePool({ detail }) {
        this.deletedPool = detail;
    }
    render() {
        return (h("div", { key: '8f0819e08c65d548c8553508a3478b04afea8121', class: "bp-sdk-question-set" }, this.useExternal && this.renderExternal(), !this.useExternal && this.renderInternal()));
    }
    renderExternal() {
        return (h("bp-sdk-external-question-set", { areResourcesReady: this.areResourcesReady, canSave: this.canSave, locked: this.locked, questionSet: this.questionSet, saveHandler: this.saveHandler, questionGroupsWithAnswersAsKey: this.questionGroupsWithAnswersAsKey, shouldRenderQuestionGroup: this.shouldRenderQuestionGroup }));
    }
    renderInternal() {
        return (h("form", { onSubmit: this.preventRefresh }, h("fieldset", { class: "bp-sdk-question-set-fieldset-wrapper", disabled: this.locked }, this._answers.map((answer) => this.renderAnswer(answer)))));
    }
    renderAnswer(answer) {
        var _a;
        if (!answer) {
            return null;
        }
        const shouldRenderGroup = this.shouldRenderQuestionGroup(this.questionGroupsWithAnswersAsKey, answer);
        return [
            !this.inQuestionGroup(answer) && (h("div", { class: buildClassList('bp-sdk-question-set bp-sdk-question-set__input', {
                    'bp-sdk-coverage-width': ((_a = this.questionSet) === null || _a === void 0 ? void 0 : _a.order) === 1,
                }), "data-answerId": answer.id }, h("bp-sdk-dynamic-input-redux-container", { answer: answer }))),
            shouldRenderGroup && this.renderDynamicGroup(answer),
        ];
    }
    renderDynamicGroup(answer) {
        const mappedGroup = answersForAQuestionGroupWithAnsAsKey(answer, this.questionGroupsWithAnswersAsKey);
        // This mapped group is rendered in a loop, so each item needs a unique key; otherwise Stencil may
        // try to reuse components and that can lead to corrupted state and odd behavior
        return mappedGroup && h("bp-sdk-question-group-container", { key: answer.id, questionGroup: mappedGroup });
    }
    static get is() { return "bp-sdk-question-set"; }
    static get properties() {
        return {
            "saveHandler": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "(questionSet: IApplicationFormQuestionSet) => void",
                    "resolved": "(questionSet: IApplicationFormQuestionSet) => void",
                    "references": {
                        "IApplicationFormQuestionSet": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IApplicationFormQuestionSet"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Save Question set function"
                }
            },
            "questionSet": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "IApplicationFormQuestionSet",
                    "resolved": "IApplicationFormQuestionSet",
                    "references": {
                        "IApplicationFormQuestionSet": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IApplicationFormQuestionSet"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "ApplicationFormQuestionSet to show questions + answers"
                }
            },
            "areResourcesReady": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Flag used to disable button if resources for question set are not ready"
                },
                "attribute": "are-resources-ready",
                "reflect": false
            },
            "locked": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Flag used to disable all answer inputs"
                },
                "attribute": "locked",
                "reflect": false
            },
            "canSave": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Can Save"
                },
                "attribute": "can-save",
                "reflect": false,
                "defaultValue": "true"
            },
            "shouldRenderQuestionGroup": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "(mappedQuestionGroups: Map<string, IMappedQuestionGroupAnswers>, answer: IAnswer) => boolean",
                    "resolved": "(mappedQuestionGroups: Map<string, IMappedQuestionGroupAnswers>, answer: IAnswer) => boolean",
                    "references": {
                        "Map": {
                            "location": "global",
                            "id": "global::Map"
                        },
                        "IMappedQuestionGroupAnswers": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IMappedQuestionGroupAnswers"
                        },
                        "IAnswer": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IAnswer"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Function that gets passed from the container to decide if an answer should render as part of a question group"
                }
            },
            "questionGroupsWithAnswersAsKey": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Map<string, IMappedQuestionGroupAnswers>",
                    "resolved": "Map<string, IMappedQuestionGroupAnswers>",
                    "references": {
                        "Map": {
                            "location": "global",
                            "id": "global::Map"
                        },
                        "IMappedQuestionGroupAnswers": {
                            "location": "import",
                            "path": "@boldpenguin/sdk-types",
                            "id": "../sdk-types/dist/types.d.ts::IMappedQuestionGroupAnswers"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "A Map of nested question groups for rendering nested question groups/question pools"
                },
                "defaultValue": "new Map()"
            }
        };
    }
    static get states() {
        return {
            "useExternal": {},
            "questions": {},
            "questionGroups": {},
            "parentIds": {},
            "answers": {},
            "deletedPool": {},
            "_answers": {}
        };
    }
    static get watchers() {
        return [{
                "propName": "questionSet",
                "methodName": "onQuestionSetChange"
            }, {
                "propName": "answers",
                "methodName": "onAnswersChange"
            }, {
                "propName": "deletedPool",
                "methodName": "onDeletedPoolChange"
            }];
    }
    static get listeners() {
        return [{
                "name": "saveQuestionSet",
                "method": "onSaveQuestionSet",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "deletePool",
                "method": "onDeletePool",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
