import { TeamDrivingRatingEventFactory } from '@core/racing/domain/services/TeamDrivingRatingEventFactory';
import { RecordTeamRaceRatingEventsInput, RecordTeamRaceRatingEventsOutput } from '../dtos/RecordTeamRaceRatingEventsDto';
import type { TeamRaceResultsProvider } from '../ports/TeamRaceResultsProvider';
import { AppendTeamRatingEventsUseCase } from './AppendTeamRatingEventsUseCase';

/**
 * Use Case: RecordTeamRaceRatingEventsUseCase
 * 
 * Records rating events for a completed team race.
 * Mirrors user slice 3 pattern in core/racing/.
 * 
 * Flow:
 * 1. Load team race results from racing context
 * 2. Factory creates team rating events
 * 3. Append to ledger via AppendTeamRatingEventsUseCase
 * 4. Recompute snapshots
 */
export class RecordTeamRaceRatingEventsUseCase {
  constructor(
    private readonly teamRaceResultsProvider: TeamRaceResultsProvider,
    private readonly appendTeamRatingEventsUseCase: AppendTeamRatingEventsUseCase,
  ) {}

  async execute(input: RecordTeamRaceRatingEventsInput): Promise<RecordTeamRaceRatingEventsOutput> {
    const errors: string[] = [];
    const teamsUpdated: string[] = [];
    let totalEventsCreated = 0;

    try {
      // 1. Load team race results
      const teamRaceResults = await this.teamRaceResultsProvider.getTeamRaceResults(input.raceId);
      
      if (!teamRaceResults) {
        return {
          success: false,
          raceId: input.raceId,
          eventsCreated: 0,
          teamsUpdated: [],
          errors: ['Team race results not found'],
        };
      }

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

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

      // 3. Process each team's events
      for (const [teamId, events] of eventsByTeam) {
        try {
          // Use AppendTeamRatingEventsUseCase to handle ledger and snapshot
          await this.appendTeamRatingEventsUseCase.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,
        raceId: input.raceId,
        eventsCreated: totalEventsCreated,
        teamsUpdated,
        errors,
      };

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

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