// ─── Guardian Encounters ─────────────────────────────────────────────────────────
// Procedural guardian generation and unified lookup.
//
// Guardian progression (9 tiers):
//   Tier 1:  Base Elements           (static,  floors 10–80,   guardian-data.ts)
//   Tier 2:  Composite Elements      (static,  floors 90–160,  guardian-data.ts)
//   Tier 3:  Exotic Elements         (static,  floors 170–240, guardian-data.ts)
//   Tier 4:  Dual Element Pairs      (dynamic, floors 250–280, this file)
//   Tier 5:  Dual Comp+Components    (dynamic, floors 290–330, this file)
//   Tier 6:  Exotic+Components       (dynamic, floors 340–380, this file)
//   Tier 7:  Exotic+Comp+Components  (dynamic, floors 390–430, this file)
//   Tier 8:  Full Fusion             (dynamic, floors 440+,    this file)
//
// All lookups go through getGuardianForFloor() which merges static + procedural.

import type { GuardianDef, GuardianBoon } from '../types';
import { STATIC_GUARDIANS } from './guardian-data';
import { resolveMultiUnlockChain } from '../utils/guardian-utils';

// ─── Name Generation ────────────────────────────────────────────────────────────

const GUARDIAN_PREFIXES: Record<string, string[]> = {
  fire: ['Ignis', 'Pyra', 'Sol', 'Vulcan', 'Ember'],
  water: ['Aqua', 'Marina', 'Thal', 'Pelag', 'Coral'],
  air: ['Ventus', 'Zephyr', 'Aero', 'Nimbus', 'Gale'],
  earth: ['Terra', 'Petra', 'Mont', 'Gaia', 'Ore'],
  light: ['Lux', 'Solaris', 'Radi', 'Lumin', 'Aur'],
  dark: ['Umbra', 'Noct', 'Teneb', 'Ereb', 'Nyx'],
  death: ['Mors', 'Necro', 'Than', 'Mort', 'Skull'],
  transference: ['Link', 'Arcana', 'Vinc', 'Bind', 'Chain'],
  metal: ['Ferr', 'Chroma', 'Steel', 'Arg', 'Ore'],
  sand: ['Arena', 'Dune', 'Siroc', 'Erg', 'Sah'],
  lightning: ['Volt', 'Fulg', 'Electr', 'Spark', 'Storm'],
  crystal: ['Prism', 'Gemma', 'Crystal', 'Shard', 'Facet'],
  stellar: ['Astro', 'Stella', 'Nova', 'Cosmo', 'Lumin'],
  void: ['Void', 'Abyss', 'Null', 'Nihil', 'Obliv'],
  frost: ['Glac', 'Cryo', 'Bore', 'Rime', 'Frost'],
  blackflame: ['Umbra', 'Cinder', 'Ash', 'Smoke', 'Ember'],
  radiantflames: ['Sol', 'Radi', 'Aura', 'Glow', 'Flare'],
  miasma: ['Mias', 'Tox', 'Plague', 'Virus', 'Blight'],
  shadowglass: ['Shade', 'Obsid', 'Night', 'Gloom', 'Void'],
  soul: ['Psy', 'Anima', 'Spirit', 'Ghost', 'Wraith'],
  time: ['Chron', 'Temp', 'Epoch', 'Aeon', 'Hour'],
  plasma: ['Ion', 'Plasm', 'Spark', 'Arc', 'Flux'],
};

const GUARDIAN_TITLES: string[] = [
  'Warden', 'Keeper', 'Lord', 'Titan', 'Sovereign',
  'Guardian', 'Sentinel', 'Champion', 'Overlord', 'Archon',
];

export function generateGuardianName(elements: string[], floor: number = 0): string {
  const parts = elements.map((el, i) => {
    const prefixes = GUARDIAN_PREFIXES[el] || ['Unknown'];
    return prefixes[(floor + i) % prefixes.length];
  });
  const title = GUARDIAN_TITLES[Math.floor(floor / 10) % GUARDIAN_TITLES.length];
  return `${parts.join('-')} the ${title}`;
}

/** @deprecated Use generateGuardianName(elements[], floor) instead. Kept for backward compat. */
export function generateGuardianNameSingle(element: string, floor: number = 0): string {
  return generateGuardianName([element], floor);
}

// ─── Guardian HP Scaling ───────────────────────────────────────────────────────

export function getGuardianHP(floor: number): number {
  const base = 5000;
  const exponent = 1.1 + (floor / 200);
  return Math.floor(base * Math.pow(floor / 10, exponent));
}

// ─── Tier Helpers ───────────────────────────────────────────────────────────────

