/**
 * Query: GetLeagueEligibilityPreviewQuery
 * 
 * Preview eligibility for a league based on DSL rules.
 * Uses EligibilityEvaluator to provide explainable results.
 */

import { ExternalGameRatingRepository } from '../../domain/repositories/ExternalGameRatingRepository';
import { UserRatingRepository } from '../../domain/repositories/UserRatingRepository';
import { EligibilityEvaluator, RatingData } from '../../domain/services/EligibilityEvaluator';
import { EligibilityFilterDto, EvaluationResultDto } from '../../domain/types/Eligibility';

export interface GetLeagueEligibilityPreviewQuery {
  userId: string;
  leagueId: string;
  eligibilityRules: string; // DSL expression
}

export class GetLeagueEligibilityPreviewQueryHandler {
  private readonly evaluator: EligibilityEvaluator;

  constructor(
    private readonly userRatingRepo: UserRatingRepository,
    private readonly externalRatingRepo: ExternalGameRatingRepository
  ) {
    this.evaluator = new EligibilityEvaluator();
  }

  async execute(query: GetLeagueEligibilityPreviewQuery): Promise<EvaluationResultDto> {
    const { userId, leagueId, eligibilityRules } = query;

    // Fetch user's rating data
    const userRating = await this.userRatingRepo.findByUserId(userId);
    const externalProfiles = await this.externalRatingRepo.findByUserId(userId);

    // Build rating data for evaluation
    const ratingData: RatingData = {
      platform: {
        driving: userRating?.driver.value || 0,
        admin: userRating?.admin.value || 0,
        steward: userRating?.steward.value || 0,
        trust: userRating?.trust.value || 0,
        fairness: userRating?.fairness.value || 0,
      },
      external: {},
    };

    // Add external ratings
    for (const profile of externalProfiles) {
      const gameKey = profile.gameKey.toString();
      ratingData.external[gameKey] = {};
      
      // Convert Map to array and iterate
      const ratingsArray = Array.from(profile.ratings.entries());
      for (const [type, rating] of ratingsArray) {
        ratingData.external[gameKey][type] = rating.value;
      }
    }

    // Evaluate eligibility
    const filter: EligibilityFilterDto = {
      dsl: eligibilityRules,
      context: {
        userId,
        leagueId,
      },
    };

    return this.evaluator.evaluate(filter, ratingData);
  }
}
