import { Match } from "@/features/matches/types";
import { Player, PlayerInfo } from "@/features/players/types";
import { Team, TeamInfo } from "@/features/teams/types";
import { Tournament, TournamentInfo } from "@/features/tournaments/types";
import { Badge, BadgeInfo, BadgeProgress, EarnedBadge } from "@/features/badges/types";
import { Prediction } from "@/features/predictions/types";
import { Activity } from "../services/activities";

export function transformPlayerInfo(record: any): PlayerInfo {
  return {
    id: record.id,
    first_name: record.first_name,
    last_name: record.last_name,
  };
}

export function transformTeamInfo(record: any): TeamInfo {
  const players = record.expand?.players?.map(transformPlayerInfo) ?? [];
  return {
    id: record.id,
    name: record.name,
    primary_color: record.primary_color,
    accent_color: record.accent_color,
    players,
    logo: record.logo,
    private: record.private || false,
  };
}

export const transformMatch = (record: any, isAdmin: boolean = false): Match => {
  return {
    id: record.id,
    order: record.order,
    lid: record.lid,
    reset: record.reset,
    round: record.round,
    home_cups: record.home_cups,
    away_cups: record.away_cups,
    ot_count: record.ot_count,
    start_time: record.start_time,
    end_time: record.end_time,
    bye: record.bye,
    home_from_lid: record.home_from_lid,
    away_from_lid: record.away_from_lid,
    home_from_loser: record.home_from_loser,
    away_from_loser: record.away_from_loser,
    is_losers_bracket: record.is_losers_bracket,
    status: record.status || "tbd",
    tournament: record.expand?.tournament ? transformTournamentInfo(record.expand?.tournament) : record.tournament,
    home: record.expand?.home ? (isAdmin ? transformTeam(record.expand.home) : transformTeamInfo(record.expand.home)) : record.home,
    away: record.expand?.away ? (isAdmin ? transformTeam(record.expand.away) : transformTeamInfo(record.expand.away)) : record.away,
    created: record.created,
    updated: record.updated,
    home_seed: record.home_seed,
    away_seed: record.away_seed,
    match_type: record.match_type,
    group: record.group,
    reported_home_cups: record.reported_home_cups ?? undefined,
    reported_away_cups: record.reported_away_cups ?? undefined,
    reported_ot_count: record.reported_ot_count ?? undefined,
    reported_by_team: record.reported_by_team || undefined,
    reported_by_player: record.reported_by_player || undefined,
  };
}

export const transformTournamentInfo = (record: any): TournamentInfo => {
  const matches = record.expand?.matches || [];
  const nonByeMatches = matches.filter((match: any) => !(match.status === 'tbd' && match.bye === true));
  const isComplete = nonByeMatches.length > 0 && nonByeMatches.every((match: any) => match.status === 'ended');

  let first_place: TeamInfo | undefined = undefined;
  let second_place: TeamInfo | undefined = undefined;
  let third_place: TeamInfo | undefined = undefined;

  if (isComplete) {
    const teams = record.expand?.teams || [];
    const teamMap = new Map<string, TeamInfo>(teams.map((team: any) => [team.id, transformTeamInfo(team)]));

    const winnersMatches = matches.filter((match: any) => !match.is_losers_bracket);
    const finalsMatch = winnersMatches.reduce((highest: any, current: any) =>
      (!highest || current.lid > highest.lid) ? current : highest, null);

    const losersMatches = matches.filter((match: any) => match.is_losers_bracket);
    const losersFinale = losersMatches.reduce((highest: any, current: any) =>
      (!highest || current.lid > highest.lid) ? current : highest, null);

    if (finalsMatch && finalsMatch.status === 'ended') {
      const finalsWinner = (finalsMatch.home_cups > finalsMatch.away_cups) ? finalsMatch.home : finalsMatch.away;
      const finalsLoser = (finalsMatch.home_cups > finalsMatch.away_cups) ? finalsMatch.away : finalsMatch.home;

      const finalsWinnerId = typeof finalsWinner === 'string' ? finalsWinner : finalsWinner?.id;
      const finalsLoserId = typeof finalsLoser === 'string' ? finalsLoser : finalsLoser?.id;

      first_place = finalsWinnerId ? teamMap.get(finalsWinnerId) || undefined : undefined;
      second_place = finalsLoserId ? teamMap.get(finalsLoserId) || undefined : undefined;

    }

    if (losersFinale && losersFinale.status === 'ended') {
      const losersFinaleLoser = (losersFinale.home_cups > losersFinale.away_cups) ? losersFinale.away : losersFinale.home;

      const losersFinaleloserId = typeof losersFinaleLoser === 'string' ? losersFinaleLoser : losersFinaleLoser?.id;
      third_place = losersFinaleloserId ? teamMap.get(losersFinaleloserId) || undefined : undefined;
    }
  }

  return {
    id: record.id,
    name: record.name,
    location: record.location,
    start_time: record.start_time,
    end_time: record.end_time,
    logo: record.logo,
    glitch_logo: record.glitch_logo,
    regional: record.regional || false,
    first_place,
    second_place,
    third_place,
  };
}

