// ─── Attunement Definitions ─────────────────────────────────────────────────────
// Attunements are class-like abilities tied to body locations
// Each provides unique capabilities, primary mana types, and skill access

import type { AttunementDef, AttunementSlot } from '../types';

// Attunement slot display names
export const ATTUNEMENT_SLOT_NAMES: Record<AttunementSlot, string> = {
  rightHand: 'Right Hand',
  leftHand: 'Left Hand',
  head: 'Head',
  back: 'Back',
  chest: 'Chest',
  leftLeg: 'Left Leg',
  rightLeg: 'Right Leg',
};

// All attunement definitions
export const ATTUNEMENTS_DEF: Record<string, AttunementDef> = {
  // ─── Enchanter (Right Hand) ─────────────────────────────────────────────────
  // Unlocks the enchanting system - applying magical effects to equipment
  // Primary mana: Transference (used to move/apply enchantments)
  enchanter: {
    id: 'enchanter',
    name: 'Enchanter',
    desc: 'Channel transference mana through your right hand to apply magical enchantments to equipment. The art of enchanting allows you to imbue items with spell effects, stat bonuses, and special properties.',
    slot: 'rightHand',
    icon: '✨',
    color: '#1ABC9C', // Teal (transference color)
    primaryManaType: 'transference',
    rawManaRegen: 0.5,
    conversionRate: 0.2, // Converts 0.2 raw mana to transference per hour
    unlocked: true, // Starting attunement
    capabilities: ['enchanting'],
    skillCategories: ['enchant', 'effectResearch'],
  },

  // ─── Invoker (Chest/Heart) ───────────────────────────────────────────────────
  // Enables forming pacts with spire guardians
  // No primary mana - instead gains mana types from each pact signed
  invoker: {
    id: 'invoker',
    name: 'Invoker',
    desc: 'Open your heart to the guardians of the spire. Form pacts with defeated guardians to gain their elemental affinity and access to their unique powers. Each pact grants access to a new mana type.',
    slot: 'chest',
    icon: '💜',
    color: '#9B59B6', // Purple
    primaryManaType: undefined, // Invoker has no primary - gains from pacts
    rawManaRegen: 0.3,
    conversionRate: 0, // No automatic conversion - mana comes from pacts
    unlocked: false, // Unlocked through gameplay
    unlockCondition: 'Defeat your first guardian and choose the path of the Invoker',
    capabilities: ['pacts', 'guardianPowers', 'elementalMastery'],
    skillCategories: ['invocation', 'pact'],
  },

  // ─── Fabricator (Left Hand) ──────────────────────────────────────────────────
  // Crafts earth golems and earthen gear
  // Primary mana: Earth
  // Later with fire mana -> metal mana, can craft metallic gear and golems
  fabricator: {
    id: 'fabricator',
    name: 'Fabricator',
    desc: 'Shape earth and metal through your left hand to craft golems and equipment. Start with earthen constructs, and unlock metalworking when you gain fire mana to create metal mana.',
    slot: 'leftHand',
    icon: '⚒️',
    color: '#F4A261', // Earth color
    primaryManaType: 'earth',
    rawManaRegen: 0.4,
    conversionRate: 0.25, // Converts 0.25 raw mana to earth per hour
    unlocked: false, // Unlocked through gameplay
    unlockCondition: 'Prove your worth as a crafter',
    capabilities: ['golemCrafting', 'gearCrafting', 'earthShaping'],
    skillCategories: ['fabrication', 'golemancy'],
  },
};

// Helper function to get attunement by slot
export function getAttunementBySlot(slot: AttunementSlot): AttunementDef | undefined {
  return Object.values(ATTUNEMENTS_DEF).find(a => a.slot === slot);
}

// Helper function to get all unlocked attunements for a player
export function getUnlockedAttunements(attunements: Record<string, { active: boolean; level: number; experience: number }>): AttunementDef[] {
  return Object.entries(attunements)
    .filter(([id, state]) => state.active)
    .map(([id]) => ATTUNEMENTS_DEF[id])
    .filter(Boolean);
}

