import type { DomainCalculationService } from '@core/shared/domain/Service'; import type { DropScorePolicy } from '../types/DropScorePolicy'; export interface EventPointsEntry { eventId: string; points: number; } export interface DropScoreResult { counted: EventPointsEntry[]; dropped: EventPointsEntry[]; totalPoints: number; } export interface DropScoreInput { policy: DropScorePolicy; events: EventPointsEntry[]; } export class DropScoreApplier implements DomainCalculationService { calculate(input: DropScoreInput): DropScoreResult { return this.apply(input.policy, input.events); } apply(policy: DropScorePolicy, events: EventPointsEntry[]): DropScoreResult { if (policy.strategy === 'none' || events.length === 0) { const totalPoints = events.reduce((sum, e) => sum + e.points, 0); return { counted: [...events], dropped: [], totalPoints, }; } if (policy.strategy === 'bestNResults') { const count = policy.count ?? events.length; if (count >= events.length) { const totalPoints = events.reduce((sum, e) => sum + e.points, 0); return { counted: [...events], dropped: [], totalPoints, }; } const sorted = [...events].sort((a, b) => b.points - a.points); const counted = sorted.slice(0, count); const dropped = sorted.slice(count); const totalPoints = counted.reduce((sum, e) => sum + e.points, 0); return { counted, dropped, totalPoints, }; } // For this slice, treat unsupported strategies as 'none' const totalPoints = events.reduce((sum, e) => sum + e.points, 0); return { counted: [...events], dropped: [], totalPoints, }; } }