brackt/app/lib/corona-states.ts

69 lines
2 KiB
TypeScript

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<string, ResultEntry>,
bracketTemplateBySportsSeason: Map<string, string | null>,
scoringRules: ScoringRules,
maxPoints: number,
): Record<string, CoronaState> {
const coronaStates: Record<string, CoronaState> = {};
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;
}