import type { ITeamRaceResultsProvider } from '../ports/ITeamRaceResultsProvider';
import type { ITeamRatingEventRepository } from '@core/racing/domain/repositories/ITeamRatingEventRepository';
import type { ITeamRatingRepository } from '@core/racing/domain/repositories/ITeamRatingRepository';
import { TeamDrivingRatingEventFactory } from '@core/racing/domain/services/TeamDrivingRatingEventFactory';
import { AppendTeamRatingEventsUseCase } from './AppendTeamRatingEventsUseCase';

/**
 * Integration Adapter: TeamRatingIntegrationAdapter
 * 
 * Minimal integration with race flow.
 * Can be called from CompleteRaceUseCase to record team ratings.
 * 
 * Usage in CompleteRaceUseCase:
 * ```typescript
 * // After race completion
 * const teamRatingAdapter = new TeamRatingIntegrationAdapter(
 *   teamRaceResultsProvider,
 *   ratingEventRepository,
 *   ratingRepository
 * );
 * 
 * await teamRatingAdapter.recordTeamRatings(raceId);
 * ```
 */
export class TeamRatingIntegrationAdapter {
  private appendUseCase: AppendTeamRatingEventsUseCase;

  constructor(
    private readonly teamRaceResultsProvider: ITeamRaceResultsProvider,
    ratingEventRepository: ITeamRatingEventRepository,
    ratingRepository: ITeamRatingRepository,
  ) {
    this.appendUseCase = new AppendTeamRatingEventsUseCase(
      ratingEventRepository,
      ratingRepository
    );
  }

  /**
   * Record team ratings for a completed race.
   * Returns true if successful, false otherwise.
   */
  async recordTeamRatings(raceId: string): Promise<boolean> {
    try {
      // Get team race results
      const teamRaceResults = await this.teamRaceResultsProvider.getTeamRaceResults(raceId);
      
      if (!teamRaceResults || teamRaceResults.results.length === 0) {
        return true; // No team results to process
      }

      // Create rating events
      const eventsByTeam = TeamDrivingRatingEventFactory.createDrivingEventsFromRace(teamRaceResults);

      if (eventsByTeam.size === 0) {
        return true; // No events generated
      }

      // Process each team
      for (const [teamId, events] of eventsByTeam) {
        try {
          await this.appendUseCase.execute(events);
        } catch (error) {
          console.error(`Failed to record team ratings for team ${teamId}:`, error);
          return false;
        }
      }

      return true;
    } catch (error) {
      console.error('Failed to record team ratings:', error);
      return false;
    }
  }

  /**
   * Record team ratings with detailed output.
   */
  async recordTeamRatingsWithDetails(raceId: string): Promise<{
    success: boolean;
    eventsCreated: number;
    teamsUpdated: string[];
    errors: string[];
  }> {
    const errors: string[] = [];
    const teamsUpdated: string[] = [];
    let totalEventsCreated = 0;

    try {
      const teamRaceResults = await this.teamRaceResultsProvider.getTeamRaceResults(raceId);
      
      if (!teamRaceResults || teamRaceResults.results.length === 0) {
        return {
          success: true,
          eventsCreated: 0,
          teamsUpdated: [],
          errors: [],
        };
      }

      const eventsByTeam = TeamDrivingRatingEventFactory.createDrivingEventsFromRace(teamRaceResults);

      if (eventsByTeam.size === 0) {
        return {
          success: true,
          eventsCreated: 0,
          teamsUpdated: [],
          errors: [],
        };
      }

      for (const [teamId, events] of eventsByTeam) {
        try {
          await this.appendUseCase.execute(events);
          teamsUpdated.push(teamId);
          totalEventsCreated += events.length;
        } catch (error) {
          const errorMsg = `Failed to process events for team ${teamId}: ${error instanceof Error ? error.message : 'Unknown error'}`;
          errors.push(errorMsg);
        }
      }

      return {
        success: errors.length === 0,
        eventsCreated: totalEventsCreated,
        teamsUpdated,
        errors,
      };

    } catch (error) {
      const errorMsg = `Failed to record team ratings: ${error instanceof Error ? error.message : 'Unknown error'}`;
      errors.push(errorMsg);

      return {
        success: false,
        eventsCreated: 0,
        teamsUpdated: [],
        errors,
      };
    }
  }
}