export function transformPlayer(record: any): Player {
  const teams =
    record.expand?.teams
      ?.filter((team: any) => !team.private)
      ?.sort((a: any, b: any) =>
        new Date(a.created) < new Date(b.created) ? -1 : 0
      )
      ?.map(transformTeamInfo) ?? [];

  return {
    id: record.id!,
    first_name: record.first_name,
    last_name: record.last_name,
    auth_id: record.auth_id,
    created: record.created,
    updated: record.updated,
    last_activity: record.last_activity,
    teams,
  };
}

export function transformFreeAgent(record: any) {
  const player = record.expand?.player ? transformPlayerInfo(record.expand.player) : undefined;
  return {
    id: record.id as string,
    phone: record.phone as string,
    player
  };
}

export function transformTeam(record: any): Team {
  const players =
    record.expand?.players
      ?.sort((a: any, b: any) =>
        new Date(a.created!) < new Date(b.created!) ? -1 : 0
      )
      ?.map(transformPlayerInfo) ?? [];
  const tournaments =
    record.expand?.tournaments
      ?.sort((a: any, b: any) =>
        new Date(a.created!) < new Date(b.created!) ? -1 : 0
      )
      ?.map(transformTournamentInfo) ?? [];

  return {
    id: record.id,
    name: record.name,
    logo: record.logo,
    primary_color: record.primary_color,
    accent_color: record.accent_color,
    song_id: record.song_id,
    song_name: record.song_name,
    song_artist: record.song_artist,
    song_album: record.song_album,
    song_start: record.song_start,
    song_end: record.song_end,
    song_image_url: record.song_image_url,
    created: record.created,
    updated: record.updated,
    players,
    tournaments,
    private: record.private || false,
  };
}

