// ─── 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+: Procedural              (dynamic, floors 250+,    guardian-procedural.ts)
//
// All lookups go through getGuardianForFloor() which merges static + procedural.

import type { GuardianDef } from '../types';
import { STATIC_GUARDIANS } from './guardian-data';
import { getProceduralGuardian } from './guardian-procedural';

// ─── 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 {
  // Use a cycle offset to ensure the same elements at different 100-floor ranges
  // produce different names. Without this, floors 170/370/570 etc. with the same
  // element(s) would produce identical names because both prefix and title cycle.
  const cycleOffset = Math.floor(floor / 50);
  const parts = elements.map((el, i) => {
    const prefixes = GUARDIAN_PREFIXES[el] || ['Unknown'];
    return prefixes[(floor + i + cycleOffset) % prefixes.length];
  });
  const titleIndex = Math.floor(floor / 10) % GUARDIAN_TITLES.length;
  // For multi-element names, also shift the title to reduce collision chance
  const title = GUARDIAN_TITLES[(titleIndex + (elements.length > 1 ? cycleOffset : 0)) % 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));
}

// ─── Color Blending ─────────────────────────────────────────────────────────────

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',
};

export 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';
  }
}

// ─── 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[] {
  const staticFloors = Object.keys(STATIC_GUARDIANS).map(Number);
  const proceduralFloors: number[] = [];
  for (let f = 250; f <= 490; f += 10) proceduralFloors.push(f);
  return Array.from(new Set([...staticFloors, ...proceduralFloors])).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;
}