// Helper function to calculate total raw mana regen from attunements (with level scaling)
export function getTotalAttunementRegen(attunements: Record<string, { active: boolean; level: number; experience: number }>): number {
  return Object.entries(attunements)
    .filter(([, state]) => state.active)
    .reduce((total, [id, state]) => {
      const def = ATTUNEMENTS_DEF[id];
      if (!def) return total;
      // Exponential scaling: base * (1.5 ^ (level - 1))
      const levelMult = Math.pow(1.5, (state.level || 1) - 1);
      return total + def.rawManaRegen * levelMult;
    }, 0);
}

// Helper function to calculate total conversion drain from all active attunements (per hour)
export function getTotalAttunementConversionDrain(attunements: Record<string, { active: boolean; level: number; experience: number }>): number {
  return Object.entries(attunements)
    .filter(([, state]) => state.active)
    .reduce((total, [id, state]) => {
      const def = ATTUNEMENTS_DEF[id];
      if (!def || def.conversionRate <= 0) return total;
      // Use the same level scaling as getAttunementConversionRate
      const scaledRate = getAttunementConversionRate(id, state.level || 1);
      return total + scaledRate;
    }, 0);
}

// Get conversion rate with level scaling
export function getAttunementConversionRate(attunementId: string, level: number): number {
  const def = ATTUNEMENTS_DEF[attunementId];
  if (!def || def.conversionRate <= 0) return 0;
  // Exponential scaling: base * (1.5 ^ (level - 1))
  return def.conversionRate * Math.pow(1.5, (level || 1) - 1);
}

// XP required for attunement level
export function getAttunementXPForLevel(level: number): number {
  // New scaling: 
  // Level 2: 1000 XP
  // Level 3: 2500 XP
  // Level 4: 5000 XP
  // Level 5: 10000 XP
  // etc. (each level requires 2x the previous, starting from 1000)
  if (level <= 1) return 0;
  if (level === 2) return 1000;
  // For level 3+: 1000 * 2.5^(level-2), but rounded nicely
  return Math.floor(1000 * Math.pow(2, level - 2) * (level >= 3 ? 1.25 : 1));
}

// Calculate XP gained from enchanting based on capacity used
export function calculateEnchantingXP(capacityUsed: number): number {
  // 1 XP per 10 capacity used, floored, minimum 1
  return Math.max(1, Math.floor(capacityUsed / 10));
}

// Max attunement level
export const MAX_ATTUNEMENT_LEVEL = 10;

// Helper function to get mana types from active attunements and pacts
export function getAttunementManaTypes(
  attunements: Record<string, { active: boolean; level: number; experience: number }>,
  signedPacts: number[]
): string[] {
  const manaTypes: string[] = [];
  
  // Add primary mana types from active attunements
  Object.entries(attunements)
    .filter(([, state]) => state.active)
    .forEach(([id]) => {
      const def = ATTUNEMENTS_DEF[id];
      if (def?.primaryManaType) {
        manaTypes.push(def.primaryManaType);
      }
    });
  
  // Invoker gains mana types from signed pacts
  if (attunements.invoker?.active && signedPacts.length > 0) {
    // Import GUARDIANS would be circular, so this is handled in the store
    // For now, just mark that invoker provides pact-based mana
    manaTypes.push('pactElements');
  }
  
  return [...new Set(manaTypes)]; // Remove duplicates
}

// Get skill categories available to player based on active attunements
export function getAvailableSkillCategories(
  attunements: Record<string, { active: boolean; level: number; experience: number }>
): string[] {
  const categories = new Set<string>();
  
  // Always available categories
  categories.add('mana');
  categories.add('study');
  categories.add('research');
  // categories.add('ascension'); // removed: banned mechanic
  
  // Add categories from active attunements
  Object.entries(attunements)
    .filter(([, state]) => state.active)
    .forEach(([id]) => {
      const def = ATTUNEMENTS_DEF[id];
      if (def?.skillCategories) {
        def.skillCategories.forEach(cat => categories.add(cat));
      }
    });
  
  return Array.from(categories);
}
