import { PointsCalculation, POINTS } from '../types';

interface Score {
  home: number;
  away: number;
}

/**
 * Berechnet die Punkte für einen Tipp.
 *
 * Punkteregeln:
 * - Exaktes Ergebnis:   3 Punkte
 * - Richtige Tendenz:   1 Punkt (Sieg/Unentschieden/Niederlage korrekt)
 * - Falsche Tendenz:    0 Punkte
 *
 * @param tip - Der abgegebene Tipp
 * @param actual - Das tatsächliche Ergebnis
 */
export const calculatePoints = (
  tip: Score,
  actual: Score
): PointsCalculation => {
  // Exaktes Ergebnis
  if (tip.home === actual.home && tip.away === actual.away) {
    return { result: 'exact', points: POINTS.EXACT };
  }

  // Tendenz prüfen (Sieg Heim / Unentschieden / Sieg Auswärts)
  const tipTendency = getTendency(tip.home, tip.away);
  const actualTendency = getTendency(actual.home, actual.away);

  if (tipTendency === actualTendency) {
    return { result: 'tendency', points: POINTS.TENDENCY };
  }

  return { result: 'wrong', points: POINTS.WRONG };
};

type Tendency = 'home' | 'draw' | 'away';

const getTendency = (home: number, away: number): Tendency => {
  if (home > away) return 'home';
  if (home < away) return 'away';
  return 'draw';
};

/**
 * Berechnet Punkte für die gesamte Tipp-History eines Users.
 * Nützlich für Statistiken.
 */
export const calculateUserStats = (
  tips: Array<{
    tipHome: number;
    tipAway: number;
    actualHome: number | null;
    actualAway: number | null;
    points: number | null;
  }>
) => {
  const evaluated = tips.filter(
    (t) => t.actualHome !== null && t.actualAway !== null
  );

  const exactCount = evaluated.filter((t) => t.points === POINTS.EXACT).length;
  const tendencyCount = evaluated.filter(
    (t) => t.points === POINTS.TENDENCY
  ).length;
  const wrongCount = evaluated.filter((t) => t.points === POINTS.WRONG).length;
  const totalPoints = evaluated.reduce((sum, t) => sum + (t.points ?? 0), 0);

  const accuracy =
    evaluated.length > 0
      ? Math.round(
          ((exactCount + tendencyCount) / evaluated.length) * 100
        )
      : 0;

  return {
    totalPoints,
    exactCount,
    tendencyCount,
    wrongCount,
    accuracy,
    evaluatedCount: evaluated.length,
    pendingCount: tips.length - evaluated.length,
  };
};
