<?php
declare(strict_types=1);

$partiesFile = dirname(__DIR__) . '/privatedata/parties.json';

function h($value): string {
    return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
}

function readJson(string $file, $default) {
    if (!file_exists($file)) {
        return $default;
    }

    $json = json_decode((string)file_get_contents($file), true);
    return is_array($json) ? $json : $default;
}

function formatDuration($seconds): string {
    $seconds = max(0, (int)$seconds);
    $min = floor($seconds / 60);
    $sec = $seconds % 60;

    if ($min <= 0) {
        return $sec . ' s';
    }

    return $min . ' min ' . str_pad((string)$sec, 2, '0', STR_PAD_LEFT) . ' s';
}

function partyUrl(array $party): string {
    return '/jeux/partie/?id=' . urlencode((string)($party['id'] ?? ''));
}

function teamPlayersLabel(array $team): string {
    $names = [];

    foreach (($team['players'] ?? []) as $player) {
        if (is_array($player)) {
            $name = trim((string)($player['name'] ?? ''));
        } else {
            $name = trim((string)$player);
        }

        if ($name !== '') {
            $names[] = $name;
        }
    }

    sort($names, SORT_NATURAL | SORT_FLAG_CASE);

    return implode(' + ', $names);
}

function teamKey(array $team): string {
    $label = teamPlayersLabel($team);

    if ($label !== '') {
        return mb_strtolower($label);
    }

    return mb_strtolower(trim((string)($team['name'] ?? 'Équipe inconnue')));
}

function rankIcon(int $index): string {
    if ($index === 0) return '🥇';
    if ($index === 1) return '🥈';
    if ($index === 2) return '🥉';
    return (string)($index + 1);
}

function isCoopWin(array $party): bool {
    if (isset($party['coop']) && is_array($party['coop'])) {
        if (($party['coop']['won'] ?? null) === true) {
            return true;
        }
        if (($party['coop']['result'] ?? '') === 'victory') {
            return true;
        }
    }

    $winner = mb_strtolower(trim((string)($party['winner'] ?? '')));
    return str_contains($winner, 'vaincu') || str_contains($winner, 'victoire');
}

function teamBadges(array $team): array {
    $mode = (string)($team['mode'] ?? 'classic');
    $games = (int)($team['games'] ?? 0);
    $wins = (int)($team['wins'] ?? 0);
    $score = (int)($team['total_score'] ?? 0);
    $winrate = $games > 0 ? round(($wins / $games) * 100) : 0;
    $avg = $games > 0 ? round($score / $games, 1) : 0;
    $bestParty = (int)($team['best_party_score'] ?? 0);

    $badges = [];

    if ($mode === 'coop') {
        if ($wins >= 3) {
            $badges[] = ['icon' => '🤝', 'label' => 'Duo anti-boss'];
        }

        if ($winrate >= 70 && $games >= 3) {
            $badges[] = ['icon' => '👑', 'label' => 'Boss maîtrisé'];
        }

        if ($bestParty >= 100) {
            $badges[] = ['icon' => '🔥', 'label' => 'Gros score Coop'];
        }

        if ($avg >= 80) {
            $badges[] = ['icon' => '⚡', 'label' => 'Coop explosive'];
        }

        return $badges;
    }

    if ($wins >= 5) {
        $badges[] = ['icon' => '🏆', 'label' => 'Équipe gagnante'];
    }

    if ($winrate >= 70 && $games >= 3) {
        $badges[] = ['icon' => '🎯', 'label' => 'Duo redoutable'];
    }

    if ($score >= 300) {
        $badges[] = ['icon' => '🔥', 'label' => 'Machine à points'];
    }

    if ($avg >= 60) {
        $badges[] = ['icon' => '⚡', 'label' => 'Rythme explosif'];
    }

    if ($bestParty >= 80) {
        $badges[] = ['icon' => '🚀', 'label' => 'Partie légendaire'];
    }

    return $badges;
}

function queryUrl(string $mode, string $sort): string {
    return '?mode=' . urlencode($mode) . '&sort=' . urlencode($sort);
}

$mode = (string)($_GET['mode'] ?? 'all');
if (!in_array($mode, ['all', 'classic', 'coop'], true)) {
    $mode = 'all';
}

$sort = (string)($_GET['sort'] ?? 'wins');
if (!in_array($sort, ['wins', 'score', 'avg', 'winrate'], true)) {
    $sort = 'wins';
}

$parties = readJson($partiesFile, []);
$teamsStats = [];