const COMPOSITE_ELEMENTS = ['metal', 'sand', 'lightning', 'frost', 'blackflame', 'radiantflames', 'miasma', 'shadowglass'];
const EXOTIC_ELEMENTS = ['crystal', 'stellar', 'void', 'soul', 'time', 'plasma'];

/** Generate boon elements (max 3) */
function makeBoons(elements: string[], floor: number): GuardianBoon[] {
  return elements.slice(0, 3).map((el) => ({
    type: 'elementalDamage' as const,
    value: 10 + Math.floor(floor / 20) * 5,
    desc: `+${10 + Math.floor(floor / 20) * 5}% ${el} damage`,
  }));
}

function getTier(floor: number): number {
  if (floor >= 440) return 8;
  if (floor >= 390) return 7;
  if (floor >= 340) return 6;
  if (floor >= 290) return 5;
  if (floor >= 250) return 4;
  return 0; // Static tiers
}

// ═══════════════════════════════════════════════════════════════════════════════
// TIER 4: Dual Element Pairs (Floors 250–280)
// ═══════════════════════════════════════════════════════════════════════════════

const DUAL_PAIRS: [string, string][] = [
  ['fire', 'water'],
  ['fire', 'air'],
  ['water', 'earth'],
  ['light', 'dark'],
  ['death', 'light'],
  ['fire', 'death'],
  ['water', 'dark'],
  ['air', 'light'],
  ['earth', 'death'],
];

function getTier4Guardian(floor: number): GuardianDef {
  const idx = Math.floor((floor - 250) / 10) % DUAL_PAIRS.length;
  const [el1, el2] = DUAL_PAIRS[idx];
  const elements = [el1, el2];
  const hpVal = getGuardianHP(floor);
  const armor = Math.min(0.5, 0.30 + (floor - 250) * 0.003);

  return {
    name: '',
    element: elements,
    hp: hpVal,
    pact: 7.5 + (floor - 250) * 0.05,
    color: blendColors(el1, el2),
    armor,
    boons: makeBoons(elements, floor),
    pactCost: Math.floor(hpVal * 0.3 + hpVal * armor * 0.5),
    pactTime: 20 + Math.floor((floor - 250) / 10),
    uniquePerk: `Dual-aspect: ${el1} and ${el2} spells gain +20% effectiveness`,
    power: Math.floor(hpVal * 0.5),
    effects: [
      { type: `${el1}_boost`, value: 0.15 },
      { type: `${el2}_boost`, value: 0.15 },
    ],
    signingCost: {
      mana: Math.floor(hpVal * 0.3),
      time: 20 + Math.floor((floor - 250) / 10),
    },
    unlocksMana: resolveMultiUnlockChain(elements),
    damageMultiplier: 3.5 + (floor - 250) * 0.02,
    insightMultiplier: 3.0 + (floor - 250) * 0.01,
  };
}

// ═══════════════════════════════════════════════════════════════════════════════
// TIER 5: Dual Composite + Components (Floors 290–330)
// Pairs of composites with all their base components.
// ═══════════════════════════════════════════════════════════════════════════════

const DUAL_COMP_PAIRS: [string, string][] = [
  ['metal', 'sand'],
  ['metal', 'lightning'],
  ['sand', 'lightning'],
  ['frost', 'blackflame'],
  ['radiantflames', 'miasma'],
  ['shadowglass', 'frost'],
];

function getTier5Guardian(floor: number): GuardianDef {
  const idx = Math.floor((floor - 290) / 10) % DUAL_COMP_PAIRS.length;
  const [comp1, comp2] = DUAL_COMP_PAIRS[idx];
  const elements = resolveMultiUnlockChain([comp1, comp2]);
  const hpVal = getGuardianHP(floor);
  const armor = Math.min(0.55, 0.35 + (floor - 290) * 0.003);

  return {
    name: '',
    element: elements,
    hp: hpVal,
    pact: 9.0 + (floor - 290) * 0.05,
    color: blendColors(comp1, comp2),
    armor,
    boons: makeBoons([comp1, comp2], floor),
    pactCost: Math.floor(hpVal * 0.3 + hpVal * armor * 0.5),
    pactTime: 24 + Math.floor((floor - 290) / 10),
    uniquePerk: `Fusion twin-aspect: ${comp1} and ${comp2} spells gain +25% effectiveness`,
    power: Math.floor(hpVal * 0.55),
    effects: [
      { type: 'armor_pierce', value: 0.2 },
      { type: 'chain', value: 1 },
    ],
    signingCost: {
      mana: Math.floor(hpVal * 0.35),
      time: 24 + Math.floor((floor - 290) / 10),
    },
    unlocksMana: resolveMultiUnlockChain(elements),
    damageMultiplier: 4.0 + (floor - 290) * 0.02,
    insightMultiplier: 3.5 + (floor - 290) * 0.01,
  };
}

