import { LeagueRepository, LeagueData } from '../ports/LeagueRepository';
import { LeagueEventPublisher, LeagueCreatedEvent } from '../ports/LeagueEventPublisher';
import { LeagueCreateCommand } from '../ports/LeagueCreateCommand';

export class CreateLeagueUseCase {
  constructor(
    private readonly leagueRepository: LeagueRepository,
    private readonly eventPublisher: LeagueEventPublisher,
  ) {}

  async execute(command: LeagueCreateCommand): Promise<LeagueData> {
    // Validate command
    if (!command.name || command.name.trim() === '') {
      throw new Error('League name is required');
    }

    if (!command.ownerId || command.ownerId.trim() === '') {
      throw new Error('Owner ID is required');
    }

    if (command.maxDrivers !== undefined && command.maxDrivers < 1) {
      throw new Error('Max drivers must be at least 1');
    }

    // Create league data
    const leagueId = `league-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    const now = new Date();

    const leagueData: LeagueData = {
      id: leagueId,
      name: command.name,
      description: command.description || null,
      visibility: command.visibility,
      ownerId: command.ownerId,
      status: 'active',
      createdAt: now,
      updatedAt: now,
      maxDrivers: command.maxDrivers || null,
      approvalRequired: command.approvalRequired,
      lateJoinAllowed: command.lateJoinAllowed,
      raceFrequency: command.raceFrequency || null,
      raceDay: command.raceDay || null,
      raceTime: command.raceTime || null,
      tracks: command.tracks || null,
      scoringSystem: command.scoringSystem || null,
      bonusPointsEnabled: command.bonusPointsEnabled,
      penaltiesEnabled: command.penaltiesEnabled,
      protestsEnabled: command.protestsEnabled,
      appealsEnabled: command.appealsEnabled,
      stewardTeam: command.stewardTeam || null,
      gameType: command.gameType || null,
      skillLevel: command.skillLevel || null,
      category: command.category || null,
      tags: command.tags || null,
    };

    // Save league to repository
    const savedLeague = await this.leagueRepository.create(leagueData);

    // Initialize league stats
    const defaultStats = {
      leagueId,
      memberCount: 1,
      raceCount: 0,
      sponsorCount: 0,
      prizePool: 0,
      rating: 0,
      reviewCount: 0,
    };
    await this.leagueRepository.updateStats(leagueId, defaultStats);

    // Initialize league financials
    const defaultFinancials = {
      leagueId,
      walletBalance: 0,
      totalRevenue: 0,
      totalFees: 0,
      pendingPayouts: 0,
      netBalance: 0,
    };
    await this.leagueRepository.updateFinancials(leagueId, defaultFinancials);

    // Initialize stewarding metrics
    const defaultStewardingMetrics = {
      leagueId,
      averageResolutionTime: 0,
      averageProtestResolutionTime: 0,
      averagePenaltyAppealSuccessRate: 0,
      averageProtestSuccessRate: 0,
      averageStewardingActionSuccessRate: 0,
    };
    await this.leagueRepository.updateStewardingMetrics(leagueId, defaultStewardingMetrics);

    // Initialize performance metrics
    const defaultPerformanceMetrics = {
      leagueId,
      averageLapTime: 0,
      averageFieldSize: 0,
      averageIncidentCount: 0,
      averagePenaltyCount: 0,
      averageProtestCount: 0,
      averageStewardingActionCount: 0,
    };
    await this.leagueRepository.updatePerformanceMetrics(leagueId, defaultPerformanceMetrics);

    // Initialize rating metrics
    const defaultRatingMetrics = {
      leagueId,
      overallRating: 0,
      ratingTrend: 0,
      rankTrend: 0,
      pointsTrend: 0,
      winRateTrend: 0,
      podiumRateTrend: 0,
      dnfRateTrend: 0,
    };
    await this.leagueRepository.updateRatingMetrics(leagueId, defaultRatingMetrics);

    // Initialize trend metrics
    const defaultTrendMetrics = {
      leagueId,
      incidentRateTrend: 0,
      penaltyRateTrend: 0,
      protestRateTrend: 0,
      stewardingActionRateTrend: 0,
      stewardingTimeTrend: 0,
      protestResolutionTimeTrend: 0,
    };
    await this.leagueRepository.updateTrendMetrics(leagueId, defaultTrendMetrics);

    // Initialize success rate metrics
    const defaultSuccessRateMetrics = {
      leagueId,
      penaltyAppealSuccessRate: 0,
      protestSuccessRate: 0,
      stewardingActionSuccessRate: 0,
      stewardingActionAppealSuccessRate: 0,
      stewardingActionPenaltySuccessRate: 0,
      stewardingActionProtestSuccessRate: 0,
    };
    await this.leagueRepository.updateSuccessRateMetrics(leagueId, defaultSuccessRateMetrics);

    // Initialize resolution time metrics
    const defaultResolutionTimeMetrics = {
      leagueId,
      averageStewardingTime: 0,
      averageProtestResolutionTime: 0,
      averageStewardingActionAppealPenaltyProtestResolutionTime: 0,
    };
    await this.leagueRepository.updateResolutionTimeMetrics(leagueId, defaultResolutionTimeMetrics);

    // Initialize complex success rate metrics
    const defaultComplexSuccessRateMetrics = {
      leagueId,
      stewardingActionAppealPenaltyProtestSuccessRate: 0,
      stewardingActionAppealProtestSuccessRate: 0,
      stewardingActionPenaltyProtestSuccessRate: 0,
      stewardingActionAppealPenaltyProtestSuccessRate2: 0,
    };
    await this.leagueRepository.updateComplexSuccessRateMetrics(leagueId, defaultComplexSuccessRateMetrics);

    // Initialize complex resolution time metrics
    const defaultComplexResolutionTimeMetrics = {
      leagueId,
      stewardingActionAppealPenaltyProtestResolutionTime: 0,
      stewardingActionAppealProtestResolutionTime: 0,
      stewardingActionPenaltyProtestResolutionTime: 0,
      stewardingActionAppealPenaltyProtestResolutionTime2: 0,
    };
    await this.leagueRepository.updateComplexResolutionTimeMetrics(leagueId, defaultComplexResolutionTimeMetrics);

    // Emit event
    const event: LeagueCreatedEvent = {
      type: 'LeagueCreatedEvent',
      leagueId,
      ownerId: command.ownerId,
      timestamp: now,
    };
    await this.eventPublisher.emitLeagueCreated(event);

    return savedLeague;
  }
}
