import {
  LeagueRepository,
  LeagueData,
  LeagueStats,
  LeagueFinancials,
  LeagueStewardingMetrics,
  LeaguePerformanceMetrics,
  LeagueRatingMetrics,
  LeagueTrendMetrics,
  LeagueSuccessRateMetrics,
  LeagueResolutionTimeMetrics,
  LeagueComplexSuccessRateMetrics,
  LeagueComplexResolutionTimeMetrics,
} from '../../../../core/leagues/application/ports/LeagueRepository';

export class InMemoryLeagueRepository implements LeagueRepository {
  private leagues: Map<string, LeagueData> = new Map();
  private leagueStats: Map<string, LeagueStats> = new Map();
  private leagueFinancials: Map<string, LeagueFinancials> = new Map();
  private leagueStewardingMetrics: Map<string, LeagueStewardingMetrics> = new Map();
  private leaguePerformanceMetrics: Map<string, LeaguePerformanceMetrics> = new Map();
  private leagueRatingMetrics: Map<string, LeagueRatingMetrics> = new Map();
  private leagueTrendMetrics: Map<string, LeagueTrendMetrics> = new Map();
  private leagueSuccessRateMetrics: Map<string, LeagueSuccessRateMetrics> = new Map();
  private leagueResolutionTimeMetrics: Map<string, LeagueResolutionTimeMetrics> = new Map();
  private leagueComplexSuccessRateMetrics: Map<string, LeagueComplexSuccessRateMetrics> = new Map();
  private leagueComplexResolutionTimeMetrics: Map<string, LeagueComplexResolutionTimeMetrics> = new Map();

  async create(league: LeagueData): Promise<LeagueData> {
    this.leagues.set(league.id, league);
    return league;
  }

  async findById(id: string): Promise<LeagueData | null> {
    return this.leagues.get(id) || null;
  }

  async findByName(name: string): Promise<LeagueData | null> {
    for (const league of Array.from(this.leagues.values())) {
      if (league.name === name) {
        return league;
      }
    }
    return null;
  }

  async findByOwner(ownerId: string): Promise<LeagueData[]> {
    const leagues: LeagueData[] = [];
    for (const league of Array.from(this.leagues.values())) {
      if (league.ownerId === ownerId) {
        leagues.push(league);
      }
    }
    return leagues;
  }

  async search(query: string): Promise<LeagueData[]> {
    const results: LeagueData[] = [];
    const lowerQuery = query.toLowerCase();
    for (const league of Array.from(this.leagues.values())) {
      if (
        league.name.toLowerCase().includes(lowerQuery) ||
        league.description?.toLowerCase().includes(lowerQuery)
      ) {
        results.push(league);
      }
    }
    return results;
  }

  async update(id: string, updates: Partial<LeagueData>): Promise<LeagueData> {
    const league = this.leagues.get(id);
    if (!league) {
      throw new Error(`League with id ${id} not found`);
    }
    const updated = { ...league, ...updates };
    this.leagues.set(id, updated);
    return updated;
  }

  async delete(id: string): Promise<void> {
    this.leagues.delete(id);
    this.leagueStats.delete(id);
    this.leagueFinancials.delete(id);
    this.leagueStewardingMetrics.delete(id);
    this.leaguePerformanceMetrics.delete(id);
    this.leagueRatingMetrics.delete(id);
    this.leagueTrendMetrics.delete(id);
    this.leagueSuccessRateMetrics.delete(id);
    this.leagueResolutionTimeMetrics.delete(id);
    this.leagueComplexSuccessRateMetrics.delete(id);
    this.leagueComplexResolutionTimeMetrics.delete(id);
  }

  async getStats(leagueId: string): Promise<LeagueStats> {
    return this.leagueStats.get(leagueId) || this.createDefaultStats(leagueId);
  }

  async updateStats(leagueId: string, stats: LeagueStats): Promise<LeagueStats> {
    this.leagueStats.set(leagueId, stats);
    return stats;
  }

  async getFinancials(leagueId: string): Promise<LeagueFinancials> {
    return this.leagueFinancials.get(leagueId) || this.createDefaultFinancials(leagueId);
  }

