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<DropScoreInput, DropScoreResult> {
  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,
    };
  }
}