// groups.js — standings computed from groups.json + results.json and the 12
// group tables. Only matches with status "finished" count toward standings
// (live scores are ignored until full-time). computeStandings() and
// isGroupFinished() are reused by bracket.js to resolve the Round of 32.

import { getData, flagSrc } from './app.js';
import { t } from './i18n.js';
import { getFavorites } from './storage.js';

// Tiebreak order per complement spec §2: points, goal difference, goals for.
// Team id alphabetical as a final stable fallback.
export function computeStandings() {
  const { groups, matches, resultByMatchId } = getData();
  const tables = {};
  for (const [letter, teamIds] of Object.entries(groups)) {
    tables[letter] = new Map(teamIds.map((id) => [id, {
      teamId: id, played: 0, won: 0, drawn: 0, lost: 0, gf: 0, ga: 0, gd: 0, points: 0,
    }]));
  }

  for (const match of matches) {
    if (!match.phase.startsWith('Group ')) continue;
    const result = resultByMatchId.get(match.id);
    if (result?.status !== 'finished') continue;
    const rows = tables[match.phase.slice(6)];
    applyResult(rows.get(match.homeTeam), result.homeScore, result.awayScore);
    applyResult(rows.get(match.awayTeam), result.awayScore, result.homeScore);
  }

  const standings = {};
  for (const [letter, rows] of Object.entries(tables)) {
    standings[letter] = [...rows.values()].sort((a, b) =>
      b.points - a.points || b.gd - a.gd || b.gf - a.gf || a.teamId.localeCompare(b.teamId));
  }
  return standings;
}

function applyResult(row, scored, conceded) {
  row.played += 1;
  row.gf += scored;
  row.ga += conceded;
  row.gd = row.gf - row.ga;
  if (scored > conceded) { row.won += 1; row.points += 3; }
  else if (scored === conceded) { row.drawn += 1; row.points += 1; }
  else { row.lost += 1; }
}

export function isGroupFinished(letter) {
  const { matches, resultByMatchId } = getData();
  return matches
    .filter((m) => m.phase === `Group ${letter}`)
    .every((m) => resultByMatchId.get(m.id)?.status === 'finished');
}

function allGroupsFinished() {
  return Object.keys(getData().groups).every(isGroupFinished);
}

// Best third-placed teams: each group's 3rd-placed row, ranked across all 12
// groups by the same criteria as within a group (points → GD → GF → id). The top
// 8 advance to the Round of 32. This only ranks the thirds for display — the
// slot→group allocation itself lives in bracket-config.json (filled from FIFA's
// official combination table), not derived here.
export function computeThirdPlaceRanking() {
  const standings = computeStandings();
  return Object.entries(standings)
    .map(([letter, rows]) => ({ ...rows[2], group: letter }))
    .sort((a, b) =>
      b.points - a.points || b.gd - a.gd || b.gf - a.gf || a.teamId.localeCompare(b.teamId))
    .map((row, i) => ({ ...row, rank: i + 1, qualified: i < 8 }));
}

// -------------------------------------------------------------- render

export function initGroups() {
  render();
  document.addEventListener('langchange', render);
  document.addEventListener('favchange', render);
  document.addEventListener('datachange', render); // new results → recompute standings
}

function render() {
  const standings = computeStandings();
  document.getElementById('groups-root').innerHTML = `
    <p class="standings-legend">
      <span class="legend-item"><span class="legend-dot qualified"></span>${t('standings.legendTop2')}</span>
      <span class="legend-item"><span class="legend-dot third"></span>${t('standings.legendThird')}</span>
    </p>
    <div class="groups-grid">
      ${Object.entries(standings).map(([letter, rows]) => groupCardHTML(letter, rows)).join('')}
    </div>
    ${allGroupsFinished() ? thirdPlaceSectionHTML() : ''}
    ${legendHTML()}`;
}

// Best-third ranking table — rendered only once all 12 groups are finished (the
// ranking is meaningless mid-stage). Reuses the .standings-table styling, the
// header tooltips and the favorite-row highlight from the group cards.
function thirdPlaceSectionHTML() {
  const ranking = computeThirdPlaceRanking();
  const headers = ['played', 'won', 'drawn', 'lost', 'gf', 'ga', 'gd', 'pts']
    .map((key) => {
      const tip = t(`tip.${key}`);
      const goals = key === 'gf' || key === 'ga' ? 'col-goals ' : '';
      return `<th class="${goals}has-tip" scope="col" data-tip="${tip}" aria-label="${t(`standings.${key}`)} — ${tip}">${t(`standings.${key}`)}</th>`;
    })
    .join('');

  return `
    <section class="third-place glass" aria-labelledby="third-place-title">
      <header class="group-card-header">
        <h3 id="third-place-title">${t('standings.thirdTitle')}</h3>
      </header>
      <p class="third-place-note">${t('standings.thirdNote')}</p>
      <p class="standings-legend third-place-keys">
        <span class="legend-item"><span class="legend-dot third"></span>${t('standings.qualified')}</span>
        <span class="legend-item"><span class="legend-dot out"></span>${t('standings.eliminated')}</span>
      </p>
      <div class="third-place-scroll">
        <table class="standings-table third-place-table">
          <thead>
            <tr>
              <th scope="col">#</th>
              <th class="col-team" scope="col">${t('standings.team')}</th>
              <th class="col-group has-tip" scope="col" data-tip="${t('standings.group')}" aria-label="${t('standings.group')}">${t('standings.group')}</th>
              ${headers}
              <th class="col-status" scope="col" aria-label="${t('standings.qualified')}"></th>
            </tr>
          </thead>
          <tbody>${ranking.map(thirdRowHTML).join('')}</tbody>
        </table>
      </div>
    </section>`;
}

