// Gamification Utilities für SchiriTrainer
// Speichert alle Spieldaten lokal im localStorage

const KEY_XP = "schiri_xp";
const KEY_STREAK = "schiri_streak";
const KEY_STREAK_LAST_DATE = "schiri_streak_last_date";
const KEY_ACHIEVEMENTS = "schiri_achievements";
const KEY_HIGHSCORES = "schiri_highscores";

export const ACHIEVEMENTS_LIST = [
  {
    id: "first_quiz",
    title: "Erster Pfiff 🎺",
    description: "Beende dein erstes Quiz.",
    xpBonus: 100,
  },
  {
    id: "perfect_score",
    title: "Fehlerfrei 🎯",
    description: "Erreiche 30/30 Punkte in einem Quiz.",
    xpBonus: 250,
  },
  {
    id: "turboschiri",
    title: "Turboschiri ⚡",
    description: "Beende ein Quiz (30 Fragen) in unter 2 Minuten.",
    xpBonus: 150,
  },
  {
    id: "d_master",
    title: "D-Lizenz Meister 🥉",
    description: "D-Lizenz Quiz mit mindestens 24 Punkten bestanden.",
    xpBonus: 100,
  },
  {
    id: "c_master",
    title: "C-Lizenz Meister 🥈",
    description: "C-Lizenz Quiz mit mindestens 24 Punkten bestanden.",
    xpBonus: 150,
  },
  {
    id: "repeat_master",
    title: "Wiederholungstäter 🔄",
    description: "Falsche Fragen wiederholt und alle korrekt beantwortet.",
    xpBonus: 100,
  },
];

// --- XP & LEVEL SYSTEM ---

export function getXP() {
  return parseInt(localStorage.getItem(KEY_XP)) || 0;
}

export function saveXP(xp) {
  localStorage.setItem(KEY_XP, xp);
}

export function getLevel(xp) {
  // Level = Math.floor(Math.sqrt(xp / 100)) + 1
  return Math.floor(Math.sqrt(xp / 100)) + 1;
}

export function getXPForLevel(level) {
  if (level <= 1) return 0;
  return Math.pow(level - 1, 2) * 100;
}

export function getLevelProgress(xp) {
  const currentLevel = getLevel(xp);
  const xpCurrentLevelStart = getXPForLevel(currentLevel);
  const xpNextLevelStart = getXPForLevel(currentLevel + 1);
  const needed = xpNextLevelStart - xpCurrentLevelStart;
  const earned = xp - xpCurrentLevelStart;
  const percentage = Math.min(100, Math.max(0, (earned / needed) * 100));

  return {
    currentLevel,
    nextLevel: currentLevel + 1,
    xpCurrentLevelStart,
    xpNextLevelStart,
    needed,
    earned,
    percentage: Math.round(percentage),
  };
}

export function addXP(amount) {
  const currentXP = getXP();
  const oldLevel = getLevel(currentXP);
  const newXP = currentXP + amount;
  saveXP(newXP);
  const newLevel = getLevel(newXP);

  return {
    newXP,
    oldLevel,
    newLevel,
    leveledUp: newLevel > oldLevel,
  };
}

// --- DAILY STREAK ---

export function getStreak() {
  const streak = parseInt(localStorage.getItem(KEY_STREAK)) || 0;
  const lastDateStr = localStorage.getItem(KEY_STREAK_LAST_DATE);

  if (!lastDateStr) return 0;

  const today = getTodayString();
  const yesterday = getYesterdayString();

  // Wenn der letzte Eintrag heute oder gestern war, ist der Streak noch gültig.
  // Sonst ist er abgelaufen (0).
  if (lastDateStr === today || lastDateStr === yesterday) {
    return streak;
  }
  return 0;
}

export function updateStreak() {
  const today = getTodayString();
  const yesterday = getYesterdayString();
  const lastDateStr = localStorage.getItem(KEY_STREAK_LAST_DATE);
  let streak = parseInt(localStorage.getItem(KEY_STREAK)) || 0;

  if (lastDateStr === today) {
    // Heute bereits gelernt, Streak bleibt gleich
    return streak;
  } else if (lastDateStr === yesterday) {
    // Gestern gelernt -> Streak erhöhen!
    streak += 1;
  } else {
    // Letztes Mal war länger her (oder erster Eintrag) -> Auf 1 setzen
    streak = 1;
  }

  localStorage.setItem(KEY_STREAK, streak);
  localStorage.setItem(KEY_STREAK_LAST_DATE, today);
  return streak;
}