  async updateFinancials(leagueId: string, financials: LeagueFinancials): Promise<LeagueFinancials> {
    this.leagueFinancials.set(leagueId, financials);
    return financials;
  }

  async getStewardingMetrics(leagueId: string): Promise<LeagueStewardingMetrics> {
    return this.leagueStewardingMetrics.get(leagueId) || this.createDefaultStewardingMetrics(leagueId);
  }

  async updateStewardingMetrics(leagueId: string, metrics: LeagueStewardingMetrics): Promise<LeagueStewardingMetrics> {
    this.leagueStewardingMetrics.set(leagueId, metrics);
    return metrics;
  }

  async getPerformanceMetrics(leagueId: string): Promise<LeaguePerformanceMetrics> {
    return this.leaguePerformanceMetrics.get(leagueId) || this.createDefaultPerformanceMetrics(leagueId);
  }

  async updatePerformanceMetrics(leagueId: string, metrics: LeaguePerformanceMetrics): Promise<LeaguePerformanceMetrics> {
    this.leaguePerformanceMetrics.set(leagueId, metrics);
    return metrics;
  }

  async getRatingMetrics(leagueId: string): Promise<LeagueRatingMetrics> {
    return this.leagueRatingMetrics.get(leagueId) || this.createDefaultRatingMetrics(leagueId);
  }

  async updateRatingMetrics(leagueId: string, metrics: LeagueRatingMetrics): Promise<LeagueRatingMetrics> {
    this.leagueRatingMetrics.set(leagueId, metrics);
    return metrics;
  }

  async getTrendMetrics(leagueId: string): Promise<LeagueTrendMetrics> {
    return this.leagueTrendMetrics.get(leagueId) || this.createDefaultTrendMetrics(leagueId);
  }

  async updateTrendMetrics(leagueId: string, metrics: LeagueTrendMetrics): Promise<LeagueTrendMetrics> {
    this.leagueTrendMetrics.set(leagueId, metrics);
    return metrics;
  }

  async getSuccessRateMetrics(leagueId: string): Promise<LeagueSuccessRateMetrics> {
    return this.leagueSuccessRateMetrics.get(leagueId) || this.createDefaultSuccessRateMetrics(leagueId);
  }

  async updateSuccessRateMetrics(leagueId: string, metrics: LeagueSuccessRateMetrics): Promise<LeagueSuccessRateMetrics> {
    this.leagueSuccessRateMetrics.set(leagueId, metrics);
    return metrics;
  }

  async getResolutionTimeMetrics(leagueId: string): Promise<LeagueResolutionTimeMetrics> {
    return this.leagueResolutionTimeMetrics.get(leagueId) || this.createDefaultResolutionTimeMetrics(leagueId);
  }

  async updateResolutionTimeMetrics(leagueId: string, metrics: LeagueResolutionTimeMetrics): Promise<LeagueResolutionTimeMetrics> {
    this.leagueResolutionTimeMetrics.set(leagueId, metrics);
    return metrics;
  }

  async getComplexSuccessRateMetrics(leagueId: string): Promise<LeagueComplexSuccessRateMetrics> {
    return this.leagueComplexSuccessRateMetrics.get(leagueId) || this.createDefaultComplexSuccessRateMetrics(leagueId);
  }

  async updateComplexSuccessRateMetrics(leagueId: string, metrics: LeagueComplexSuccessRateMetrics): Promise<LeagueComplexSuccessRateMetrics> {
    this.leagueComplexSuccessRateMetrics.set(leagueId, metrics);
    return metrics;
  }

  async getComplexResolutionTimeMetrics(leagueId: string): Promise<LeagueComplexResolutionTimeMetrics> {
    return this.leagueComplexResolutionTimeMetrics.get(leagueId) || this.createDefaultComplexResolutionTimeMetrics(leagueId);
  }

  async updateComplexResolutionTimeMetrics(leagueId: string, metrics: LeagueComplexResolutionTimeMetrics): Promise<LeagueComplexResolutionTimeMetrics> {
    this.leagueComplexResolutionTimeMetrics.set(leagueId, metrics);
    return metrics;
  }