foreach ($parties as $party) {

    if (!is_array($party)) {
        continue;
    }

    $partyStatus = (string)($party['status'] ?? 'validated');

    if ($partyStatus === 'excluded' || $partyStatus === 'suspect') {
        continue;
    }

    // Si l'anti-triche a signalé la partie, elle ne compte pas tant que l'admin ne l'a pas publiée.
    // Quand tu cliques sur "Publier quand même", le statut passe à "validated" : elle est alors comptée.
    if (!empty($party['suspicious']) && $partyStatus !== 'validated') {
        continue;
    }

    $isCoopParty = (($party['game_mode'] ?? 'classic') === 'coop') || !empty($party['coop']['enabled']);
    $partyMode = $isCoopParty ? 'coop' : 'classic';

    if ($mode !== 'all' && $mode !== $partyMode) {
        continue;
    }

    $winner = trim((string)($party['winner'] ?? ''));
    $partyId = (string)($party['id'] ?? '');
    $createdAt = (string)($party['created_at'] ?? '');
    $coopWon = $isCoopParty ? isCoopWin($party) : false;
    $coopLabel = '';

    if ($isCoopParty && isset($party['coop']) && is_array($party['coop'])) {
        $coopLabel = trim((string)(($party['coop']['label'] ?? '') ?: ($party['coop']['rank_label'] ?? '')));
    }

    foreach (($party['teams'] ?? []) as $team) {
        if (!is_array($team)) {
            continue;
        }

        $baseKey = teamKey($team);
        $key = $partyMode . '|' . $baseKey;
        $playersLabel = teamPlayersLabel($team);
        $teamName = trim((string)($team['name'] ?? 'Équipe inconnue'));
        $score = (int)($team['total'] ?? 0);
        $isWinner = $isCoopParty ? $coopWon : ($winner !== '' && $teamName === $winner);

        if (!isset($teamsStats[$key])) {
            $teamsStats[$key] = [
                'key' => $key,
                'mode' => $partyMode,
                'label' => $playersLabel !== '' ? $playersLabel : $teamName,
                'last_team_name' => $isCoopParty ? ($coopLabel !== '' ? $coopLabel : 'Groupe Coop') : $teamName,
                'games' => 0,
                'wins' => 0,
                'total_score' => 0,
                'best_party_score' => 0,
                'best_party_id' => '',
                'last_party_id' => '',
                'last_played_at' => '',
                'players' => [],
            ];
        }

        $teamsStats[$key]['games']++;
        $teamsStats[$key]['total_score'] += $score;
        $teamsStats[$key]['last_team_name'] = $isCoopParty ? ($coopLabel !== '' ? $coopLabel : 'Groupe Coop') : $teamName;
        $teamsStats[$key]['last_party_id'] = $partyId;
        $teamsStats[$key]['last_played_at'] = $createdAt;

        if ($isWinner) {
            $teamsStats[$key]['wins']++;
        }

        if ($score > (int)$teamsStats[$key]['best_party_score']) {
            $teamsStats[$key]['best_party_score'] = $score;
            $teamsStats[$key]['best_party_id'] = $partyId;
        }

        foreach (($team['players'] ?? []) as $player) {
            if (is_array($player)) {
                $name = trim((string)($player['name'] ?? ''));
            } else {
                $name = trim((string)$player);
            }

            if ($name !== '') {
                $teamsStats[$key]['players'][$name] = true;
            }
        }
    }
}

$teams = array_values($teamsStats);

foreach ($teams as &$team) {
    $games = (int)$team['games'];
    $wins = (int)$team['wins'];
    $score = (int)$team['total_score'];

    $team['_avg'] = $games > 0 ? round($score / $games, 1) : 0;
    $team['_winrate'] = $games > 0 ? round(($wins / $games) * 100) : 0;
    $team['_losses'] = max(0, $games - $wins);
    $team['_mode_label'] = (($team['mode'] ?? 'classic') === 'coop') ? 'Coop' : 'Classique';
}
unset($team);

usort($teams, function($a, $b) use ($sort) {
    if ($sort === 'score') {
        return (($b['total_score'] ?? 0) <=> ($a['total_score'] ?? 0))
            ?: (($b['wins'] ?? 0) <=> ($a['wins'] ?? 0));
    }

    if ($sort === 'avg') {
        return (($b['_avg'] ?? 0) <=> ($a['_avg'] ?? 0))
            ?: (($b['wins'] ?? 0) <=> ($a['wins'] ?? 0));
    }

    if ($sort === 'winrate') {
        return (($b['_winrate'] ?? 0) <=> ($a['_winrate'] ?? 0))
            ?: (($b['wins'] ?? 0) <=> ($a['wins'] ?? 0));
    }

    return (($b['wins'] ?? 0) <=> ($a['wins'] ?? 0))
        ?: (($b['total_score'] ?? 0) <=> ($a['total_score'] ?? 0));
});

