/**
 * StorageManager.js
 * Handles local data persistence using wx.setStorageSync/getStorageSync.
 * Manages game save data, settings, and high scores.
 */

class StorageManager {
  constructor() {
    this._prefix = 'tankwar_';
  }

  // ============================================================
  // Generic Storage
  // ============================================================

  /**
   * Save a value to local storage.
   * @param {string} key
   * @param {*} value - Will be JSON-serialized.
   */
  set(key, value) {
    try {
      wx.setStorageSync(this._prefix + key, JSON.stringify(value));
    } catch (e) {
      console.warn(`[StorageManager] Failed to save "${key}":`, e);
    }
  }

  /**
   * Load a value from local storage.
   * @param {string} key
   * @param {*} [defaultValue=null]
   * @returns {*} Parsed value, or defaultValue if not found.
   */
  get(key, defaultValue = null) {
    try {
      const raw = wx.getStorageSync(this._prefix + key);
      if (raw === '' || raw === undefined || raw === null) return defaultValue;
      return JSON.parse(raw);
    } catch (e) {
      console.warn(`[StorageManager] Failed to load "${key}":`, e);
      return defaultValue;
    }
  }

  /**
   * Remove a value from local storage.
   * @param {string} key
   */
  remove(key) {
    try {
      wx.removeStorageSync(this._prefix + key);
    } catch (e) {}
  }

  // ============================================================
  // Game Progress
  // ============================================================

  /**
   * Save game progress.
   * @param {object} progress
   * @param {number} progress.currentLevel
   * @param {number} progress.lives
   * @param {number} progress.fireLevel
   * @param {string} progress.mode
   */
  saveProgress(progress) {
    this.set('progress', progress);
  }

  /**
   * Load game progress.
   * @returns {object|null}
   */
  loadProgress() {
    return this.get('progress', null);
  }

  /**
   * Clear saved progress.
   */
  clearProgress() {
    this.remove('progress');
  }

  // ============================================================
  // High Scores
  // ============================================================

  /**
   * Get the high score for a mode.
   * @param {string} mode - Game mode.
   * @returns {number}
   */
  getHighScore(mode) {
    const scores = this.get('highscores', {});
    return scores[mode] || 0;
  }

  /**
   * Update high score if the new score is higher.
   * @param {string} mode
   * @param {number} score
   * @returns {boolean} Whether a new high score was set.
   */
  updateHighScore(mode, score) {
    const scores = this.get('highscores', {});
    if (score > (scores[mode] || 0)) {
      scores[mode] = score;
      this.set('highscores', scores);
      return true;
    }
    return false;
  }

  /**
   * Get the highest level reached.
   * @returns {number}
   */
  getHighestLevel() {
    return this.get('highest_level', 0);
  }

  /**
   * Update highest level if new level is higher.
   * @param {number} level
   */
  updateHighestLevel(level) {
    const current = this.getHighestLevel();
    if (level > current) {
      this.set('highest_level', level);
    }
  }

  // ============================================================
  // Settings
  // ============================================================

  /**
   * Save game settings.
   * @param {object} settings
   */
  saveSettings(settings) {
    this.set('settings', settings);
  }

  /**
   * Load game settings.
   * @returns {object}
   */
  loadSettings() {
    return this.get('settings', {
      soundEnabled: true,
      musicEnabled: true,
      vibrationEnabled: true,
    });
  }

  // ============================================================
  // Purchases & Unlocks
  // ============================================================

  /**
   * Record a purchase.
   * @param {string} itemId
   */
  recordPurchase(itemId) {
    const purchases = this.get('purchases', []);
    if (!purchases.includes(itemId)) {
      purchases.push(itemId);
      this.set('purchases', purchases);
    }
  }

  /**
   * Check if an item has been purchased.
   * @param {string} itemId
   * @returns {boolean}
   */
  hasPurchased(itemId) {
    const purchases = this.get('purchases', []);
    return purchases.includes(itemId);
  }

  // ============================================================
  // First-time flags
  // ============================================================

  /**
   * Check if this is the first time playing.
   * @returns {boolean}
   */
  isFirstPlay() {
    return !this.get('has_played', false);
  }

  /**
   * Mark that the player has played.
   */
  markPlayed() {
    this.set('has_played', true);
  }

  // ============================================================
  // Cloud Sync Helpers
  // ============================================================

  /**
   * Get data to sync to cloud.
   * @returns {object}
   */
  getCloudSyncData() {
    return {
      highscores: this.get('highscores', {}),
      highest_level: this.getHighestLevel(),
      purchases: this.get('purchases', []),
    };
  }

  /**
   * Restore data from cloud.
   * @param {object} cloudData
   */
  restoreFromCloud(cloudData) {
    if (cloudData.highscores) {
      const local = this.get('highscores', {});
      // Merge: keep the higher score
      for (const [mode, score] of Object.entries(cloudData.highscores)) {
        if (score > (local[mode] || 0)) {
          local[mode] = score;
        }
      }
      this.set('highscores', local);
    }

    if (cloudData.highest_level) {
      this.updateHighestLevel(cloudData.highest_level);
    }

    if (cloudData.purchases) {
      const local = this.get('purchases', []);
      const merged = [...new Set([...local, ...cloudData.purchases])];
      this.set('purchases', merged);
    }
  }
}

module.exports = StorageManager;
