// ─── Crafting Loot Inventory System ────────────────────────────────────────────
// Loot inventory functions

import type { LootInventory } from './types';
import type { CraftingRecipe } from './data/crafting-recipes';

// ─── Inventory Queries ──────────────────────────────────────────────────────

// Get material count
export function getMaterialCount(inventory: LootInventory, materialId: string): number {
  return inventory.materials[materialId] || 0;
}

// Check if has blueprint
export function hasBlueprint(inventory: LootInventory, blueprintId: string): boolean {
  return inventory.blueprints.includes(blueprintId);
}

// Check if has any materials
export function hasMaterials(inventory: LootInventory): boolean {
  return Object.keys(inventory.materials).length > 0;
}

// Get total number of unique materials
export function getUniqueMaterialCount(inventory: LootInventory): number {
  return Object.keys(inventory.materials).length;
}

// Get total material stacks (sum of all quantities)
export function getTotalMaterialStacks(inventory: LootInventory): number {
  return Object.values(inventory.materials || {}).reduce((sum, qty) => sum + qty, 0);
}

// ─── Inventory Modifications ────────────────────────────────────────────────

// Add materials to inventory
export function addMaterial(inventory: LootInventory, materialId: string, amount: number): LootInventory {
  const currentAmount = inventory.materials[materialId] || 0;
  return {
    ...inventory,
    materials: {
      ...inventory.materials,
      [materialId]: currentAmount + amount,
    },
  };
}

// Add multiple materials at once
export function addMaterials(
  inventory: LootInventory,
  materials: Record<string, number>
): LootInventory {
  const newMaterials = { ...inventory.materials };
  for (const [matId, amount] of Object.entries(materials)) {
    newMaterials[matId] = (newMaterials[matId] || 0) + amount;
  }
  return {
    ...inventory,
    materials: newMaterials,
  };
}

// Remove materials from inventory
export function removeMaterial(inventory: LootInventory, materialId: string, amount: number): {
  inventory: LootInventory;
  removed: number;
} {
  const currentAmount = inventory.materials[materialId] || 0;
  const removed = Math.min(amount, currentAmount);
  const remaining = Math.max(0, currentAmount - amount);

  const newMaterials = { ...inventory.materials };
  if (remaining <= 0) {
    delete newMaterials[materialId];
  } else {
    newMaterials[materialId] = remaining;
  }

  return {
    inventory: {
      ...inventory,
      materials: newMaterials,
    },
    removed,
  };
}

// Delete materials completely (admin/debug operation)
export function deleteMaterial(inventory: LootInventory, materialId: string): LootInventory {
  const newMaterials = { ...inventory.materials };
  delete newMaterials[materialId];
  return {
    ...inventory,
    materials: newMaterials,
  };
}

// Clear all materials
export function clearMaterials(inventory: LootInventory): LootInventory {
  return {
    ...inventory,
    materials: {},
  };
}

// ─── Blueprint Management ──────────────────────────────────────────────────

// Add a blueprint
export function addBlueprint(inventory: LootInventory, blueprintId: string): LootInventory {
  if (inventory.blueprints.includes(blueprintId)) {
    return inventory;
  }
  return {
    ...inventory,
    blueprints: [...inventory.blueprints, blueprintId],
  };
}

// Remove a blueprint
export function removeBlueprint(inventory: LootInventory, blueprintId: string): LootInventory {
  return {
    ...inventory,
    blueprints: inventory.blueprints.filter(id => id !== blueprintId),
  };
}

// Check and remove consumed blueprint (if single-use)
export function consumeBlueprint(inventory: LootInventory, _blueprintId: string): LootInventory {
  // Blueprints are persistent for now, but this function provides future flexibility
  return inventory;
}

// ─── Recipe Material Checks ─────────────────────────────────────────────────