$topTeams = array_slice($teams, 0, 50);
$isCoopView = ($mode === 'coop');
$isClassicView = ($mode === 'classic');
$victoryLabel = $isCoopView ? 'Boss vaincus' : 'Victoires';
$lossLabel = $isCoopView ? 'Boss perdus' : 'Défaites';
$rateLabel = $isCoopView ? 'Réussite Coop' : 'Taux victoire';
$scoreLabel = $isCoopView ? 'Mots trouvés' : 'Score total';
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Top équipes Chrono Party</title>
<meta name="description" content="Classement des meilleures équipes Chrono Party : équipes classiques, groupes Coop, boss vaincus, scores, moyenne et taux de réussite.">
<meta name="viewport" content="width=device-width, initial-scale=1">

<style>
:root{
  --bg1:#140f2d;
  --bg2:#08111f;
  --card:rgba(255,255,255,.08);
  --line:rgba(255,255,255,.14);
  --text:#fff;
  --muted:rgba(255,255,255,.72);
  --accent:#8b5cf6;
  --accent2:#22d3ee;
  --yellow:#ffd84d;
}

*{box-sizing:border-box}

body{
  margin:0;
  min-height:100vh;
  font-family:Arial, Helvetica, sans-serif;
  color:var(--text);
  background:
    radial-gradient(circle at top left, rgba(139,92,246,.35), transparent 35%),
    radial-gradient(circle at top right, rgba(34,211,238,.24), transparent 35%),
    linear-gradient(160deg,var(--bg1),var(--bg2));
  padding:18px;
  padding-bottom:110px;
}

.container{
  max-width:1150px;
  margin:0 auto;
}

.header{
  text-align:center;
  padding:22px 10px 18px;
}