export function transformTournament(record: any, isAdmin: boolean = false): Tournament {
  const teams =
    record.expand?.teams
      ?.sort((a: any, b: any) =>
        new Date(a.created) < new Date(b.created) ? -1 : 0
      )
      ?.map(isAdmin ? transformTeam : transformTeamInfo) ?? [];

  const matches =
    record.expand?.matches
      ?.sort((a: any, b: any) =>
        a.lid - b.lid ? -1 : 0
      )
      ?.map((match: any) => transformMatch(match, isAdmin)) ?? [];

  const team_stats = record.team_stats?.map((stat: any) => ({
    id: stat.id,
    team_id: stat.team_id,
    tournament_id: stat.tournament_id,
    team_name: stat.team_name,
    matches: stat.matches,
    wins: stat.wins,
    losses: stat.losses,
    total_cups_made: stat.total_cups_made,
    total_cups_against: stat.total_cups_against,
    margin_of_victory: stat.margin_of_victory,
    margin_of_loss: stat.margin_of_loss,
    win_percentage: (stat.wins / stat.matches) * 100,
    avg_cups_per_match: stat.total_cups_made / stat.matches,
  })) ?? [];

  const nonByeMatches = matches.filter((match: any) => !(match.status === 'tbd' && match.bye === true));
  const isComplete = nonByeMatches.length > 0 && nonByeMatches.every((match: any) => match.status === 'ended');

  let first_place: TeamInfo | undefined = undefined;
  let second_place: TeamInfo | undefined = undefined;
  let third_place: TeamInfo | undefined = undefined;

  if (isComplete) {
    const teamMap = new Map<string, TeamInfo>(teams.map((team: any) => [team.id, team]));

    const winnersMatches = matches.filter((match: any) => !match.is_losers_bracket);
    const finalsMatch = winnersMatches.reduce((highest: any, current: any) =>
      (!highest || current.lid > highest.lid) ? current : highest, null);

    const losersMatches = matches.filter((match: any) => match.is_losers_bracket);
    const losersFinale = losersMatches.reduce((highest: any, current: any) =>
      (!highest || current.lid > highest.lid) ? current : highest, null);

    if (finalsMatch && finalsMatch.status === 'ended') {
      const finalsWinner = (finalsMatch.home_cups > finalsMatch.away_cups) ? finalsMatch.home : finalsMatch.away;
      const finalsLoser = (finalsMatch.home_cups > finalsMatch.away_cups) ? finalsMatch.away : finalsMatch.home;

      const finalsWinnerId = typeof finalsWinner === 'string' ? finalsWinner : finalsWinner?.id;
      const finalsLoserId = typeof finalsLoser === 'string' ? finalsLoser : finalsLoser?.id;

      first_place = finalsWinnerId ? teamMap.get(finalsWinnerId) || undefined : undefined;
      second_place = finalsLoserId ? teamMap.get(finalsLoserId) || undefined : undefined;
    }

    if (losersFinale && losersFinale.status === 'ended') {
      const losersFinaleLoser = (losersFinale.home_cups > losersFinale.away_cups) ? losersFinale.away : losersFinale.home;

      const losersFinaleloserId = typeof losersFinaleLoser === 'string' ? losersFinaleLoser : losersFinaleLoser?.id;
      third_place = losersFinaleloserId ? teamMap.get(losersFinaleloserId) || undefined : undefined;
    }
  }

  const groups = (record.groups || record.expand?.groups)?.map((group: any) => ({
    id: group.id,
    tournament: group.tournament,
    name: group.name,
    order: group.order,
    teams: group.expand?.teams?.map(transformTeamInfo) ?? [],
    created: group.created,
    updated: group.updated,
  })) ?? [];

  return {
    id: record.id,
    name: record.name,
    location: record.location,
    desc: record.desc,
    rules: record.rules,
    logo: record.logo,
    glitch_logo: record.glitch_logo,
    enroll_time: record.enroll_time,
    start_time: record.start_time,
    end_time: record.end_time,
    created: record.created,
    updated: record.updated,
    regional: record.regional || false,
    format: record.format,
    phase: record.phase,
    group_config: record.group_config,
    teams,
    matches,
    groups,
    first_place,
    second_place,
    third_place,
    team_stats,
  };
}

export function transformReaction(record: any) {
  return {
    id: record.id,
    emoji: record.emoji,
    player: transformPlayerInfo(record.expand.player),
    match: record.match
  };
}

export function transformPrediction(record: any): Prediction {
  return {
    id: record.id,
    tournament: record.tournament,
    player: transformPlayerInfo(record.expand?.player ?? { id: record.player }),
    picks: record.picks || {},
    created: record.created,
    updated: record.updated,
  };
}

export function transformBadgeInfo(record: any): BadgeInfo {
  return {
    id: record.id,
    name: record.name,
    key: record.key,
    description: record.description,
    type: record.type,
    progressive: record.progressive,
    order: record.order ?? 999,
  };
}

export function transformBadge(record: any): Badge {
  return {
    ...transformBadgeInfo(record),
    criteria: record.criteria,
    created: record.created,
    updated: record.updated,
  };
}

export function transformBadgeProgress(record: any): BadgeProgress {
  return {
    id: record.id,
    badge: record.expand?.badge ? transformBadgeInfo(record.expand.badge) : record.badge,
    player: record.player,
    progress: record.progress,
    earned: record.earned,
    created: record.created,
    updated: record.updated,
  };
}

export function transformEarnedBadge(record: any): EarnedBadge {
  return {
    id: record.id,
    badge: record.badge,
    player: record.expand?.player ? transformPlayerInfo(record.expand.player) : record.player,
    progress: record.progress,
    earned: record.earned,
    created: record.created,
    updated: record.updated,
  };
}

export function transformActivity(record: any): Activity {
  return {
    id: record.id,
    name: record.name,
    player: record.expand?.player ? transformPlayerInfo(record.expand.player) : record.player,
    duration: record.duration,
    success: record.success,
    error: record.error,
    arguments: record.arguments,
    user_agent: record.user_agent,
    created: record.created,
    updated: record.updated,
  };
}
