import { UserRating } from '../value-objects/UserRating';
import { RatingEvent } from '../entities/RatingEvent';

/**
 * Domain Service: RatingSnapshotCalculator
 * 
 * Pure, stateless calculator that derives a UserRating snapshot from events.
 * STUB IMPLEMENTATION - will be evolved in future slices.
 */
export class RatingSnapshotCalculator {
  /**
   * Calculate UserRating snapshot from events
   * 
   * STUB: Currently creates a basic snapshot by summing deltas per dimension.
   * Future: Will implement:
   * - Confidence calculation based on sample size
   * - Trend detection from recent events
   * - Exponential moving averages
   * - Calculator version tracking
   */
  static calculate(userId: string, events: RatingEvent[]): UserRating {
    // Start with default UserRating
    let snapshot = UserRating.create(userId);

    // Group events by dimension
    const eventsByDimension = events.reduce((acc, event) => {
      const dimension = event.dimension.value;
      if (!acc[dimension]) acc[dimension] = [];
      acc[dimension].push(event);
      return acc;
    }, {} as Record<string, RatingEvent[]>);

    // Apply events to each dimension
    for (const [dimension, dimensionEvents] of Object.entries(eventsByDimension)) {
      const totalDelta = dimensionEvents.reduce((sum, e) => sum + e.delta.value, 0);
      const sampleSize = dimensionEvents.length;
      
      // Calculate new value (base 50 + delta)
      const newValue = Math.max(0, Math.min(100, 50 + totalDelta));

      // Update the appropriate dimension
      if (dimension === 'driving') {
        snapshot = snapshot.updateDriverRating(newValue, sampleSize);
      } else if (dimension === 'adminTrust') {
        snapshot = snapshot.updateAdminRating(newValue, sampleSize);
      } else if (dimension === 'stewardTrust') {
        snapshot = snapshot.updateStewardRating(newValue, sampleSize);
      } else if (dimension === 'broadcasterTrust') {
        // Future dimension - would need to add to UserRating
        // For now, skip
      }
    }

    return snapshot;
  }
}