import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../../teams/domain/player.dart';
import '../../teams/domain/team.dart';
import '../../teams/infrastructure/teams_repository.dart';

part 'stats_notifier.g.dart';

/// A player paired with the team they belong to. Records are emitted by the
/// stats providers so leaderboard rows can show "Player — Team" without doing
/// a second lookup.
typedef PlayerWithTeam = ({Player player, Team team});

/// Top scorers across every team, sorted by goals scored (descending). Ties
/// are broken by assists, then by player name so the order is deterministic.
@riverpod
Future<List<PlayerWithTeam>> topScorers(TopScorersRef ref) async {
  final teams = await ref.watch(teamsStreamProvider.future);
  final entries = <PlayerWithTeam>[
    for (final team in teams)
      for (final player in team.players) (player: player, team: team),
  ];
  entries.sort((a, b) {
    final byGoals = b.player.goalsScored.compareTo(a.player.goalsScored);
    if (byGoals != 0) return byGoals;
    final byAssists = b.player.assists.compareTo(a.player.assists);
    if (byAssists != 0) return byAssists;
    return a.player.name.compareTo(b.player.name);
  });
  return entries;
}

/// Top assisters across every team, sorted by assists (descending). Ties are
/// broken by goals, then by player name.
@riverpod
Future<List<PlayerWithTeam>> topAssisters(TopAssistersRef ref) async {
  final teams = await ref.watch(teamsStreamProvider.future);
  final entries = <PlayerWithTeam>[
    for (final team in teams)
      for (final player in team.players) (player: player, team: team),
  ];
  entries.sort((a, b) {
    final byAssists = b.player.assists.compareTo(a.player.assists);
    if (byAssists != 0) return byAssists;
    final byGoals = b.player.goalsScored.compareTo(a.player.goalsScored);
    if (byGoals != 0) return byGoals;
    return a.player.name.compareTo(b.player.name);
  });
  return entries;
}

/// League standings: teams sorted by wins (desc), then draws (desc), then by
/// fewer losses, then name. The points column shown in the UI is computed as
/// `wins * 3 + draws`.
@riverpod
Future<List<Team>> teamStandings(TeamStandingsRef ref) async {
  final teams = await ref.watch(teamsStreamProvider.future);
  final sorted = [...teams];
  sorted.sort((a, b) {
    final byWins = b.wins.compareTo(a.wins);
    if (byWins != 0) return byWins;
    final byDraws = b.draws.compareTo(a.draws);
    if (byDraws != 0) return byDraws;
    final byLosses = a.losses.compareTo(b.losses);
    if (byLosses != 0) return byLosses;
    return a.name.compareTo(b.name);
  });
  return sorted;
}
