import { BigFiveDomain, IpipNeoItem, ipipNeo120Items, ipipNeo300Items, } from '@/questionairies/bigfive/neo-data'; const reverseItems = new Set([ 2, 4, 6, 8, 10, 12, 16, 18, 19, 20, 22, 24, 26, 28, 29, 30, 32, 34, 36, 38, 39, 44, 46, 48, 49, ]); const dimensions = { extraversion: [1, 6, 11, 16, 21, 26, 31, 36, 41, 46], agreeableness: [2, 7, 12, 17, 22, 27, 32, 37, 42, 47], conscientiousness: [3, 8, 13, 18, 23, 28, 33, 38, 43, 48], emotionalStability: [4, 9, 14, 19, 24, 29, 34, 39, 44, 49], openness: [5, 10, 15, 20, 25, 30, 35, 40, 45, 50], }; export function calculateBigFiveResults(answers: string[]) { const scoreItem = (questionId: number) => { const raw = Number(answers[questionId - 1] || 0); if (!raw) return 0; return reverseItems.has(questionId) ? 6 - raw : raw; }; return Object.fromEntries( Object.entries(dimensions).map(([key, items]) => { const score = items.reduce((sum, item) => sum + scoreItem(item), 0); return [ key, { score, average: score / items.length, }, ]; }), ); } export const ipipNeoItemsByVersion = { 120: ipipNeo120Items, 300: ipipNeo300Items, } as const; export function calculateIpipNeoResults( answers: string[], items: IpipNeoItem[], ) { const domainTotals = new Map(); const facetTotals = new Map(); items.forEach((item, index) => { const raw = Number(answers[index] || 0); const score = raw ? (item.reverse ? 6 - raw : raw) : 0; const domain = domainTotals.get(item.domain) || { score: 0, count: 0 }; domain.score += score; domain.count += 1; domainTotals.set(item.domain, domain); const facet = facetTotals.get(item.facet) || { score: 0, count: 0 }; facet.score += score; facet.count += 1; facetTotals.set(item.facet, facet); }); const toResults = (totals: Map) => Object.fromEntries( [...totals.entries()].map(([key, value]) => [ key, { score: value.score, average: value.count ? value.score / value.count : 0, itemCount: value.count, }, ]), ); return { domains: toResults(domainTotals), facets: toResults(facetTotals), }; }