/**
 * Reputation System Manager
 * Handles reputation with genres, musicians, and eras
 */

export class ReputationManager {
  store: any;
  
  constructor(gameStore: any) {
    this.store = gameStore;
  }

  // Reputation tiers
  static TIERS = {
    HATED: -100,
    DISLIKED: -50,
    NEUTRAL: 0,
    LIKED: 50,
    ADMIRED: 100,
    LEGENDARY: 200
  };

  /**
   * Change reputation with a genre, musician, or era
   * @param {string} category - 'genres', 'musicians', or 'eras'
   * @param {string} key - Identifier (e.g., 'jazz', 'mozart', '1960s')
   * @param {number} amount - Amount to change (positive or negative)
   */
  changeReputation(category, key, amount) {
    this.store.getState().changeReputation(category, key, amount);
  }

  /**
   * Get reputation value
   * @param {string} category - 'genres', 'musicians', or 'eras'
   * @param {string} key - Identifier
   * @returns {number} - Reputation value
   */
  getReputation(category, key) {
    const reputation = this.store.getState().player.reputation[category];
    return reputation?.[key] || 0;
  }

  /**
   * Get reputation tier
   * @param {number} value - Reputation value
   * @returns {string} - Tier name
   */
  getTier(value) {
    if (value >= ReputationManager.TIERS.LEGENDARY) return 'LEGENDARY';
    if (value >= ReputationManager.TIERS.ADMIRED) return 'ADMIRED';
    if (value >= ReputationManager.TIERS.LIKED) return 'LIKED';
    if (value >= ReputationManager.TIERS.NEUTRAL) return 'NEUTRAL';
    if (value >= ReputationManager.TIERS.DISLIKED) return 'DISLIKED';
    return 'HATED';
  }

  /**
   * Check if reputation meets minimum requirement
   * @param {string} category - 'genres', 'musicians', or 'eras'
   * @param {string} key - Identifier
   * @param {number} minimum - Minimum required reputation
   * @returns {boolean} - Meets requirement
   */
  meetsRequirement(category, key, minimum) {
    const reputation = this.getReputation(category, key);
    return reputation >= minimum;
  }

  /**
   * Get all reputation entries sorted by value
   * @param {string} category - 'genres', 'musicians', or 'eras'
   * @returns {Array} - Sorted reputation entries
   */
  getAllSorted(category) {
    const reputation = this.store.getState().player.reputation[category];
    
    if (!reputation) return [];

    return Object.entries(reputation)
      .map(([key, value]) => ({
        key,
        value,
        tier: this.getTier(value)
      }))
      .sort((a, b) => (b as any).value - (a as any).value);
  }

  /**
   * Calculate reputation multiplier for rewards
   * @param {string} category - 'genres', 'musicians', or 'eras'
   * @param {string} key - Identifier
   * @returns {number} - Multiplier (0.5 to 1.5)
   */
  getRewardMultiplier(category, key) {
    const reputation = this.getReputation(category, key);
    const tier = this.getTier(reputation);

    switch (tier) {
      case 'LEGENDARY':
        return 1.5;
      case 'ADMIRED':
        return 1.3;
      case 'LIKED':
        return 1.1;
      case 'NEUTRAL':
        return 1.0;
      case 'DISLIKED':
        return 0.9;
      case 'HATED':
        return 0.7;
      default:
        return 1.0;
    }
  }

  /**
   * Get progress to next tier
   * @param {number} value - Current reputation value
   * @returns {Object} - Progress info
   */
  getProgressToNextTier(value) {
    const currentTier = this.getTier(value);
    const tiers = Object.entries(ReputationManager.TIERS).sort((a, b) => a[1] - b[1]);
    
    const currentIndex = tiers.findIndex(([name]) => name === currentTier);
    
    if (currentIndex === tiers.length - 1) {
      return {
        currentTier,
        nextTier: null,
        progress: 100,
        remaining: 0,
        maxed: true
      };
    }

    const nextTier = tiers[currentIndex + 1];
    const currentThreshold = tiers[currentIndex][1];
    const nextThreshold = nextTier[1];
    
    const progress = ((value - currentThreshold) / (nextThreshold - currentThreshold)) * 100;
    const remaining = nextThreshold - value;

    return {
      currentTier,
      nextTier: nextTier[0],
      progress: Math.min(100, Math.max(0, progress)),
      remaining: Math.max(0, remaining),
      maxed: false
    };
  }

  /**
   * Check for reputation-based unlocks
   * @param {string} category - 'genres', 'musicians', or 'eras'
   * @param {string} key - Identifier
   * @param {Array} unlockRequirements - Array of unlock definitions
   * @returns {Array} - Unlocked items
   */
  checkUnlocks(category, key, unlockRequirements) {
    const reputation = this.getReputation(category, key);
    
    return unlockRequirements.filter(unlock => 
      unlock.category === category &&
      unlock.key === key &&
      reputation >= unlock.minimumReputation
    );
  }
}