// --- ACHIEVEMENTS ---

export function getUnlockedAchievements() {
  try {
    return JSON.parse(localStorage.getItem(KEY_ACHIEVEMENTS)) || [];
  } catch (e) {
    return [];
  }
}

export function unlockAchievement(id) {
  const unlocked = getUnlockedAchievements();
  if (unlocked.includes(id)) return null; // bereits freigeschaltet

  const ach = ACHIEVEMENTS_LIST.find((a) => a.id === id);
  if (!ach) return null;

  unlocked.push(id);
  localStorage.setItem(KEY_ACHIEVEMENTS, JSON.stringify(unlocked));

  // XP Bonus gutschreiben
  const levelUpResult = addXP(ach.xpBonus);

  return {
    achievement: ach,
    ...levelUpResult,
  };
}

// Prüft und schaltet Achievements frei basierend auf den aktuellen Quiz-Daten
export function checkAchievements(context) {
  const { score, total, timeInSeconds, mode, isRepeatRun } = context;
  const newlyUnlocked = [];

  // 1. Erster Pfiff (Erstes beendetes Quiz)
  const unlocked = getUnlockedAchievements();
  if (!unlocked.includes("first_quiz") && !isRepeatRun) {
    const res = unlockAchievement("first_quiz");
    if (res) newlyUnlocked.push(res);
  }

  // 2. Fehlerfrei (30/30)
  if (score === 30 && total === 30) {
    const res = unlockAchievement("perfect_score");
    if (res) newlyUnlocked.push(res);
  }

  // 3. Turboschiri (Beendet in unter 120s und vollzählig 30 Fragen)
  if (timeInSeconds < 120 && total === 30 && !isRepeatRun) {
    const res = unlockAchievement("turboschiri");
    if (res) newlyUnlocked.push(res);
  }

  // 4. D-Lizenz Meister
  if (mode === "d" && score >= 24 && total === 30 && !isRepeatRun) {
    const res = unlockAchievement("d_master");
    if (res) newlyUnlocked.push(res);
  }

  // 5. C-Lizenz Meister
  if (mode === "c" && score >= 24 && total === 30 && !isRepeatRun) {
    const res = unlockAchievement("c_master");
    if (res) newlyUnlocked.push(res);
  }

  // 6. Wiederholungstäter (Falsche Fragen wiederholt und alle gelöst)
  if (isRepeatRun && score === total && total > 0) {
    const res = unlockAchievement("repeat_master");
    if (res) newlyUnlocked.push(res);
  }

  return newlyUnlocked;
}

// --- HIGHSCORES ---

export function getHighscores() {
  try {
    return JSON.parse(localStorage.getItem(KEY_HIGHSCORES)) || [];
  } catch (e) {
    return [];
  }
}

export function saveHighscore(score, total, timeInSeconds, mode) {
  const scores = getHighscores();
  const percentage = (score / total) * 100;

  const newEntry = {
    score,
    total,
    percentage: Math.round(percentage * 10) / 10,
    time: timeInSeconds,
    mode: mode.toUpperCase(),
    date: new Date().toLocaleDateString("de-DE"),
  };

  scores.push(newEntry);

  // Sortiere nach Prozent absteigend, bei Gleichstand nach Zeit aufsteigend
  scores.sort((a, b) => {
    if (b.percentage !== a.percentage) {
      return b.percentage - a.percentage;
    }
    return a.time - b.time;
  });

  // Nur die Top 5 behalten
  const topScores = scores.slice(0, 5);
  localStorage.setItem(KEY_HIGHSCORES, JSON.stringify(topScores));

  // Prüfen, ob der neue Eintrag in den Top 5 gelandet ist
  const isTopScore = topScores.some(
    (s) => s.date === newEntry.date && s.score === newEntry.score && s.time === newEntry.time
  );

  return {
    highscores: topScores,
    isNewPersonalBest: isTopScore,
  };
}

// --- HELPER ---

function getTodayString() {
  const d = new Date();
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
}

function getYesterdayString() {
  const d = new Date();
  d.setDate(d.getDate() - 1);
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
}