function thirdRowHTML(entry, index) {
  const team = getData().teamById.get(entry.teamId);
  const fav = getFavorites().includes(team.id);
  const cls = [
    entry.qualified ? 'row-third' : 'row-out',
    index === 8 ? 'cut' : '',
    fav ? 'fav-row' : '',
  ].filter(Boolean).join(' ');
  const status = entry.qualified
    ? `<span class="qual-yes" aria-label="${t('standings.qualified')}">✓</span>`
    : `<span class="qual-no" aria-label="${t('standings.eliminated')}">—</span>`;
  return `
    <tr class="${cls}">
      <td>${entry.rank}</td>
      <td class="col-team">
        <img class="flag" src="${flagSrc(team)}" alt="" width="22" height="15" loading="lazy">
        <span>${team.name}</span>
        <button class="fav-btn ${fav ? 'active' : ''}" data-fav="${team.id}"
                aria-pressed="${fav}" aria-label="${t('fav.toggle')} ${team.name}">${fav ? '★' : '☆'}</button>
      </td>
      <td class="col-group">${entry.group}</td>
      <td>${entry.played}</td>
      <td>${entry.won}</td>
      <td>${entry.drawn}</td>
      <td>${entry.lost}</td>
      <td class="col-goals">${entry.gf}</td>
      <td class="col-goals">${entry.ga}</td>
      <td>${entry.gd > 0 ? '+' : ''}${entry.gd}</td>
      <td class="col-pts">${entry.points}</td>
      <td class="col-status">${status}</td>
    </tr>`;
}

// Abbreviation key shown only on small screens (where the header hover tooltips
// don't fire); reuses the shared .stats-legend styling.
function legendHTML() {
  const pairs = ['played', 'won', 'drawn', 'lost', 'gf', 'ga', 'gd', 'pts']
    .map((key) => `<span class="legend-pair"><b>${t(`standings.${key}`)}</b> = ${t(`tip.${key}`)}</span>`)
    .join('');
  return `<p class="stats-legend">${pairs}</p>`;
}

function groupCardHTML(letter, rows) {
  const finished = isGroupFinished(letter);
  const headers = ['played', 'won', 'drawn', 'lost', 'gf', 'ga', 'gd', 'pts']
    .map((key) => {
      const tip = t(`tip.${key}`);
      const goals = key === 'gf' || key === 'ga' ? 'col-goals ' : '';
      return `<th class="${goals}has-tip" scope="col" data-tip="${tip}" aria-label="${t(`standings.${key}`)} — ${tip}">${t(`standings.${key}`)}</th>`;
    })
    .join('');

  return `
    <section class="group-card glass" aria-labelledby="group-title-${letter}">
      <header class="group-card-header">
        <h3 id="group-title-${letter}">${t('phase.group')} ${letter}</h3>
        ${finished ? '' : `<span class="group-progress">${t('standings.inProgress')}</span>`}
      </header>
      <table class="standings-table">
        <thead>
          <tr><th scope="col">#</th><th class="col-team" scope="col">${t('standings.team')}</th>${headers}</tr>
        </thead>
        <tbody>${rows.map(standingRowHTML).join('')}</tbody>
      </table>
    </section>`;
}

function standingRowHTML(row, index) {
  const team = getData().teamById.get(row.teamId);
  const fav = getFavorites().includes(team.id);
  const rankClass = [
    index < 2 ? 'row-qualified' : index === 2 ? 'row-third' : '',
    fav ? 'fav-row' : '',
  ].filter(Boolean).join(' ');
  return `
    <tr class="${rankClass}">
      <td>${index + 1}</td>
      <td class="col-team">
        <img class="flag" src="${flagSrc(team)}" alt="" width="22" height="15" loading="lazy">
        <span>${team.name}</span>
        <button class="fav-btn ${fav ? 'active' : ''}" data-fav="${team.id}"
                aria-pressed="${fav}" aria-label="${t('fav.toggle')} ${team.name}">${fav ? '★' : '☆'}</button>
      </td>
      <td>${row.played}</td>
      <td>${row.won}</td>
      <td>${row.drawn}</td>
      <td>${row.lost}</td>
      <td class="col-goals">${row.gf}</td>
      <td class="col-goals">${row.ga}</td>
      <td>${row.gd > 0 ? '+' : ''}${row.gd}</td>
      <td class="col-pts">${row.points}</td>
    </tr>`;
}