// ═══════════════════════════════════════════════════════════════════════════════
// TIER 6: Exotic + Components (Floors 340–380)
// Each exotic element paired with all its component base elements.
// ═══════════════════════════════════════════════════════════════════════════════

function getTier6Guardian(floor: number): GuardianDef {
  const exoticIdx = Math.floor((floor - 340) / 10) % EXOTIC_ELEMENTS.length;
  const exoticEl = EXOTIC_ELEMENTS[exoticIdx];
  const chain = resolveMultiUnlockChain([exoticEl]);
  const hpVal = getGuardianHP(floor);
  const armor = Math.min(0.6, 0.40 + (floor - 340) * 0.003);

  return {
    name: '',
    element: chain,
    hp: hpVal,
    pact: 10.5 + (floor - 340) * 0.05,
    color: '#B8A9C9',
    armor,
    boons: [makeBoons([exoticEl], floor)[0]],
    pactCost: Math.floor(hpVal * 0.35 + hpVal * armor * 0.5),
    pactTime: 28 + Math.floor((floor - 340) / 10),
    uniquePerk: `Exotic resonance: ${exoticEl} spells gain +30% effectiveness`,
    power: Math.floor(hpVal * 0.6),
    effects: [
      { type: 'resist_ignore', value: 0.2 },
      { type: 'reflect', value: 0.1 },
    ],
    signingCost: {
      mana: Math.floor(hpVal * 0.35),
      time: 28 + Math.floor((floor - 340) / 10),
    },
    unlocksMana: chain,
    damageMultiplier: 4.5 + (floor - 340) * 0.02,
    insightMultiplier: 4.0 + (floor - 340) * 0.01,
  };
}

// ═══════════════════════════════════════════════════════════════════════════════
// TIER 7: Exotic + Composite + Components (Floors 390–430)
// One exotic + one composite + all base elements.
// ═══════════════════════════════════════════════════════════════════════════════

function getTier7Guardian(floor: number): GuardianDef {
  const exoticIdx = Math.floor((floor - 390) / 10) % EXOTIC_ELEMENTS.length;
  const compIdx = Math.floor((floor - 390) / 10) % COMPOSITE_ELEMENTS.length;
  const exoticEl = EXOTIC_ELEMENTS[exoticIdx];
  const compEl = COMPOSITE_ELEMENTS[compIdx];
  const elements = resolveMultiUnlockChain([exoticEl, compEl]);
  const hpVal = getGuardianHP(floor);
  const armor = Math.min(0.65, 0.45 + (floor - 390) * 0.003);

  return {
    name: '',
    element: elements,
    hp: hpVal,
    pact: 12.0 + (floor - 390) * 0.05,
    color: '#9B72AA',
    armor,
    boons: makeBoons([exoticEl, compEl], floor),
    pactCost: Math.floor(hpVal * 0.4 + hpVal * armor * 0.5),
    pactTime: 32 + Math.floor((floor - 390) / 10),
    uniquePerk: `Primordial fusion: ${exoticEl} and ${compEl} spells gain +25% effectiveness`,
    power: Math.floor(hpVal * 0.65),
    effects: [
      { type: 'resist_ignore', value: 0.25 },
      { type: 'armor_pierce', value: 0.2 },
      { type: 'chain', value: 1 },
    ],
    signingCost: {
      mana: Math.floor(hpVal * 0.4),
      time: 32 + Math.floor((floor - 390) / 10),
    },
    unlocksMana: elements,
    damageMultiplier: 5.0 + (floor - 390) * 0.02,
    insightMultiplier: 4.5 + (floor - 390) * 0.01,
  };
}

// ═══════════════════════════════════════════════════════════════════════════════
// TIER 8: Full Fusion — 1 Exotic + 2 Composite + All Components (Floors 440+)
// ═══════════════════════════════════════════════════════════════════════════════

