import * as _ from 'lodash-es';
import React from 'react';
import { findChildrenAnswers, getNumericAttribute, parentElements, queryAll } from '../../dom-utils';
import { withContext } from './withContext';
export const ResultsContext = React.createContext({});
export const withResultsContext = withContext(ResultsContext, ({ scores, doc, gradingStructure, gradingText, answers, singleGrading }) => {
    const answersByQuestionId = _.keyBy(answers, 'questionId');
    const topLevelQuestions = queryAll(doc.documentElement, 'question', false);
    const totalScore = calculateQuestionsTotalSumScore(topLevelQuestions, gradingStructure, scores, answersByQuestionId);
    return {
        answersByQuestionId,
        gradingStructure,
        scores,
        totalScore,
        gradingText,
        singleGrading
    };
});
export function findMultiChoiceFromGradingStructure(gradingStructure, id) {
    const choiceGroups = (gradingStructure === null || gradingStructure === void 0 ? void 0 : gradingStructure.questions.filter(v => v.type === 'choicegroup')) || [];
    for (let i = 0, length = choiceGroups.length; i < length; i++) {
        const choiceGroup = choiceGroups[i];
        for (let j = 0, choicesLength = choiceGroup.choices.length; j < choicesLength; j++) {
            if (choiceGroup.choices[j].id === id) {
                return choiceGroup.choices[j];
            }
        }
    }
    return undefined;
}
export function findScore(scores, questionId) {
    return scores.find(a => a.questionId === questionId);
}
export function calculateQuestionsTotalSumScore(topLevelQuestions, gradingStructure, scores, answersByQuestionId) {
    return _.sum(topLevelQuestions.map(question => calculateQuestionSumScore(question, gradingStructure, scores, answersByQuestionId)));
}
export function calculateQuestionSumScore(questionElement, gradingStructure, scores, answersById) {
    const choiceQuestionScore = (questionId, scoredAnswer) => {
        var _a;
        const choice = findMultiChoiceFromGradingStructure(gradingStructure, questionId);
        const option = choice === null || choice === void 0 ? void 0 : choice.options.find(o => o.id === Number(scoredAnswer.value) && choice.id === questionId);
        return (_a = option === null || option === void 0 ? void 0 : option.score) !== null && _a !== void 0 ? _a : 0;
    };
    const textQuestionScore = (questionId) => {
        var _a, _b;
        const score = findScore(scores, questionId);
        return score
            ? ((_b = [score.inspection, (_a = score.censoring) === null || _a === void 0 ? void 0 : _a.scores[0], score.autograding, score.pregrading].find(Boolean)) === null || _b === void 0 ? void 0 : _b.score) || 0
            : 0;
    };
    const sumScore = _.sum(findChildrenAnswers(questionElement).map(answer => {
        const questionId = getNumericAttribute(answer, 'question-id');
        const scoredAnswer = answersById[questionId];
        if (!scoredAnswer) {
            return 0;
        }
        if (scoredAnswer.type === 'choice') {
            return choiceQuestionScore(questionId, scoredAnswer);
        }
        else {
            return textQuestionScore(questionId);
        }
    }));
    // top level questions may not yield negative scores
    if (parentElements(questionElement, 'question').length === 0 && sumScore < 0) {
        return 0;
    }
    return sumScore;
}
//# sourceMappingURL=ResultsContext.js.map