// ─── Discipline Effects ───────────────────────────────────────────────────────
// Computes bonuses from active disciplines and integrates with the unified effect system
//
// NEW MODEL: Conversion disciplines contribute to conversion_{element} stat bonuses.
// The unified conversion-rates.ts calculator handles rate computation and regen deduction.
// This file no longer builds a direct conversions map for the tick pipeline.

import type { DisciplineStoreState } from '../stores/discipline-slice';
import type { DisciplineState } from '../types/disciplines';
import { useDisciplineStore } from '../stores/discipline-slice';
import { ALL_DISCIPLINES } from '../data/disciplines';
import {
  calculateStatBonus,
  calculatePerkTier,
  getUnlockedPerks,
} from '../utils/discipline-math';

/**
 * Known stat keys consumed by computeAllEffects() in effects.ts.
 * Perk bonuses are routed to these keys so they flow into the unified system.
 */
const KNOWN_BONUS_STATS = new Set([
  'maxManaBonus',
  'regenBonus',
  'regenMultiplier',
  'clickManaBonus',
  'baseDamageBonus',
  'elementCapBonus',
  'elementCap_lightning',
  'meditationCapBonus',
  'pactAffinityBonus',
  'guardianBoonMultiplier',
  'enchantPower',
  'golemCapacity',
  'craftingCostReduction',
  'disciplineXpBonus',
  'clickManaMultiplier',
  'studySpeed',
  'invocationChargeRateBonus',
  'drainRateMultiplier',
  'invocationCostReduction',
  // Conversion stat bonuses (one per element)
  'conversion_fire',
  'conversion_water',
  'conversion_air',
  'conversion_earth',
  'conversion_light',
  'conversion_dark',
  'conversion_death',
  'conversion_transference',
  'conversion_metal',
  'conversion_sand',
  'conversion_lightning',
  'conversion_frost',
  'conversion_blackflame',
  'conversion_radiantflames',
  'conversion_miasma',
  'conversion_shadowglass',
  'conversion_crystal',
  'conversion_stellar',
  'conversion_void',
  'conversion_soul',
  'conversion_plasma',
  'conversion_time',
  'channelIntensity',
  'channelEfficiency',
  'roomEnchantmentAuraMagnitude',
  'roomCoverageRate',
]);

export interface DisciplineEffectsResult {
  bonuses: Record<string, number>;
  multipliers: Record<string, number>;
  specials: Set<string>;
  meditationCapBonus: number;
  /**
   * Conversion entries: for each active discipline with a conversionRate,
   * maps target mana type → { rate, sourceManaTypes }.
   * Used by the unified conversion calculator for rate computation.
   */
  conversions: Record<string, { rate: number; sourceManaTypes: string[] }>;
}

export function computeDisciplineEffects(_state?: DisciplineStoreState): DisciplineEffectsResult {
  const { disciplines } = useDisciplineStore.getState();
  const activeDiscs = Object.entries(disciplines)
    .filter(([, disc]) => disc && disc.xp > 0 && !disc.paused)
    .map(([id, disc]) => ({ id, disc, def: ALL_DISCIPLINES.find(d => d.id === id) }))
    .filter((entry): entry is { id: string; disc: DisciplineState; def: NonNullable<typeof ALL_DISCIPLINES[0]> } => !!entry.def);

  const bonuses: Record<string, number> = {};
  const multipliers: Record<string, number> = {};
  const specials = new Set<string>();
  let meditationCapBonus = 0;
  const conversions: Record<string, { rate: number; sourceManaTypes: string[] }> = {};

  function addBonus(stat: string, amount: number) {
    if (stat === 'meditationCapBonus') {
      meditationCapBonus += amount;
      return;
    }
    if (stat === 'regenMultiplier') {
      multipliers[stat] = (multipliers[stat] || 0) + amount;
      return;
    }
    bonuses[stat] = (bonuses[stat] || 0) + amount;
  }

  for (const { disc, def } of activeDiscs) {
    // Continuous stat bonus (includes conversion_{element} for regen disciplines)
    const statBonus = calculateStatBonus(def.statBonus.baseValue, disc.xp, def.scalingFactor);
    if (def.statBonus.stat) {
      addBonus(def.statBonus.stat, statBonus);
    }

    // Conversion entry — if this discipline defines conversionRate
    // This is used by the unified conversion calculator
    if (def.conversionRate && def.sourceManaTypes && def.sourceManaTypes.length > 0) {
      const scaledRate = def.conversionRate + statBonus;
      conversions[def.manaType] = {
        rate: scaledRate,
        sourceManaTypes: def.sourceManaTypes,
      };
    }

    // Perk unlocks
    const perks = getUnlockedPerks(def, disc.xp);
    for (const perk of perks) {
      if (perk.type === 'once') {
        if (perk.bonus) {
          addBonus(perk.bonus.stat, perk.bonus.amount);
        } else if (!perk.unlocksEffects) {
          specials.add(perk.id);
        }
      } else if (perk.type === 'infinite') {
        if (perk.bonus) {
          const interval = perk.value;
          const tier = calculatePerkTier(disc.xp, perk.threshold, interval);
          if (tier > 0) {
            addBonus(perk.bonus.stat, tier * perk.bonus.amount);
          }
        } else if (!perk.unlocksEffects) {
          specials.add(perk.id);
        }
      } else if (perk.type === 'capped') {
        if (perk.bonus) {
          let tier = calculatePerkTier(disc.xp, perk.threshold, perk.value);
          if (tier > 0 && perk.maxTier !== undefined) {
            tier = Math.min(tier, perk.maxTier);
          }
          if (tier > 0) {
            addBonus(perk.bonus.stat, tier * perk.bonus.amount);
          }
        } else if (!perk.unlocksEffects) {
          specials.add(perk.id);
        }
      }
    }
  }

  return { bonuses, multipliers, specials, meditationCapBonus, conversions };
}

/**
 * Compute the enchanting efficiency bonus from discipline effects.
 * The enchantPower stat from active disciplines is converted to an efficiency bonus
 * that reduces enchantment capacity costs.
 *
 * Formula: efficiencyBonus = enchantPower / 100 (capped at 0.9)
 *
 * Example: enchantPower = 15 → efficiencyBonus = 0.15 (15% cost reduction)
 */
export function getEnchantingEfficiencyBonus(): number {
  const effects = computeDisciplineEffects();
  const enchantPower = effects.bonuses.enchantPower || 0;
  return Math.min(0.9, enchantPower / 100);
}