function getTier8Guardian(floor: number): GuardianDef {
  const exoticIdx = (Math.floor((floor - 440) / 10)) % EXOTIC_ELEMENTS.length;
  const exoticEl = EXOTIC_ELEMENTS[exoticIdx];
  // Pick 2 different composites
  const comp1 = COMPOSITE_ELEMENTS[Math.floor((floor - 440) / 10) % COMPOSITE_ELEMENTS.length];
  const comp2 = COMPOSITE_ELEMENTS[(Math.floor((floor - 440) / 10) + 1) % COMPOSITE_ELEMENTS.length];
  const elements = resolveMultiUnlockChain([exoticEl, comp1, comp2]);
  const hpVal = getGuardianHP(floor);
  const armor = Math.min(0.7, 0.50 + (floor - 440) * 0.002);

  return {
    name: '',
    element: elements,
    hp: hpVal,
    pact: 14.0 + (floor - 440) * 0.05,
    color: '#7B5E9A',
    armor,
    boons: makeBoons([exoticEl, comp1, comp2], floor),
    pactCost: Math.floor(hpVal * 0.45 + hpVal * armor * 0.5),
    pactTime: 36 + Math.floor((floor - 440) / 10),
    uniquePerk: `Cosmic convergence: All exotic, composite, and base spells gain +15% effectiveness`,
    power: Math.floor(hpVal * 0.7),
    effects: [
      { type: 'resist_ignore', value: 0.3 },
      { type: 'armor_pierce', value: 0.25 },
      { type: 'chain', value: 2 },
      { type: 'reflect', value: 0.1 },
    ],
    signingCost: {
      mana: Math.floor(hpVal * 0.45),
      time: 36 + Math.floor((floor - 440) / 10),
    },
    unlocksMana: elements,
    damageMultiplier: 5.5 + (floor - 440) * 0.02,
    insightMultiplier: 5.0 + (floor - 440) * 0.01,
  };
}

// ─── Blending Colors for Dual/Multi-Element Guardians ──────────────────────────

const ELEMENT_COLORS: Record<string, string> = {
  fire: '#FF6B35', water: '#4ECDC4', air: '#00D4FF', earth: '#F4A261',
  light: '#FFD700', dark: '#9B59B6', death: '#778CA3', transference: '#1ABC9C',
  metal: '#BDC3C7', sand: '#D4AC0D', lightning: '#FFEB3B',
  crystal: '#85C1E9', stellar: '#F0E68C', void: '#4A235A',
  frost: '#A8D8EA', blackflame: '#8B2500', radiantflames: '#FFAA33',
  miasma: '#6B8E23', shadowglass: '#2C2C54',
  soul: '#E8D5F5', time: '#C5B99A', plasma: '#FF6B9D',
};

function blendColors(el1: string, el2: string): string {
  const c1 = ELEMENT_COLORS[el1] || '#888888';
  const c2 = ELEMENT_COLORS[el2] || '#888888';
  try {
    const r = Math.floor((parseInt(c1.slice(1, 3), 16) + parseInt(c2.slice(1, 3), 16)) / 2);
    const g = Math.floor((parseInt(c1.slice(3, 5), 16) + parseInt(c2.slice(3, 5), 16)) / 2);
    const b = Math.floor((parseInt(c1.slice(5, 7), 16) + parseInt(c2.slice(5, 7), 16)) / 2);
    return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
  } catch {
    return '#888888';
  }
}

// ─── Procedural Guardian Generator ─────────────────────────────────────────────

function getProceduralGuardian(floor: number): GuardianDef | null {
  if (floor < 250 || floor % 10 !== 0) return null;

  const tier = getTier(floor);
  let g: GuardianDef;

  switch (tier) {
    case 4: g = getTier4Guardian(floor); break;
    case 5: g = getTier5Guardian(floor); break;
    case 6: g = getTier6Guardian(floor); break;
    case 7: g = getTier7Guardian(floor); break;
    case 8: g = getTier8Guardian(floor); break;
    default: return null;
  }

  if (!g.name) {
    g.name = generateGuardianName(g.element, floor);
  }
  return g;
}

// ─── Unified Guardian System ────────────────────────────────────────────────────

/** Get the guardian for any floor. Returns null if no guardian at that floor. */
export function getGuardianForFloor(floor: number): GuardianDef | null {
  if (STATIC_GUARDIANS[floor]) {
    const g = { ...STATIC_GUARDIANS[floor] };
    if (!g.name) g.name = generateGuardianName(g.element, floor);
    return g;
  }
  return getProceduralGuardian(floor);
}

/** All guardian floors — dynamically computed. */
export function getAllGuardianFloors(): number[] {
  // Static floors from guardian-data.ts
  const staticFloors = Object.keys(STATIC_GUARDIANS).map(Number);
  // Procedural floors: every 10th floor from 250 to 490
  const proceduralFloors: number[] = [];
  for (let f = 250; f <= 490; f += 10) {
    proceduralFloors.push(f);
  }
  const all = new Set([...staticFloors, ...proceduralFloors]);
  return Array.from(all).sort((a, b) => a - b);
}

/** Check if a floor is a guardian floor (every 10th floor with a defined guardian). */
export function isGuardianFloor(floor: number): boolean {
  return floor % 10 === 0 && floor >= 10;
}
