// ─── Mana & Regen Utilities ──────────────────────────────────────────────────

import type { AttunementState } from '../types';
import type { ComputedEffects } from '../effects/upgrade-effects.types';
import { HOURS_PER_TICK } from '../constants';
import { getTotalAttunementRegen } from '../data/attunements';

export interface DisciplineBonuses {
  bonuses: Record<string, number>;
  multipliers: Record<string, number>;
}

// ─── Mana Params ────────────────────────────────────────────────────────────

export interface ManaComputeParams {
  prestigeUpgrades?: Record<string, number>;
}

export interface RegenComputeParams extends ManaComputeParams {
  attunements: Record<string, AttunementState>;
}

export interface EffectiveRegenParams extends RegenComputeParams {
  rawMana: number;
  incursionStrength: number;
}

// ─── Max Mana ────────────────────────────────────────────────────────────────

export function computeMaxMana(
  state: Partial<ManaComputeParams>,
  effects?: ComputedEffects,
  discipline?: DisciplineBonuses,
): number {
  const pu = state.prestigeUpgrades || {};
  const base =
    100 +
    (pu.manaWell || 0) * 500 +
    (discipline?.bonuses?.maxManaBonus || 0);

  if (effects) {
    return Math.floor((base + effects.maxManaBonus) * effects.maxManaMultiplier);
  }
  return base;
}

// ─── Regen ────────────────────────────────────────────────────────────────────

export function computeRegen(
  state: Pick<RegenComputeParams, 'prestigeUpgrades' | 'attunements'>,
  effects?: ComputedEffects,
  discipline?: DisciplineBonuses,
): number {
  const pu = state.prestigeUpgrades || {};
  const temporalBonus = 1 + (pu.temporalEcho || 0) * 0.1;
  const base =
    2 +
    ((pu || {}).manaFlow || 0) * 0.5;

  let regen = base * temporalBonus;

  // Add attunement raw mana regen
  const attunementRegen = getTotalAttunementRegen(state.attunements || {});
  regen += attunementRegen;

  // Apply discipline regen bonus
  if (discipline?.bonuses?.regenBonus) {
    regen += discipline.bonuses.regenBonus;
  }

  // Apply upgrade effects if provided
  if (effects) {
    regen = (regen + effects.regenBonus + effects.permanentRegenBonus) * effects.regenMultiplier;
  }

  return regen;
}

// ─── Effective Regen for Display ──────────────────────────────────────────────

export function computeEffectiveRegenForDisplay(
  state: Pick<RegenComputeParams, 'prestigeUpgrades' | 'attunements'>,
  effects?: ComputedEffects,
  discipline?: DisciplineBonuses,
): { rawRegen: number; conversionDrain: number; effectiveRegen: number } {
  const rawRegen = computeRegen(state, effects, discipline);
  return { rawRegen, conversionDrain: 0, effectiveRegen: rawRegen };
}

// ─── Effective Regen (dynamic) ────────────────────────────────────────────────

export function computeEffectiveRegen(
  state: Pick<RegenComputeParams, 'prestigeUpgrades' | 'attunements'> & { rawMana: number; incursionStrength: number },
  effects?: ComputedEffects,
  discipline?: DisciplineBonuses,
): number {
  let regen = computeRegen(state, effects, discipline);
  const incursionStrength = state.incursionStrength || 0;
  regen *= (1 - incursionStrength);
  return regen;
}

// ─── Click Mana ───────────────────────────────────────────────────────────────

export function computeClickMana(
  discipline?: DisciplineBonuses,
): number {
  const discClickBonus = discipline?.bonuses?.clickManaBonus || 0;
  return 1 + discClickBonus;
}

// ─── Meditation Bonus ─────────────────────────────────────────────────────────

export function getMeditationBonus(
  meditateTicks: number,
  meditationEfficiency: number = 1,
  disciplineMeditationCap: number = 0,
): number {
  const hours = meditateTicks * HOURS_PER_TICK;

  // Continuous ramp: 1 + (hours / 8) * 4, capped at 2.5 + disciplineMeditationCap
  const maxMultiplier = 2.5 + disciplineMeditationCap;
  const bonus = Math.min(1 + (hours / 8) * 4, maxMultiplier);

  // Apply meditation efficiency from upgrades
  return bonus * meditationEfficiency;
}
