/**
 * Regra de pontuação — **portada** do `scoring.service.ts` do NestJS.
 *
 * É cópia deliberada, não reescrita: a regra já era função pura lá, com 14 casos
 * de teste do plano `PR-1`. Reescrever "melhor" na migração seria trocar regra
 * verificada por regra nova sem que ninguém pedisse — e a única forma de descobrir
 * teria sido no primeiro bolão real.
 *
 * Nenhuma dependência de Firebase aqui de propósito: pontuação é a regra mais
 * cara de errar do produto, e ela tem de ser testável sem emulador, sem rede e sem
 * banco.
 */

export interface TabelaDePontos {
  pointsExact: number;
  pointsWinnerDiff: number;
  pointsWinner: number;
}

export type FaixaDePonto =
  | 'PLACAR_EXATO'
  | 'VENCEDOR_E_SALDO'
  | 'SO_VENCEDOR'
  | 'ERROU';

/**
 * Faixa de acerto de um palpite contra o placar oficial.
 *
 * "Saldo de gols" aqui é a diferença **do jogo**, não o acumulado do campeonato.
 */
export function faixa(
  palpiteCasa: number,
  palpiteFora: number,
  oficialCasa: number,
  oficialFora: number,
): FaixaDePonto {
  if (palpiteCasa === oficialCasa && palpiteFora === oficialFora) {
    return 'PLACAR_EXATO';
  }

  const sinal = (a: number, b: number) => Math.sign(a - b);
  const acertouVencedor =
    sinal(palpiteCasa, palpiteFora) === sinal(oficialCasa, oficialFora);
  if (!acertouVencedor) return 'ERROU';

  const saldoIgual = palpiteCasa - palpiteFora === oficialCasa - oficialFora;
  // Empate acertado sem o placar exato cai aqui: o saldo é 0 nos dois lados, mas o
  // placar difere. **Confirmado pelo dono em 07/08:** vale a faixa de "só
  // vencedor" — palpitar 1x1 num jogo que termina 4x4 dá 3 pontos, não 5.
  if (saldoIgual && oficialCasa !== oficialFora) return 'VENCEDOR_E_SALDO';

  return 'SO_VENCEDOR';
}

/** Valor da faixa **na tabela do bolão**, nunca em constante (CC-2 BE-3). */
export function pontos(faixa: FaixaDePonto, tabela: TabelaDePontos): number {
  switch (faixa) {
    case 'PLACAR_EXATO':
      return tabela.pointsExact;
    case 'VENCEDOR_E_SALDO':
      return tabela.pointsWinnerDiff;
    case 'SO_VENCEDOR':
      return tabela.pointsWinner;
    case 'ERROU':
      return 0;
  }
}
