// ─── Conversion Cost Ratios ───────────────────────────────────────────────────
// All conversions produce 1 unit of destination mana.
// Costs are deducted from regen (not from the mana pool).
//
// For a destination element at distance d:
//   rawCost       = 2 * d
//   componentCost = 3 * d per component

import type { ElementRecipe } from '../types';

export interface ConversionCost {
  /** Destination element ID */
  element: string;
  /** Distance from raw mana */
  distance: number;
  /** Raw mana cost per 1 unit of destination */
  rawCost: number;
  /** Component costs: element ID → amount per 1 unit of destination */
  componentCosts: Record<string, number>;
}

function computeRawCost(distance: number): number {
  return 2 * distance;
}

function computeComponentCost(distance: number): number {
  return 3 * distance;
}

/** Build a ConversionCost for a base element (distance 1, no components) */
function baseElementCost(element: string): ConversionCost {
  return {
    element,
    distance: 1,
    rawCost: computeRawCost(1), // 2
    componentCosts: {},
  };
}

/** Build a ConversionCost for a composite element (distance 2) */
function compositeElementCost(element: string, components: string[]): ConversionCost {
  const costPerComponent = computeComponentCost(2); // 6 each
  const componentCosts: Record<string, number> = {};
  for (const c of components) {
    componentCosts[c] = (componentCosts[c] || 0) + costPerComponent;
  }
  return {
    element,
    distance: 2,
    rawCost: computeRawCost(2), // 4
    componentCosts,
  };
}

/** Build a ConversionCost for an exotic element (distance 3) */
function exoticElementCost(element: string, components: string[]): ConversionCost {
  const costPerComponent = computeComponentCost(3); // 9 each
  const componentCosts: Record<string, number> = {};
  for (const c of components) {
    componentCosts[c] = (componentCosts[c] || 0) + costPerComponent;
  }
  return {
    element,
    distance: 3,
    rawCost: computeRawCost(3), // 6
    componentCosts,
  };
}

/** Build a ConversionCost for time (distance 4) */
function timeElementCost(element: string, components: string[]): ConversionCost {
  const costPerComponent = computeComponentCost(4); // 12 each
  const componentCosts: Record<string, number> = {};
  for (const c of components) {
    componentCosts[c] = (componentCosts[c] || 0) + costPerComponent;
  }
  return {
    element,
    distance: 4,
    rawCost: computeRawCost(4), // 8
    componentCosts,
  };
}

// ─── Full Cost Table ──────────────────────────────────────────────────────────

export const CONVERSION_COSTS: Record<string, ConversionCost> = {
  // Base (distance 1)
  fire: baseElementCost('fire'),
  water: baseElementCost('water'),
  air: baseElementCost('air'),
  earth: baseElementCost('earth'),
  light: baseElementCost('light'),
  dark: baseElementCost('dark'),
  death: baseElementCost('death'),
  // Utility (distance 1)
  transference: baseElementCost('transference'),
  // Composite (distance 2)
  metal: compositeElementCost('metal', ['fire', 'earth']),
  sand: compositeElementCost('sand', ['earth', 'water']),
  lightning: compositeElementCost('lightning', ['fire', 'air']),
  frost: compositeElementCost('frost', ['air', 'water']),
  blackflame: compositeElementCost('blackflame', ['dark', 'fire']),
  radiantflames: compositeElementCost('radiantflames', ['light', 'fire']),
  miasma: compositeElementCost('miasma', ['air', 'death']),
  shadowglass: compositeElementCost('shadowglass', ['earth', 'dark']),
  // Exotic (distance 3)
  crystal: exoticElementCost('crystal', ['sand', 'sand', 'light']),
  stellar: exoticElementCost('stellar', ['plasma', 'light', 'fire']),
  void: exoticElementCost('void', ['dark', 'death']),
  soul: exoticElementCost('soul', ['light', 'dark', 'transference']),
  plasma: exoticElementCost('plasma', ['lightning', 'fire', 'transference']),
  // Time (distance 4)
  time: timeElementCost('time', ['soul', 'sand', 'transference']),
};

/** Get the conversion cost for an element. Returns null if not found. */
export function getConversionCost(element: string): ConversionCost | null {
  return CONVERSION_COSTS[element] ?? null;
}

/** Get all source types (raw + components) for a conversion */
export function getConversionSources(element: string): string[] {
  const cost = CONVERSION_COSTS[element];
  if (!cost) return [];
  return ['raw', ...Object.keys(cost.componentCosts)];
}
