import { Fuel, Trinary, EligibilityStatus, PropertyQuestionId } from '../../common/entities/Enums'; import { UserDataState } from '../state/UserDataState'; import { isNil } from 'lodash'; export class PropertyQuestionsService { constructor(private userDataState: UserDataState) { } clear() { delete this.userDataState.metersDiffFloor; delete this.userDataState.gasBrownBox; delete this.userDataState.inFlat; delete this.userDataState.storageHeaters; } /** Get the question to ask (assuming that the user may have already answered some of the questions) */ getFirstUnansweredQuestion(): PropertyQuestionTree { switch (this.userDataState.fuel) { case 'Dual': return this.walkTree(dualQuestions); case 'Electricity': return this.walkTree(electricityQuestions); } } getEligibilityStatus(): EligibilityStatus { const questionOrStatus = this.getFirstUnansweredQuestion(); return isEligibilityStatus(questionOrStatus) ? questionOrStatus : undefined; } /** Set the answer to the current question in local storage, and get the next question - or eligibility status */ setAnswer(question: PropertyQuestion, answer: Trinary): PropertyQuestionTree { switch (question.id) { case 'MetersDiffFloor': this.userDataState.metersDiffFloor = answer; break; case 'GasBrownBox': this.userDataState.gasBrownBox = answer; break; case 'InFlat': this.userDataState.inFlat = answer; break; case 'StorageHeaters': this.userDataState.storageHeaters = answer; break; } return this.walkTree(question); } private walkTree(tree: PropertyQuestionTree): PropertyQuestionTree { // Return the value if it's an eligibility status if (typeof tree === 'string') return tree; const answer = this.getAnswer(tree.id); switch (answer) { case 'Yes': return this.walkTree(tree.yes); case 'No': case 'Unknown': return this.walkTree(tree.no); default: return tree; } } private getAnswer(id: PropertyQuestionId): Trinary { switch (id) { case 'MetersDiffFloor': return this.userDataState.metersDiffFloor; case 'GasBrownBox': return this.userDataState.gasBrownBox; case 'InFlat': return this.userDataState.inFlat; case 'StorageHeaters': return this.userDataState.storageHeaters; } } } export function isEligibilityStatus(tree: PropertyQuestionTree): tree is EligibilityStatus { return typeof (tree) === 'string'; } export function isQuestion(tree: PropertyQuestionTree): tree is PropertyQuestion { return !isEligibilityStatus(tree); } export type PropertyQuestionTree = PropertyQuestion | EligibilityStatus; export interface PropertyQuestion { id: PropertyQuestionId, yes: PropertyQuestionTree, no: PropertyQuestionTree } const brownBoxQuestion: PropertyQuestion = { id: 'GasBrownBox', yes: 'PropertyNotEligible', no: 'Eligible' }; const dualQuestions: PropertyQuestion = { id: 'MetersDiffFloor', yes: { id: 'InFlat', yes: 'Eligible', no: brownBoxQuestion }, no: brownBoxQuestion }; const electricityQuestions: PropertyQuestion = { id: 'StorageHeaters', yes: 'PropertyNotEligible', no: 'Eligible' };