.logo{
  width:76px;
  height:76px;
  border-radius:24px;
  margin:0 auto 12px;
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:38px;
  background:linear-gradient(135deg,#8b5cf6,#22d3ee);
  box-shadow:0 18px 45px rgba(0,0,0,.35);
}

h1{
  margin:0;
  font-size:clamp(28px,6vw,48px);
  letter-spacing:-1px;
}

.subtitle{
  margin:10px auto 0;
  max-width:720px;
  color:var(--muted);
  line-height:1.5;
  font-size:15px;
}

.tabs{
  display:flex;
  gap:10px;
  justify-content:center;
  flex-wrap:wrap;
  margin:18px 0 22px;
}

.tab{
  color:#fff;
  text-decoration:none;
  padding:10px 14px;
  border-radius:999px;
  border:1px solid var(--line);
  background:rgba(255,255,255,.07);
  font-weight:800;
  font-size:14px;
}

.tab.active{
  background:linear-gradient(135deg,#8b5cf6,#22d3ee);
  border-color:transparent;
  box-shadow:0 10px 25px rgba(0,0,0,.28);
}

.podium{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:14px;
  margin:0 0 18px;
}

.podiumCard{
  position:relative;
  overflow:hidden;
  border:1px solid rgba(255,255,255,.18);
  border-radius:26px;
  padding:18px;
  text-align:center;
  box-shadow:0 18px 45px rgba(0,0,0,.28);
  background:linear-gradient(135deg,rgba(139,92,246,.22),rgba(34,211,238,.12));
}

.podiumCard.first{
  background:linear-gradient(135deg,rgba(255,215,0,.20),rgba(255,255,255,.08));
  transform:translateY(-6px);
}

.podiumRank{
  font-size:34px;
  margin-bottom:8px;
}

.teamName{
  font-size:18px;
  font-weight:1000;
  margin-bottom:8px;
}

.teamMeta{
  color:var(--muted);
  font-size:13px;
  line-height:1.5;
}

.badges{
  display:flex;
  gap:5px;
  flex-wrap:wrap;
  margin:9px 0;
  justify-content:center;
}

.badgeMini{
  position:relative;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  min-width:28px;
  height:28px;
  padding:0 7px;
  border-radius:10px;
  background:rgba(255,255,255,.10);
  border:1px solid rgba(255,255,255,.14);
  font-size:15px;
}

.badgeMini:hover::after{
  content:attr(data-label);
  position:absolute;
  bottom:34px;
  left:50%;
  transform:translateX(-50%);
  white-space:nowrap;
  background:#111827;
  color:#fff;
  font-size:12px;
  font-weight:900;
  padding:6px 8px;
  border-radius:8px;
  box-shadow:0 10px 25px rgba(0,0,0,.3);
  z-index:20;
}

.tableBox{
  background:var(--card);
  border:1px solid var(--line);
  border-radius:26px;
  overflow:hidden;
  box-shadow:0 18px 50px rgba(0,0,0,.25);
}

table{
  width:100%;
  border-collapse:collapse;
}

th,td{
  padding:15px 10px;
  text-align:center;
  border-bottom:1px solid rgba(255,255,255,.08);
}

th{
  color:rgba(255,255,255,.8);
  font-size:12px;
  text-transform:uppercase;
  letter-spacing:.04em;
  background:rgba(255,255,255,.06);
}

td.name{
  text-align:left;
  font-weight:1000;
}

.rank{
  font-size:20px;
  font-weight:1000;
}

.link{
  color:#a5f3fc;
  text-decoration:none;
  font-weight:1000;
  border-bottom:1px dashed rgba(165,243,252,.75);
}

.link:hover{
  color:white;
  border-bottom-color:white;
}

.pill{
  display:inline-block;
  margin-top:5px;
  padding:6px 9px;
  border-radius:999px;
  background:rgba(255,255,255,.10);
  color:rgba(255,255,255,.82);
  font-size:12px;
  font-weight:900;
}

.empty{
  text-align:center;
  padding:26px;
  color:var(--muted);
  background:var(--card);
  border-radius:22px;
  border:1px solid var(--line);
}

.mobileList{
  display:none;
}

.teamCard{
  background:var(--card);
  border:1px solid var(--line);
  border-radius:22px;
  padding:14px;
  margin-bottom:12px;
  box-shadow:0 12px 32px rgba(0,0,0,.22);
}

.teamTop{
  display:flex;
  gap:12px;
  align-items:flex-start;
  justify-content:space-between;
}

.mobileRank{
  width:44px;
  height:44px;
  border-radius:16px;
  display:flex;
  align-items:center;
  justify-content:center;
  background:rgba(255,255,255,.12);
  font-weight:1000;
  font-size:20px;
  flex-shrink:0;
}

.mobileLeft{
  display:flex;
  gap:12px;
  align-items:flex-start;
  min-width:0;
}

.scorePill{
  padding:8px 11px;
  border-radius:999px;
  background:linear-gradient(135deg,rgba(139,92,246,.85),rgba(34,211,238,.85));
  font-weight:1000;
  white-space:nowrap;
}

.statsGrid{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:8px;
  margin-top:12px;
}

.statBox{
  border-radius:16px;
  background:rgba(255,255,255,.08);
  border:1px solid rgba(255,255,255,.09);
  padding:10px 8px;
  text-align:center;
}

.statBox strong{
  display:block;
  font-size:18px;
}

.statBox span{
  display:block;
  color:var(--muted);
  font-size:11px;
  margin-top:3px;
}

.bottomActions{
  position:fixed;
  left:50%;
  bottom:calc(12px + env(safe-area-inset-bottom));
  transform:translateX(-50%);
  width:calc(100% - 24px);
  max-width:520px;
  z-index:9999;
  margin:0;
  padding:10px;
  border-radius:26px;
  background:rgba(7,17,31,.82);
  border:1px solid rgba(255,255,255,.12);
  backdrop-filter:blur(14px);
  box-shadow:0 14px 36px rgba(0,0,0,.35);
}

.bottomActionsGrid{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:10px;
}

.bottomBtn{
  appearance:none;
  border:0;
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:center;
  min-height:46px;
  padding:11px 12px;
  border-radius:18px;
  color:white;
  text-decoration:none;
  font-weight:1000;
  font-size:14px;
  background:rgba(255,255,255,.09);
  border:1px solid rgba(255,255,255,.14);
}

.bottomBtn.primary{
  background:linear-gradient(135deg,var(--accent),var(--accent2));
  border-color:transparent;
}

.bottomBtn.danger{
  background:rgba(255,255,255,.08);
}

.profileModal{
  display:none;
  position:fixed;
  inset:0;
  z-index:100;
  background:rgba(0,0,0,.62);
  padding:18px;
  align-items:center;
  justify-content:center;
}

.profileModal.open{display:flex}

.profileModalBox{
  width:min(420px,100%);
  background:#15122f;
  border:1px solid rgba(255,255,255,.16);
  border-radius:26px;
  padding:20px;
  box-shadow:0 24px 70px rgba(0,0,0,.45);
}

.profileModalBox h2{
  margin:0 0 8px;
  font-size:24px;
}

.profileModalBox p{
  margin:0 0 14px;
  color:var(--muted);
}

.profileChoice{
  display:flex;
  width:100%;
  border:1px solid rgba(255,255,255,.14);
  background:rgba(255,255,255,.08);
  color:white;
  border-radius:18px;
  padding:13px 14px;
  margin:8px 0;
  font-weight:1000;
  cursor:pointer;
  text-align:left;
}

.profileClose{
  margin-top:12px;
  width:100%;
}

@media(max-width:820px){
  body{
    padding:12px;
    padding-bottom:110px;
  }

  .podium{
    grid-template-columns:1fr;
  }

  .podiumCard.first{
    transform:none;
  }

  .tableBox{
    display:none;
  }

  .mobileList{
    display:block;
  }

  .tabs{
    gap:8px;
  }

  .tab{
    flex:1;
    text-align:center;
    min-width:130px;
    padding:10px 8px;
    font-size:13px;
  }

  .bottomActions{
    bottom:8px;
    border-radius:22px;
  }

  .bottomActionsGrid{
    grid-template-columns:1fr 1fr;
  }

  .bottomBtn{
    min-height:44px;
    font-size:14px;
  }
}


/* Filtres par colonne */
.columnFilterRow th{
  background:rgba(255,255,255,.08) !important;
  padding:8px !important;
}
.columnFilterRow input{
  width:100%;
  box-sizing:border-box;
  border:1px solid rgba(255,255,255,.22);
  border-radius:10px;
  padding:8px 9px;
  background:rgba(255,255,255,.10);
  color:inherit;
  font-weight:800;
  outline:none;
}
.columnFilterRow input::placeholder{color:rgba(255,255,255,.58)}
.filterCounter{
  margin:10px 0 14px;
  font-size:13px;
  font-weight:900;
  color:inherit;
  opacity:.82;
}

</style>
</head>

<body>
<div class="container">

<header class="header">
  <div class="logo">👥</div>
  <h1>Top équipes</h1>
  <p class="subtitle">
    Les équipes classiques et les groupes Coop sont séparés pour éviter de mélanger les victoires contre le Boss avec les victoires d'équipes.
  </p>
</header>

<nav class="tabs">
  <a class="tab <?= $mode === 'all' ? 'active' : '' ?>" href="<?= h(queryUrl('all', $sort)) ?>">🌍 Tous</a>
  <a class="tab <?= $mode === 'classic' ? 'active' : '' ?>" href="<?= h(queryUrl('classic', $sort)) ?>">⚔️ Classique</a>
  <a class="tab <?= $mode === 'coop' ? 'active' : '' ?>" href="<?= h(queryUrl('coop', $sort)) ?>">🤝 Coop</a>
</nav>

<nav class="tabs">
  <a class="tab <?= $sort === 'wins' ? 'active' : '' ?>" href="<?= h(queryUrl($mode, 'wins')) ?>">🏆 <?= h($victoryLabel) ?></a>
  <a class="tab <?= $sort === 'score' ? 'active' : '' ?>" href="<?= h(queryUrl($mode, 'score')) ?>">🔥 <?= h($scoreLabel) ?></a>
  <a class="tab <?= $sort === 'avg' ? 'active' : '' ?>" href="<?= h(queryUrl($mode, 'avg')) ?>">⚡ Moyenne</a>
  <a class="tab <?= $sort === 'winrate' ? 'active' : '' ?>" href="<?= h(queryUrl($mode, 'winrate')) ?>">🎯 <?= h($rateLabel) ?></a>
</nav>

<?php if (empty($topTeams)): ?>

  <div class="empty">
    Aucune équipe enregistrée pour ce filtre.
  </div>

<?php else: ?>

  <section class="podium">
    <?php foreach(array_slice($topTeams, 0, 3) as $index => $team): ?>
      <?php $badges = teamBadges($team); ?>

      <article class="podiumCard <?= $index === 0 ? 'first' : '' ?>">
        <div class="podiumRank"><?= h(rankIcon($index)) ?></div>
        <div class="teamName"><?= h($team['label']) ?></div>

        <?php if (!empty($badges)): ?>
          <div class="badges">
            <?php foreach($badges as $badge): ?>
              <span class="badgeMini" data-label="<?= h($badge['label']) ?>">
                <?= h($badge['icon']) ?>
              </span>
            <?php endforeach; ?>
          </div>
        <?php endif; ?>

        <div class="teamMeta">
          <?= h($team['wins']) ?> <?= h(mb_strtolower($victoryLabel)) ?> ·
          <?= h($team['_losses']) ?> <?= h(mb_strtolower($lossLabel)) ?> ·
          <?= h($team['games']) ?> partie(s)<br>
          <?= h($team['total_score']) ?> pts ·
          <?= h($team['_winrate']) ?>% <?= h(mb_strtolower($rateLabel)) ?>
        </div>
      </article>
    <?php endforeach; ?>
  </section>

  <div class="tableBox">
    <table>
      <thead>
      <tr>
        <th>#</th>
        <th>Équipe / Groupe</th>
        <th>Parties</th>
        <th><?= h($victoryLabel) ?></th>
        <th><?= h($lossLabel) ?></th>
        <th><?= h($scoreLabel) ?></th>
        <th>Moyenne</th>
        <th><?= h($rateLabel) ?></th>
        <th>Record partie</th>
        <th>Dernière partie</th>
      </tr>
      </thead>

      <tbody>
      <?php foreach($topTeams as $index => $team): ?>
        <?php $badges = teamBadges($team); ?>

        <tr>
          <td class="rank"><?= h(rankIcon($index)) ?></td>

          <td class="name">
            <?= h($team['label']) ?>

            <?php if (!empty($badges)): ?>
              <div class="badges" style="justify-content:flex-start">
                <?php foreach($badges as $badge): ?>
                  <span class="badgeMini" data-label="<?= h($badge['label']) ?>">
                    <?= h($badge['icon']) ?>
                  </span>
                <?php endforeach; ?>
              </div>
            <?php endif; ?>

            <span class="pill"><?= h($team['_mode_label']) ?> · <?= h($team['last_team_name']) ?></span>
          </td>

          <td><?= h($team['games']) ?></td>
          <td><?= h($team['wins']) ?></td>
          <td><?= h($team['_losses']) ?></td>
          <td><strong><?= h($team['total_score']) ?></strong></td>
          <td><?= h($team['_avg']) ?></td>
          <td><?= h($team['_winrate']) ?>%</td>

          <td>
            <?php if (!empty($team['best_party_id'])): ?>
              <a class="link" href="/jeux/partie/?id=<?= urlencode((string)$team['best_party_id']) ?>">
                <?= h($team['best_party_score']) ?> pts
              </a>
            <?php else: ?>
              —
            <?php endif; ?>
          </td>

          <td>
            <?php if (!empty($team['last_party_id'])): ?>
              <a class="link" href="/jeux/partie/?id=<?= urlencode((string)$team['last_party_id']) ?>">
                Voir
              </a>
            <?php else: ?>
              —
            <?php endif; ?>
          </td>
        </tr>
      <?php endforeach; ?>
      </tbody>
    </table>
  </div>

  <div class="mobileList">
    <?php foreach($topTeams as $index => $team): ?>
      <?php $badges = teamBadges($team); ?>

      <article class="teamCard">
        <div class="teamTop">
          <div class="mobileLeft">
            <div class="mobileRank"><?= h(rankIcon($index)) ?></div>
            <div>
              <div class="teamName"><?= h($team['label']) ?></div>
              <div class="teamMeta">
                <?= h($team['wins']) ?> <?= h(mb_strtolower($victoryLabel)) ?> ·
                <?= h($team['_losses']) ?> <?= h(mb_strtolower($lossLabel)) ?> ·
                <?= h($team['games']) ?> partie(s)
              </div>

              <?php if (!empty($badges)): ?>
                <div class="badges" style="justify-content:flex-start">
                  <?php foreach($badges as $badge): ?>
                    <span class="badgeMini" data-label="<?= h($badge['label']) ?>">
                      <?= h($badge['icon']) ?>
                    </span>
                  <?php endforeach; ?>
                </div>
              <?php endif; ?>
            </div>
          </div>

          <div class="scorePill">
            <?= h($team['total_score']) ?> pts
          </div>
        </div>

        <div class="statsGrid">
          <div class="statBox">
            <strong><?= h($team['_avg']) ?></strong>
            <span>Moyenne</span>
          </div>

          <div class="statBox">
            <strong><?= h($team['_losses']) ?></strong>
            <span><?= h($lossLabel) ?></span>
          </div>

          <div class="statBox">
            <strong><?= h($team['_winrate']) ?>%</strong>
            <span><?= h($rateLabel) ?></span>
          </div>

          <div class="statBox">
            <strong><?= h($team['best_party_score']) ?></strong>
            <span>Record</span>
          </div>
        </div>

        <?php if (!empty($team['best_party_id'])): ?>
          <p style="margin:12px 0 0">
            <a class="link" href="/jeux/partie/?id=<?= urlencode((string)$team['best_party_id']) ?>">
              Voir la meilleure partie →
            </a>
          </p>
        <?php endif; ?>
      </article>
    <?php endforeach; ?>
  </div>

<?php endif; ?>

<div class="bottomActions">
  <div class="bottomActionsGrid">
    <a class="bottomBtn primary" href="/statistiques/">📊 Statistiques</a>
    <button type="button" class="bottomBtn danger" onclick="closeStatsPage()">✕ Fermer</button>
  </div>
</div>

<div id="profileModal" class="profileModal" aria-hidden="true">
  <div class="profileModalBox">
    <h2>👤 Mon profil joueur</h2>
    <p id="profileModalText">Choisis le profil à consulter.</p>
    <div id="profileChoices"></div>
    <button type="button" class="bottomBtn profileClose" onclick="closeProfileModal()">Fermer</button>
  </div>
</div>

</div>

<script>
const PROFILE_BASE_URL = '/joueur/?id=';

function closeStatsPage(){
  window.location.href = '/jeux/';
}

async function openMyPlayerProfile(){

  const savedId = localStorage.getItem('chrono_personal_player_id');

  if(savedId){
    window.location.href = PROFILE_BASE_URL + encodeURIComponent(savedId);
    return;
  }

  const modal = document.getElementById('profileModal');
  const choices = document.getElementById('profileChoices');
  const text = document.getElementById('profileModalText');

  text.textContent = 'Indique ton prénom et ton initiale pour retrouver ton profil joueur.';

  choices.innerHTML = `
    <input id="profileFirstName" type="text" placeholder="Prénom, ex : Giovanni" style="width:100%;margin:8px 0;padding:13px;border-radius:14px;border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.08);color:white;font-weight:900;">
    <input id="profileInitials" type="text" maxlength="2" placeholder="Initiale, ex : C" style="width:100%;margin:8px 0;padding:13px;border-radius:14px;border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.08);color:white;font-weight:900;">
    <button type="button" class="bottomBtn primary" style="width:100%;margin-top:10px" onclick="confirmMyPlayerProfile()">Valider mon profil</button>
  `;

  modal.classList.add('open');
  modal.setAttribute('aria-hidden', 'false');

  setTimeout(function(){
    const input = document.getElementById('profileFirstName');
    if(input) input.focus();
  }, 100);
}

async function confirmMyPlayerProfile(){

  const nameInput = document.getElementById('profileFirstName');
  const initialsInput = document.getElementById('profileInitials');

  const name = nameInput ? nameInput.value.trim() : '';
  const initials = initialsInput ? initialsInput.value.trim().toUpperCase() : '';

  if(!name || !initials){
    alert('Indique ton prénom et ton initiale.');
    return;
  }

  try{
    const response = await fetch('/api/player-profile.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name, initials })
    });

    const data = await response.json();

    if(!response.ok || !data.ok || !data.player || !data.player.id){
      alert(data.error || 'Profil joueur introuvable.');
      return;
    }

    const displayName = ((data.player.name || name) + ' ' + (data.player.initials || initials)).trim();

    localStorage.setItem('chrono_personal_player_id', data.player.id);
    localStorage.setItem('chrono_personal_player_name', displayName);

    window.location.href = PROFILE_BASE_URL + encodeURIComponent(data.player.id);

  }catch(e){
    alert('Impossible de récupérer le profil joueur.');
  }
}

function closeProfileModal(){
  const modal = document.getElementById('profileModal');
  modal.classList.remove('open');
  modal.setAttribute('aria-hidden', 'true');
}

document.addEventListener('click', function(event){
  const modal = document.getElementById('profileModal');
  if(event.target === modal){
    closeProfileModal();
  }
});
</script>


<script>
(function(){
  function normalizeText(value){
    return (value || '')
      .toString()
      .toLowerCase()
      .normalize('NFD')
      .replace(/[\u0300-\u036f]/g, '')
      .trim();
  }

  function setupColumnFilters(){
    document.querySelectorAll('table').forEach(function(table, tableIndex){
      if(table.dataset.columnFiltersReady === '1') return;
      const thead = table.querySelector('thead');
      const tbody = table.querySelector('tbody');
      const headerRow = thead ? thead.querySelector('tr') : null;
      if(!thead || !tbody || !headerRow) return;

      table.dataset.columnFiltersReady = '1';
      const headers = Array.from(headerRow.children);
      const filterRow = document.createElement('tr');
      filterRow.className = 'columnFilterRow';
      const rows = Array.from(tbody.querySelectorAll('tr'));

      headers.forEach(function(th, index){
        const cell = document.createElement('th');
        const input = document.createElement('input');
        const datalist = document.createElement('datalist');
        const listId = 'column-filter-list-' + tableIndex + '-' + index;
        const values = new Set();

        rows.forEach(function(row){
          const currentCell = row.children[index];
          if(!currentCell) return;
          const raw = (currentCell.textContent || '').replace(/\s+/g, ' ').trim();
          if(!raw) return;

          values.add(raw);

          raw.split(/\s*[|•·—–-]\s*/).forEach(function(part){
            part = part.replace(/\s+/g, ' ').trim();
            if(part.length >= 2 && part.length <= 70) values.add(part);
          });
        });

        Array.from(values)
          .filter(function(value){ return value.length <= 90; })
          .sort(function(a,b){ return a.localeCompare(b, 'fr', {numeric:true, sensitivity:'base'}); })
          .slice(0, 80)
          .forEach(function(value){
            const option = document.createElement('option');
            option.value = value;
            datalist.appendChild(option);
          });

        input.type = 'search';
        input.placeholder = normalizeText(th.textContent) ? 'Filtrer ' + th.textContent.trim() : 'Filtrer';
        input.setAttribute('aria-label', 'Filtrer ' + normalizeText(th.textContent));
        input.dataset.columnIndex = String(index);
        input.setAttribute('list', listId);
        datalist.id = listId;

        cell.appendChild(input);
        cell.appendChild(datalist);
        filterRow.appendChild(cell);
      });

      thead.appendChild(filterRow);

      const globalBox = document.createElement('div');
      globalBox.className = 'filterCounter';
      globalBox.innerHTML = '<input type="search" placeholder="Recherche simple dans tout le tableau" style="width:100%;max-width:420px;padding:11px 13px;border-radius:12px;border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.08);color:inherit;font-weight:800;box-sizing:border-box"> <button type="button" style="margin-left:8px;padding:10px 14px;border:0;border-radius:12px;background:#7c5cff;color:white;font-weight:900;cursor:pointer">Reset</button><div class="filterResultText" style="margin-top:8px"></div>';
      table.parentNode.insertBefore(globalBox, table);
      const globalInput = globalBox.querySelector('input');
      const resetBtn = globalBox.querySelector('button');
      const counter = globalBox.querySelector('.filterResultText');

      function applyFilters(){
        const globalFilter = normalizeText(globalInput ? globalInput.value : '');
        const filters = Array.from(filterRow.querySelectorAll('input')).map(function(input){
          return normalizeText(input.value);
        });

        let visible = 0;
        rows.forEach(function(row){
          const cells = Array.from(row.children);
          const rowText = normalizeText(row.textContent);
          const okGlobal = !globalFilter || rowText.includes(globalFilter);
          const okColumns = filters.every(function(filter, columnIndex){
            if(!filter) return true;
            const cellText = normalizeText(cells[columnIndex] ? cells[columnIndex].textContent : '');
            return cellText.includes(filter);
          });
          const ok = okGlobal && okColumns;
          row.style.display = ok ? '' : 'none';
          if(ok) visible++;
        });

        counter.textContent = visible + ' ligne(s) affichée(s)';
      }

      filterRow.querySelectorAll('input').forEach(function(input){
        input.addEventListener('input', applyFilters);
        input.addEventListener('change', applyFilters);
      });
      if(globalInput){
        globalInput.addEventListener('input', applyFilters);
        globalInput.addEventListener('change', applyFilters);
      }
      if(resetBtn){
        resetBtn.addEventListener('click', function(){
          if(globalInput) globalInput.value = '';
          filterRow.querySelectorAll('input').forEach(function(input){ input.value = ''; });
          applyFilters();
        });
      }
      applyFilters();
    });
  }

  if(document.readyState === 'loading'){
    document.addEventListener('DOMContentLoaded', setupColumnFilters);
  }else{
    setupColumnFilters();
  }
})();
</script>

</body>
</html>