const KEY = 'conduit.pipedream.v1';

const defaults = () => ({
  settings: {
    master: 0.75,
    music: 0.45,
    sfx: 0.85,
    shake: true,
    particles: true,
    ghostPath: true,
    rotatePieces: true,
    undo: true,
    difficulty: 'normal',
    palette: 'aqua',
    reducedMotion: false,
  },
  scores: [],
  best: {},
  unlocked: 1,
  seenTutorial: false,
  player: 'ACE',
});

function loadRaw() {
  try {
    const raw = localStorage.getItem(KEY);
    if (!raw) return defaults();
    const parsed = JSON.parse(raw);
    const base = defaults();
    return {
      ...base,
      ...parsed,
      settings: { ...base.settings, ...(parsed.settings || {}) },
      scores: Array.isArray(parsed.scores) ? parsed.scores : [],
      best: parsed.best && typeof parsed.best === 'object' ? parsed.best : {},
    };
  } catch {
    return defaults();
  }
}

let cache = loadRaw();

function save() {
  try {
    localStorage.setItem(KEY, JSON.stringify(cache));
  } catch {
    /* sandbox / private mode */
  }
}

export const Storage = {
  get() {
    return cache;
  },
  settings() {
    return cache.settings;
  },
  setSettings(partial) {
    cache.settings = { ...cache.settings, ...partial };
    save();
  },
  player() {
    return cache.player || 'ACE';
  },
  setPlayer(name) {
    cache.player = String(name || 'ACE').slice(0, 12).toUpperCase();
    save();
    return cache.player;
  },
  seenTutorial() {
    return !!cache.seenTutorial;
  },
  markTutorial() {
    cache.seenTutorial = true;
    save();
  },
  unlocked() {
    return cache.unlocked | 0 || 1;
  },
  unlock(level) {
    if (level > cache.unlocked) {
      cache.unlocked = level;
      save();
    }
  },
  recordScore(entry) {
    const row = {
      name: entry.name || cache.player || 'ACE',
      score: entry.score | 0,
      mode: entry.mode || 'campaign',
      level: entry.level | 0,
      difficulty: entry.difficulty || cache.settings.difficulty,
      date: Date.now(),
    };
    cache.scores.push(row);
    cache.scores.sort((a, b) => b.score - a.score);
    cache.scores = cache.scores.slice(0, 20);
    const key = `${row.mode}:${row.level}:${row.difficulty}`;
    const prev = cache.best[key] | 0;
    if (row.score > prev) cache.best[key] = row.score;
    save();
    return { row, best: cache.best[key], isBest: row.score >= (prev || row.score) && row.score > prev };
  },
  top(n = 10, mode = null) {
    let list = cache.scores.slice();
    if (mode) list = list.filter((s) => s.mode === mode);
    return list.slice(0, n);
  },
  bestFor(mode, level, difficulty) {
    return cache.best[`${mode}:${level}:${difficulty}`] | 0;
  },
  resetScores() {
    cache.scores = [];
    cache.best = {};
    save();
  },
};
