import { calculateFantasyPoints, calculateBracketPoints } from "~/models/scoring-rules"; export type CoronaState = | { type: "eliminated"; points: 0 } | { type: "pending" } | { type: "scored"; brightness: number; points: number }; interface PickEntry { participant: { id: string; sportsSeasonId: string }; scoringPattern: string | null; } interface ResultEntry { participantId: string; finalPosition: number | null; isPartialScore: boolean | null; } interface ScoringRules { pointsFor1st: number; pointsFor2nd: number; pointsFor3rd: number; pointsFor4th: number; pointsFor5th: number; pointsFor6th: number; pointsFor7th: number; pointsFor8th: number; } export function computeCoronaStates( picks: PickEntry[], resultByParticipant: Map, bracketTemplateBySportsSeason: Map, scoringRules: ScoringRules, maxPoints: number, ): Record { const coronaStates: Record = {}; for (const pick of picks) { const result = resultByParticipant.get(pick.participant.id); if (!result || result.finalPosition === null) { coronaStates[pick.participant.id] = { type: "pending" }; continue; } if (result.finalPosition === 0 && !result.isPartialScore) { coronaStates[pick.participant.id] = { type: "eliminated", points: 0 }; continue; } if (result.finalPosition > 0) { const isBracket = pick.scoringPattern === "playoff_bracket"; const templateId = isBracket ? (bracketTemplateBySportsSeason.get(pick.participant.sportsSeasonId) ?? null) : null; const points = isBracket ? calculateBracketPoints(result.finalPosition, scoringRules, templateId) : calculateFantasyPoints(result.finalPosition, scoringRules); const brightness = maxPoints > 0 ? Math.min(points / maxPoints, 1) : 0; coronaStates[pick.participant.id] = { type: "scored", brightness, points }; continue; } coronaStates[pick.participant.id] = { type: "pending" }; } return coronaStates; }