// Check if specific materials are available
export function checkMaterialsAvailable(
  inventory: LootInventory,
  required: Record<string, number>
): { hasAll: boolean; missing: Record<string, number> } {
  const missing: Record<string, number> = {};
  let hasAll = true;

  for (const [matId, amount] of Object.entries(required)) {
    const available = inventory.materials[matId] || 0;
    if (available < amount) {
      missing[matId] = amount - available;
      hasAll = false;
    }
  }

  return { hasAll, missing };
}

// Deduct recipe materials
export function deductRecipeMaterials(
  inventory: LootInventory,
  recipeMaterials: Record<string, number>
): LootInventory {
  const newMaterials = { ...inventory.materials };
  for (const [matId, amount] of Object.entries(recipeMaterials)) {
    const newAmount = (newMaterials[matId] || 0) - amount;
    if (newAmount <= 0) {
      delete newMaterials[matId];
    } else {
      newMaterials[matId] = newAmount;
    }
  }
  return {
    ...inventory,
    materials: newMaterials,
  };
}

// ─── Inventory Filters & Sorting ────────────────────────────────────────────

export interface MaterialWithInfo {
  id: string;
  quantity: number;
  name: string;
  rarity: string;
}

// Get all materials with their info
export function getAllMaterials(inventory: LootInventory): MaterialWithInfo[] {
  return Object.entries(inventory.materials).map(([id, quantity]) => ({
    id,
    quantity,
    name: id, // Could be replaced with lookup from LOOT_DROPS
    rarity: 'common', // Could be replaced with lookup
  }));
}

// Filter materials by minimum quantity
export function filterMaterialsByQuantity(
  inventory: LootInventory,
  minQuantity: number
): Record<string, number> {
  const filtered: Record<string, number> = {};
  for (const [id, qty] of Object.entries(inventory.materials)) {
    if (qty >= minQuantity) {
      filtered[id] = qty;
    }
  }
  return filtered;
}

// ─── Crafting Availability ─────────────────────────────────────────────────

// Check if can craft a recipe
export function canCraftFromInventory(
  inventory: LootInventory,
  recipe: CraftingRecipe,
  currentMana: number
): { canCraft: boolean; reason?: string; missingMaterials?: Record<string, number>; missingMana?: number } {
  const { hasAll, missing } = checkMaterialsAvailable(inventory, recipe.materials);

  if (!hasAll) {
    return { canCraft: false, missingMaterials: missing };
  }

  if (currentMana < recipe.manaCost) {
    return { 
      canCraft: false, 
      missingMana: recipe.manaCost - currentMana,
      reason: 'Insufficient mana',
    };
  }

  if (!inventory.blueprints.includes(recipe.id)) {
    return { canCraft: false, reason: 'Blueprint not acquired' };
  }

  return { canCraft: true };
}

// Get all craftable recipes from inventory
export function getCraftableRecipes(
  inventory: LootInventory,
  recipes: Record<string, CraftingRecipe>,
  currentMana: number
): CraftingRecipe[] {
  const craftable: CraftingRecipe[] = [];

  for (const blueprintId of inventory.blueprints) {
    const recipe = recipes[blueprintId];
    if (!recipe) continue;

    const { canCraft } = canCraftFromInventory(inventory, recipe, currentMana);
    if (canCraft) {
      craftable.push(recipe);
    }
  }

  return craftable;
}

// ─── Inventory Statistics ──────────────────────────────────────────────────

export interface InventoryStats {
  totalUniqueMaterials: number;
  totalMaterialStacks: number;
  totalBlueprints: number;
  craftableItems: string[];
}

export function getInventoryStats(inventory: LootInventory): InventoryStats {
  const totalUniqueMaterials = Object.keys(inventory.materials).length;
  const totalMaterialStacks = Object.values(inventory.materials || {}).reduce((sum, qty) => sum + qty, 0);
  const totalBlueprints = inventory.blueprints.length;

  return {
    totalUniqueMaterials,
    totalMaterialStacks,
    totalBlueprints,
    craftableItems: [], // Would need recipes to compute
  };
}
