// ─── Crafting Design System ─────────────────────────────────────────────────
// Design system functions: calculateDesignTime, capacity cost, XP, etc.

import type { EnchantmentDesign, DesignEffect, AppliedEnchantment } from './types';
import { calculateEnchantingXP } from './data/attunements';
import { ENCHANTMENT_EFFECTS, calculateEffectCapacityCost } from './data/enchantment-effects';
import { hasSpecial, SPECIAL_EFFECTS } from './effects/special-effects';
import { computeEffects } from './effects/upgrade-effects';
import { EQUIPMENT_TYPES, type EquipmentCategory } from './data/equipment';

// ─── Design Creation & Calculation ──────────────────────────────────────────

// Validate effects for a design against equipment category
export function validateDesignEffects(
  effects: DesignEffect[],
  equipmentTypeId: string,
  enchantingLevel: number
): { valid: boolean; reason?: string } {
  if (enchantingLevel < 1) {
    return { valid: false, reason: 'Requires enchanting skill level 1' };
  }

  const equipType = EQUIPMENT_TYPES[equipmentTypeId];
  if (!equipType) {
    return { valid: false, reason: 'Invalid equipment type' };
  }
  const category = equipType.category;
  if (!category) {
    return { valid: false, reason: 'Invalid equipment category' };
  }

  for (const eff of effects) {
    const effectDef = ENCHANTMENT_EFFECTS[eff.effectId];
    if (!effectDef) {
      return { valid: false, reason: `Unknown effect: ${eff.effectId}` };
    }
    if (!effectDef.allowedEquipmentCategories.includes(category)) {
      return { valid: false, reason: `Effect ${eff.effectId} not allowed on ${category}` };
    }
    if (eff.stacks > effectDef.maxStacks) {
      return { valid: false, reason: `Stacks exceed maximum for ${eff.effectId}` };
    }
  }

  return { valid: true };
}

// Create an enchantment design from validated inputs
export function createEnchantmentDesign(
  name: string,
  equipmentType: string,
  effects: DesignEffect[],
  efficiencyBonus: number = 0
): EnchantmentDesign {
  const totalCapacityUsed = calculateDesignCapacityCost(effects, efficiencyBonus);
  const designTime = calculateDesignTime(effects);

  return {
    id: `design_${Date.now()}`,
    name,
    equipmentType,
    effects,
    totalCapacityUsed,
    designTime,
    created: Date.now(),
  };
}

// ─── Capacity Cost Calculation ──────────────────────────────────────────────

export function calculateDesignCapacityCost(effects: DesignEffect[], efficiencyBonus: number = 0): number {
  return effects.reduce((total, eff) => total + calculateEffectCapacityCost(eff.effectId, eff.stacks, efficiencyBonus), 0);
}

export function calculateTotalCapacityCost(design: EnchantmentDesign): number {
  return design.totalCapacityUsed;
}

// ─── XP & Progression ───────────────────────────────────────────────────────

export function calculateEnchantingXpFromDesign(design: EnchantmentDesign): number {
  return calculateEnchantingXP(design.totalCapacityUsed);
}

export function calculateXpFromInstanceEnchantments(
  instance: { enchantments: AppliedEnchantment[] }
): number {
  let totalXp = 0;
  for (const ench of instance.enchantments) {
    const effectDef = ENCHANTMENT_EFFECTS[ench.effectId];
    const baseCost = effectDef?.baseCapacityCost || 0;
    totalXp += calculateEnchantingXP(baseCost * ench.stacks);
  }
  return totalXp;
}

// ─── Design Time Calculations ──────────────────────────────────────────────

export function calculateDesignTime(effects: DesignEffect[]): number {
  let time = 1;
  for (const eff of effects) {
    const effectDef = ENCHANTMENT_EFFECTS[eff.effectId];
    if (effectDef) {
      time += 0.5 * eff.stacks;
    }
  }
  return time;
}

export function getDesignTimeWithHaste(
  effects: DesignEffect[],
  isRepeatDesign: boolean,
  computedEffects: any
): number {
  let time = calculateDesignTime(effects);
  if (isRepeatDesign && hasSpecial(computedEffects, SPECIAL_EFFECTS.HASTY_ENCHANTER)) {
    time *= 0.75;
  }
  return time;
}

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

export interface DesignProgressUpdate {
  progress: number;
  required: number;
  isComplete: boolean;
  timeBonus: number;
}

export function calculateDesignProgress(
  currentProgress: number,
  required: number,
  computedEffects: any,
  isRepeatDesign: boolean
): DesignProgressUpdate {
  let progress = currentProgress + 0.04;
  let timeBonus = 0;

  if (isRepeatDesign && hasSpecial(computedEffects, SPECIAL_EFFECTS.HASTY_ENCHANTER)) {
    timeBonus = 0.04 * 0.25;
    progress += timeBonus;
  }

  if (hasSpecial(computedEffects, SPECIAL_EFFECTS.INSTANT_DESIGNS) && Math.random() < 0.10) {
    progress = required;
  }

  return { progress, required, isComplete: progress >= required, timeBonus };
}

export function calculateSecondDesignProgress(
  currentProgress: number,
  required: number,
  computedEffects: any,
  isRepeatDesign: boolean
): DesignProgressUpdate {
  return calculateDesignProgress(currentProgress, required, computedEffects, isRepeatDesign);
}

export function isSecondDesignSlotAvailable(
  designProgress: any,
  designProgress2: any,
  hasEnchantMastery: boolean
): boolean {
  if (!designProgress && !designProgress2) return true;
  if (!designProgress && designProgress2) return false;
  if (designProgress && !designProgress2 && hasEnchantMastery) return true;
  return false;
}

// ─── Auto-save Completed Design ────────────────────────────────────────────

export function createCompletedDesignFromProgress(
  progressData: {
    designId: string;
    name: string;
    equipmentType: string;
    effects: DesignEffect[];
    required: number;
  },
  efficiencyBonus: number = 0
): EnchantmentDesign {
  const totalCapacityCost = calculateDesignCapacityCost(progressData.effects, efficiencyBonus);
  return {
    id: progressData.designId,
    name: progressData.name,
    equipmentType: progressData.equipmentType,
    effects: progressData.effects,
    totalCapacityUsed: totalCapacityCost,
    designTime: progressData.required,
    created: Date.now(),
  };
}

// ─── Design Management ──────────────────────────────────────────────────────

export interface DesignWithCapacityInfo {
  design: EnchantmentDesign;
  fitsInEquipment: boolean;
  availableCapacity: number;
}

export function filterDesignsByEquipment(
  designs: EnchantmentDesign[],
  equipment: { instanceId: string; totalCapacity: number; usedCapacity: number } | null
): DesignWithCapacityInfo[] {
  if (!equipment) return [];
  return designs.map(design => ({
    design,
    fitsInEquipment: designFitsInEquipment(design, {
      ...equipment,
      enchantments: [],
      rarity: 'common',
      quality: 100,
      typeId: '',
      name: '',
    } as any),
    availableCapacity: equipment.totalCapacity - equipment.usedCapacity,
  }));
}

function designFitsInEquipment(design: EnchantmentDesign, instance: any): boolean {
  return (instance.usedCapacity || 0) + design.totalCapacityUsed <= instance.totalCapacity;
}