  clear(): void {
    this.leagues.clear();
    this.leagueStats.clear();
    this.leagueFinancials.clear();
    this.leagueStewardingMetrics.clear();
    this.leaguePerformanceMetrics.clear();
    this.leagueRatingMetrics.clear();
    this.leagueTrendMetrics.clear();
    this.leagueSuccessRateMetrics.clear();
    this.leagueResolutionTimeMetrics.clear();
    this.leagueComplexSuccessRateMetrics.clear();
    this.leagueComplexResolutionTimeMetrics.clear();
  }

  private createDefaultStats(leagueId: string): LeagueStats {
    return {
      leagueId,
      memberCount: 1,
      raceCount: 0,
      sponsorCount: 0,
      prizePool: 0,
      rating: 0,
      reviewCount: 0,
    };
  }

  private createDefaultFinancials(leagueId: string): LeagueFinancials {
    return {
      leagueId,
      walletBalance: 0,
      totalRevenue: 0,
      totalFees: 0,
      pendingPayouts: 0,
      netBalance: 0,
    };
  }

  private createDefaultStewardingMetrics(leagueId: string): LeagueStewardingMetrics {
    return {
      leagueId,
      averageResolutionTime: 0,
      averageProtestResolutionTime: 0,
      averagePenaltyAppealSuccessRate: 0,
      averageProtestSuccessRate: 0,
      averageStewardingActionSuccessRate: 0,
    };
  }

  private createDefaultPerformanceMetrics(leagueId: string): LeaguePerformanceMetrics {
    return {
      leagueId,
      averageLapTime: 0,
      averageFieldSize: 0,
      averageIncidentCount: 0,
      averagePenaltyCount: 0,
      averageProtestCount: 0,
      averageStewardingActionCount: 0,
    };
  }

  private createDefaultRatingMetrics(leagueId: string): LeagueRatingMetrics {
    return {
      leagueId,
      overallRating: 0,
      ratingTrend: 0,
      rankTrend: 0,
      pointsTrend: 0,
      winRateTrend: 0,
      podiumRateTrend: 0,
      dnfRateTrend: 0,
    };
  }

  private createDefaultTrendMetrics(leagueId: string): LeagueTrendMetrics {
    return {
      leagueId,
      incidentRateTrend: 0,
      penaltyRateTrend: 0,
      protestRateTrend: 0,
      stewardingActionRateTrend: 0,
      stewardingTimeTrend: 0,
      protestResolutionTimeTrend: 0,
    };
  }

  private createDefaultSuccessRateMetrics(leagueId: string): LeagueSuccessRateMetrics {
    return {
      leagueId,
      penaltyAppealSuccessRate: 0,
      protestSuccessRate: 0,
      stewardingActionSuccessRate: 0,
      stewardingActionAppealSuccessRate: 0,
      stewardingActionPenaltySuccessRate: 0,
      stewardingActionProtestSuccessRate: 0,
    };
  }

  private createDefaultResolutionTimeMetrics(leagueId: string): LeagueResolutionTimeMetrics {
    return {
      leagueId,
      averageStewardingTime: 0,
      averageProtestResolutionTime: 0,
      averageStewardingActionAppealPenaltyProtestResolutionTime: 0,
    };
  }

  private createDefaultComplexSuccessRateMetrics(leagueId: string): LeagueComplexSuccessRateMetrics {
    return {
      leagueId,
      stewardingActionAppealPenaltyProtestSuccessRate: 0,
      stewardingActionAppealProtestSuccessRate: 0,
      stewardingActionPenaltyProtestSuccessRate: 0,
      stewardingActionAppealPenaltyProtestSuccessRate2: 0,
    };
  }

  private createDefaultComplexResolutionTimeMetrics(leagueId: string): LeagueComplexResolutionTimeMetrics {
    return {
      leagueId,
      stewardingActionAppealPenaltyProtestResolutionTime: 0,
      stewardingActionAppealProtestResolutionTime: 0,
      stewardingActionPenaltyProtestResolutionTime: 0,
      stewardingActionAppealPenaltyProtestResolutionTime2: 0,
    };
  }
}
