// ─── Crafting Application System ────────────────────────────────────────────
// Application system functions

import type { EquipmentInstance, AppliedEnchantment, EnchantmentDesign, ApplicationProgress } from './types';
import { calculateApplicationTime, calculateApplicationManaPerHour } from './crafting-utils';
import { hasSpecial, SPECIAL_EFFECTS } from './effects/special-effects';
import type { ComputedEffects } from './effects/upgrade-effects.types';
import type { AttunementState } from './types';
import { calculateEnchantingXP, getAttunementXPForLevel, MAX_ATTUNEMENT_LEVEL } from './data/attunements';
import { ENCHANTMENT_EFFECTS } from './data/enchantment-effects';

// ─── Application Validation ─────────────────────────────────────────────────

// Check if enchantment application can start
export function canApplyEnchantment(
  instance: EquipmentInstance | undefined,
  design: EnchantmentDesign | undefined,
  currentAction: string
): { canApply: boolean; reason?: string } {
  if (!instance) {
    return { canApply: false, reason: 'Equipment instance not found' };
  }

  if (!design) {
    return { canApply: false, reason: 'Enchantment design not found' };
  }

  if (currentAction !== 'meditate') {
    return { canApply: false, reason: 'Must be in meditate state' };
  }

  if (!instance.tags?.includes('Ready for Enchantment')) {
    return { canApply: false, reason: 'Equipment must be prepared for enchanting' };
  }

  if (instance.usedCapacity + design.totalCapacityUsed > instance.totalCapacity) {
    return { canApply: false, reason: 'Not enough capacity on equipment' };
  }

  return { canApply: true };
}

// ─── Application Resource Calculation ────────────────────────────────────────

export interface ApplicationCosts {
  time: number;
  manaPerHour: number;
  manaPerTick: number;
}

export function calculateApplicationCosts(design: EnchantmentDesign): ApplicationCosts {
  const time = calculateApplicationTime(design);
  const manaPerHour = calculateApplicationManaPerHour(design);
  const manaPerTick = manaPerHour * 0.04; // HOURS_PER_TICK

  return { time, manaPerHour, manaPerTick };
}

// ─── Application Progress ───────────────────────────────────────────────────

// Initialize application progress
export function initializeApplicationProgress(
  equipmentInstanceId: string,
  designId: string,
  design: EnchantmentDesign
): ApplicationProgress {
  const costs = calculateApplicationCosts(design);

  return {
    equipmentInstanceId,
    designId,
    progress: 0,
    required: costs.time,
    manaPerHour: costs.manaPerHour,
    paused: false,
    manaSpent: 0,
  };
}

// Calculate application progress after a tick
export interface ApplicationTickResult {
  progress: number;
  manaSpent: number;
  manaConsumed: number;
  isComplete: boolean;
  triggeredFreeEnchant: boolean;
}

export function calculateApplicationTick(
  currentProgress: number,
  required: number,
  currentManaSpent: number,
  manaPerTick: number,
  computedEffects: ComputedEffects
): ApplicationTickResult {
  let progress = currentProgress + 0.04;
  let manaSpent = currentManaSpent + manaPerTick;
  let manaConsumed = manaPerTick;
  let triggeredFreeEnchant = false;

  let freeEnchantChance = 0;
  if (hasSpecial(computedEffects, SPECIAL_EFFECTS.ENCHANT_PRESERVATION)) {
    freeEnchantChance += 0.25;
  }
  if (hasSpecial(computedEffects, SPECIAL_EFFECTS.THRIFTY_ENCHANTER)) {
    freeEnchantChance += 0.10;
  }
  if (hasSpecial(computedEffects, SPECIAL_EFFECTS.OPTIMIZED_ENCHANTING)) {
    freeEnchantChance += 0.25;
  }

  if (freeEnchantChance > 0 && Math.random() < freeEnchantChance) {
    progress = required;
    manaConsumed = 0;
    manaSpent = currentManaSpent;
    triggeredFreeEnchant = true;
  }

  return {
    progress,
    manaSpent,
    manaConsumed,
    isComplete: progress >= required,
    triggeredFreeEnchant,
  };
}

// ─── Enchantment Application ────────────────────────────────────────────────

// Apply enchantments to equipment instance
export function applyEnchantments(
  instance: EquipmentInstance,
  design: EnchantmentDesign,
  computedEffects: ComputedEffects
): {
  updatedInstance: EquipmentInstance;
  xpGained: number;
  logMessage: string;
} {
  const isPureEssenceActive = hasSpecial(computedEffects, SPECIAL_EFFECTS.PURE_ESSENCE);

  const newEnchantments: AppliedEnchantment[] = design.effects.map(eff => {
    let stacks = eff.stacks;
    let actualCost = eff.capacityCost;

    const effectDef = ENCHANTMENT_EFFECTS[eff.effectId];
    if (isPureEssenceActive && effectDef && effectDef.baseCapacityCost < 100) {
      stacks = Math.ceil(stacks * 1.25);
    }

    return {
      effectId: eff.effectId,
      stacks,
      actualCost,
    };
  });

  const xpGained = calculateEnchantingXP(design.totalCapacityUsed);

  const updatedInstance: EquipmentInstance = {
    ...instance,
    enchantments: [...instance.enchantments, ...newEnchantments],
    usedCapacity: instance.usedCapacity + design.totalCapacityUsed,
  };

  return {
    updatedInstance,
    xpGained,
    logMessage: `✨ Enchantment "${design.name}" applied to ${instance.name}! (+${xpGained} Enchanter XP)`,
  };
}

// ─── Attunement XP Updates ──────────────────────────────────────────────────

export function updateEnchanterAttunement(
  attunements: Record<string, AttunementState>,
  xpGained: number
): Record<string, AttunementState> {
  if (!attunements?.enchanter?.active || xpGained <= 0) {
    return attunements;
  }

  const enchanterState = attunements.enchanter;
  let newXP = enchanterState.experience + xpGained;
  let newLevel = enchanterState.level;


  while (newLevel < MAX_ATTUNEMENT_LEVEL) {
    const xpNeeded = getAttunementXPForLevel(newLevel + 1);
    if (newXP >= xpNeeded) {
      newXP -= xpNeeded;
      newLevel++;
    } else {
      break;
    }
  }

  return {
    ...attunements,
    enchanter: {
      ...enchanterState,
      level: newLevel,
      experience: newXP,
    },
  };
}

// ─── Application Cancellation ────────────────────────────────────────────────

export function cancelApplication() {
  return { logMessage: 'Enchantment application cancelled.' };
}

export function pauseApplication() {
  return { logMessage: 'Enchantment application paused.' };
}

export function resumeApplication() {
  return { logMessage: 'Enchantment application resumed.' };
}

// ─── Progress Calculations ──────────────────────────────────────────────────

export function getApplicationManaCostForTick(manaPerHour: number): number {
  return manaPerHour * 0.04;
}

export function getApplicationRemainingTime(currentProgress: number, required: number): number {
  return Math.max(0, required - currentProgress);
}

export function getApplicationCompletionPercent(currentProgress: number, required: number): number {
  return Math.min(100, Math.floor((currentProgress / required) * 100));
}
