import type {
  ITeamsLeaderboardPresenter,
  TeamsLeaderboardViewModel,
  TeamLeaderboardItemViewModel,
  SkillLevel,
  TeamsLeaderboardResultDTO,
} from '@core/racing/application/presenters/ITeamsLeaderboardPresenter';

interface TeamLeaderboardInput {
  id: string;
  name: string;
  memberCount: number;
  rating: number | null;
  totalWins: number;
  totalRaces: number;
  performanceLevel: SkillLevel;
  isRecruiting: boolean;
  createdAt: Date;
  description?: string | null;
  specialization?: string | null;
  region?: string | null;
  languages?: string[];
}

export class TeamsLeaderboardPresenter implements ITeamsLeaderboardPresenter {
  private viewModel: TeamsLeaderboardViewModel | null = null;

  reset(): void {
    this.viewModel = null;
  }

  present(input: TeamsLeaderboardResultDTO): void {
    const teams = (input.teams ?? []) as TeamLeaderboardInput[];
    const recruitingCount = input.recruitingCount ?? 0;

    const transformedTeams = teams.map((team) => this.transformTeam(team));

    const groupsBySkillLevel = transformedTeams.reduce<Record<SkillLevel, TeamLeaderboardItemViewModel[]>>(
      (acc, team) => {
        if (!acc[team.performanceLevel]) {
          acc[team.performanceLevel] = [];
        }
        acc[team.performanceLevel]!.push(team);
        return acc;
      },
      {
        beginner: [],
        intermediate: [],
        advanced: [],
        pro: [],
      },
    );

    const topTeams = transformedTeams
      .filter((t) => t.rating !== null)
      .slice()
      .sort((a, b) => (b.rating ?? 0) - (a.rating ?? 0))
      .slice(0, 5);

    this.viewModel = {
      teams: transformedTeams,
      recruitingCount,
      groupsBySkillLevel,
      topTeams,
    };
  }

  getViewModel(): TeamsLeaderboardViewModel | null {
    return this.viewModel;
  }

  private transformTeam(team: TeamLeaderboardInput): TeamLeaderboardItemViewModel {
    let specialization: TeamLeaderboardItemViewModel['specialization'];
    if (
      team.specialization === 'endurance' ||
      team.specialization === 'sprint' ||
      team.specialization === 'mixed'
    ) {
      specialization = team.specialization;
    } else {
      specialization = undefined;
    }

    return {
      id: team.id,
      name: team.name,
      memberCount: team.memberCount,
      rating: team.rating,
      totalWins: team.totalWins,
      totalRaces: team.totalRaces,
      performanceLevel: team.performanceLevel,
      isRecruiting: team.isRecruiting,
      createdAt: team.createdAt,
      description: team.description ?? '',
      specialization: specialization ?? 'mixed',
      region: team.region ?? '',
      languages: team.languages ?? [],
    };
  }
}