/**
 * Genre Mastery System Manager
 * Handles genre XP, leveling, skill unlocks, and fusion detection
 */

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

  /**
   * XP requirements for each level (0-10)
   */
  static XP_REQUIREMENTS = [0, 100, 250, 500, 1000, 2000, 3500, 5500, 8000, 12000];

  /**
   * Award XP for a genre and check for level ups
   * @param {string} genreId - Genre identifier
   * @param {number} xp - Amount of XP to award
   * @returns {Object} - Level up info { leveledUp: boolean, newLevel: number }
   */
  awardXP(genreId, xp) {
    const currentMastery = this.store.getState().player.genreMastery[genreId] || {
      level: 1,
      xp: 0,
      skills: []
    };

    const oldLevel = currentMastery.level;
    this.store.getState().gainGenreXP(genreId, xp);
    
    const newMastery = this.store.getState().player.genreMastery[genreId];
    const newLevel = newMastery.level;

    return {
      leveledUp: newLevel > oldLevel,
      newLevel,
      oldLevel,
      currentXP: newMastery.xp,
      xpToNextLevel: newLevel < 10 ? GenreManager.XP_REQUIREMENTS[newLevel] - newMastery.xp : 0
    };
  }

  /**
   * Get multiplier bonus based on genre level
   * @param {string} genreId - Genre identifier
   * @returns {number} - Multiplier (1.0 = no bonus, 1.2 = +20%)
   */
  getGenreMultiplier(genreId) {
    const mastery = this.store.getState().player.genreMastery[genreId];
    
    if (!mastery) return 1.0;

    const { level } = mastery;
    
    // Level 5: +20%, Level 10: +50%
    if (level >= 10) return 1.5;
    if (level >= 5) return 1.2;
    if (level >= 3) return 1.1;
    
    return 1.0;
  }

  /**
   * Check if a genre skill can be unlocked
   * @param {string} genreId - Genre identifier
   * @param {Object} skill - Skill definition
   * @returns {boolean} - Can unlock
   */
  canUnlockSkill(genreId, skill) {
    const mastery = this.store.getState().player.genreMastery[genreId];
    
    if (!mastery) return false;
    if (mastery.level < skill.level) return false;
    if (mastery.skills.includes(skill.id)) return false; // Already unlocked
    
    // Check prerequisite
    if (skill.prerequisite && !mastery.skills.includes(skill.prerequisite)) {
      return false;
    }

    return true;
  }

  /**
   * Unlock a skill for a genre
   * @param {string} genreId - Genre identifier
   * @param {string} skillId - Skill identifier
   */
  unlockSkill(genreId, skillId) {
    this.store.getState().unlockGenreSkill(genreId, skillId);
  }

  /**
   * Check if a fusion can be created based on genre levels
   * @param {Object} fusion - Fusion recipe
   * @returns {boolean} - Can create fusion
   */
  canCreateFusion(fusion) {
    const { player } = this.store.getState();
    
    for (const ingredient of fusion.ingredients) {
      const mastery = player.genreMastery[ingredient.genre];
      if (!mastery || mastery.level < ingredient.minLevel) {
        return false;
      }
    }

    return true;
  }

  /**
   * Get all available fusions based on current genre masteries
   * @param {Array} allFusions - All fusion recipes
   * @returns {Array} - Available fusions
   */
  getAvailableFusions(allFusions) {
    return allFusions.filter(fusion => this.canCreateFusion(fusion));
  }

  /**
   * Get progress toward next level for a genre
   * @param {string} genreId - Genre identifier
   * @returns {Object} - Progress info
   */
  getLevelProgress(genreId) {
    const mastery = this.store.getState().player.genreMastery[genreId] || {
      level: 1,
      xp: 0,
      skills: []
    };

    if (mastery.level >= 10) {
      return {
        level: 10,
        currentXP: mastery.xp,
        requiredXP: GenreManager.XP_REQUIREMENTS[9],
        progress: 100,
        maxLevel: true
      };
    }

    const currentLevelXP = GenreManager.XP_REQUIREMENTS[mastery.level - 1];
    const nextLevelXP = GenreManager.XP_REQUIREMENTS[mastery.level];
    const progressXP = mastery.xp - currentLevelXP;
    const requiredXP = nextLevelXP - currentLevelXP;
    const progress = (progressXP / requiredXP) * 100;

    return {
      level: mastery.level,
      currentXP: mastery.xp,
      requiredXP: nextLevelXP,
      progress: Math.min(100, Math.max(0, progress)),
      xpToNextLevel: requiredXP - progressXP,
      maxLevel: false
    };
  }

  /**
   * Get all genre masteries sorted by level
   * @returns {Array} - Sorted genre masteries
   */
  getAllMasteriesSorted() {
    const { genreMastery } = this.store.getState().player;
    
    return Object.entries(genreMastery)
      .map(([genre, data]) => ({
        genre,
        ...(data as any)
      }))
      .sort((a, b) => b.level - a.level || b.xp - a.xp);
  }
}

