// ─── Extended Guardian Encounters ─────────────────────────────────────────────
// Full guardian definitions for all mana types across all spire floors.
// Guardians at floors 10-80: base types, 90-110: compound, 120+: exotic/combination.

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

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

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

export function generateGuardianName(element: string): string {
  const prefixes = GUARDIAN_PREFIXES[element] || ['Unknown'];
  const prefix = prefixes[Math.floor(Math.random() * prefixes.length)];
  const title = GUARDIAN_TITLES[Math.floor(Math.random() * GUARDIAN_TITLES.length)];
  return `${prefix} the ${title}`;
}

export function generateComboGuardianName(elements: string[]): string {
  const parts = elements.map((el) => {
    const prefixes = GUARDIAN_PREFIXES[el] || ['Unknown'];
    return prefixes[Math.floor(Math.random() * prefixes.length)];
  });
  const title = GUARDIAN_TITLES[Math.floor(Math.random() * GUARDIAN_TITLES.length)];
  return `${parts.join('-')} the ${title}`;
}

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

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

// ─── Extended Guardian Definitions ────────────────────────────────────────────

// Floors 10-80: Base mana type guardians (already in constants/guardians.ts)
// Floors 90-110: Compound mana type guardians
// Floors 120-140: Exotic mana type guardians
// Floors 150+: Combination guardians

const COMPOUND_GUARDIANS: Record<number, GuardianDef> = {
  90: {
    name: '', // Generated dynamically
    element: 'metal',
    hp: getGuardianHP(90),
    pact: 3.5,
    color: '#BDC3C7',
    armor: 0.30,
    boons: [
      { type: 'elementalDamage', value: 15, desc: '+15% Metal damage' },
      { type: 'maxMana', value: 150, desc: '+150 max mana' },
    ],
    pactCost: 60000,
    pactTime: 18,
    uniquePerk: 'Metal spells pierce 20% armor',
    power: 6000,
    effects: [{ type: 'armor_pierce', value: 0.2 }],
    signingCost: { mana: 60000, time: 18 },
    unlocksMana: ['metal'],
    damageMultiplier: 1.9,
    insightMultiplier: 1.6,
  },
  100: {
    name: '',
    element: 'sand',
    hp: getGuardianHP(100),
    pact: 3.75,
    color: '#D4AC0D',
    armor: 0.25,
    boons: [
      { type: 'elementalDamage', value: 15, desc: '+15% Sand damage' },
      { type: 'manaRegen', value: 1.5, desc: '+1.5 mana regen' },
    ],
    pactCost: 80000,
    pactTime: 20,
    uniquePerk: 'Sand spells slow enemies by 25%',
    power: 8000,
    effects: [{ type: 'slow', value: 0.25 }],
    signingCost: { mana: 80000, time: 20 },
    unlocksMana: ['sand'],
    damageMultiplier: 2.0,
    insightMultiplier: 1.7,
  },
  110: {
    name: '',
    element: 'lightning',
    hp: getGuardianHP(110),
    pact: 4.0,
    color: '#FFEB3B',
    armor: 0.22,
    boons: [
      { type: 'elementalDamage', value: 15, desc: '+15% Lightning damage' },
      { type: 'castingSpeed', value: 15, desc: '+15% casting speed' },
    ],
    pactCost: 100000,
    pactTime: 22,
    uniquePerk: 'Lightning spells chain to 2 additional targets',
    power: 10000,
    effects: [{ type: 'chain', value: 2 }],
    signingCost: { mana: 100000, time: 22 },
    unlocksMana: ['lightning'],
    damageMultiplier: 2.1,
    insightMultiplier: 1.8,
  },
};

const EXOTIC_GUARDIANS: Record<number, GuardianDef> = {
  120: {
    name: '',
    element: 'crystal',
    hp: getGuardianHP(120),
    pact: 4.5,
    color: '#85C1E9',
    armor: 0.35,
    boons: [
      { type: 'elementalDamage', value: 20, desc: '+20% Crystal damage' },
      { type: 'maxMana', value: 300, desc: '+300 max mana' },
      { type: 'manaRegen', value: 2, desc: '+2 mana regen' },
    ],
    pactCost: 150000,
    pactTime: 26,
    uniquePerk: 'Crystal spells reflect 15% damage back to attackers',
    power: 15000,
    effects: [{ type: 'reflect', value: 0.15 }],
    signingCost: { mana: 150000, time: 26 },
    unlocksMana: ['crystal'],
    damageMultiplier: 2.3,
    insightMultiplier: 1.9,
  },
  130: {
    name: '',
    element: 'stellar',
    hp: getGuardianHP(130),
    pact: 5.0,
    color: '#F0E68C',
    armor: 0.30,
    boons: [
      { type: 'elementalDamage', value: 25, desc: '+25% Stellar damage' },
      { type: 'insightGain', value: 20, desc: '+20% insight gain' },
    ],
    pactCost: 200000,
    pactTime: 30,
    uniquePerk: 'Stellar spells deal +30% damage at night',
    power: 20000,
    effects: [{ type: 'night_bonus', value: 0.3 }],
    signingCost: { mana: 200000, time: 30 },
    unlocksMana: ['stellar'],
    damageMultiplier: 2.5,
    insightMultiplier: 2.0,
  },
  140: {
    name: '',
    element: 'void',
    hp: getGuardianHP(140),
    pact: 5.5,
    color: '#4A235A',
    armor: 0.35,
    boons: [
      { type: 'elementalDamage', value: 25, desc: '+25% Void damage' },
      { type: 'rawDamage', value: 15, desc: '+15% raw damage' },
      { type: 'maxMana', value: 400, desc: '+400 max mana' },
    ],
    pactCost: 300000,
    pactTime: 34,
    uniquePerk: 'Void spells ignore 40% of all resistances',
    power: 30000,
    effects: [{ type: 'resist_ignore', value: 0.4 }],
    signingCost: { mana: 300000, time: 34 },
    unlocksMana: ['void'],
    damageMultiplier: 2.8,
    insightMultiplier: 2.2,
  },
};

// ─── Combination Guardians (Floor 150+) ───────────────────────────────────────

const COMBO_PAIRS: [string, string][] = [
  ['fire', 'water'],   // Steam
  ['fire', 'air'],     // Already lightning but different flavor
  ['water', 'earth'],  // Already sand but different flavor
  ['light', 'dark'],   // Twilight
  ['death', 'light'],  // Undeath
  ['fire', 'death'],   // Hellfire
  ['water', 'dark'],   // Abyssal
  ['air', 'light'],    // Radiant wind
  ['earth', 'death'],  // Fossil
];

export function getComboGuardian(floor: number): GuardianDef {
  const comboIndex = Math.floor((floor - 150) / 10) % COMBO_PAIRS.length;
  const [el1, el2] = COMBO_PAIRS[comboIndex];
  const hp = getGuardianHP(floor);
  const armor = Math.min(0.5, 0.25 + (floor - 150) * 0.002);

  return {
    name: '',
    element: `${el1}+${el2}`,
    hp,
    pact: 6.0 + (floor - 150) * 0.05,
    color: '#E8D5F5',
    armor,
    boons: [
      { type: 'elementalDamage', value: 10, desc: `+10% ${el1} damage` },
      { type: 'elementalDamage', value: 10, desc: `+10% ${el2} damage` },
    ],
    pactCost: Math.floor(hp * 0.5),
    pactTime: 20 + Math.floor((floor - 150) / 10),
    uniquePerk: `Dual-aspect: ${el1} and ${el2} spells gain +20% effectiveness`,
    power: Math.floor(hp * 0.5),
    effects: [
      { type: `${el1}_boost`, value: 0.2 },
      { type: `${el2}_boost`, value: 0.2 },
    ],
    signingCost: { mana: Math.floor(hp * 0.5), time: 20 + Math.floor((floor - 150) / 10) },
    unlocksMana: [el1, el2],
    damageMultiplier: 3.0 + (floor - 150) * 0.02,
    insightMultiplier: 2.5 + (floor - 150) * 0.01,
  };
}

// ─── Guardian Lookup ──────────────────────────────────────────────────────────

export function getExtendedGuardian(floor: number): GuardianDef | null {
  if (COMPOUND_GUARDIANS[floor]) {
    const g = { ...COMPOUND_GUARDIANS[floor] };
    if (!g.name) g.name = generateGuardianName(g.element);
    return g;
  }
  if (EXOTIC_GUARDIANS[floor]) {
    const g = { ...EXOTIC_GUARDIANS[floor] };
    if (!g.name) g.name = generateGuardianName(g.element);
    return g;
  }
  if (floor >= 150 && floor % 10 === 0) {
    const g = getComboGuardian(floor);
    if (!g.name) {
      const elements = g.element.split('+');
      g.name = generateComboGuardianName(elements);
    }
    return g;
  }
  return null;
}

// ─── Unified Guardian System ─────────────────────────────────────────────────
// Merges the static GUARDIANS constant (floors 10–100) with the extended
// procedural system (compound 110, exotic 120–140, combo 150+).
// For floors 90–100 the static definitions take precedence (canonical names).

import { GUARDIANS } from '../constants/guardians';

/** Get the guardian for any floor, merging static and extended systems. */
export function getGuardianForFloor(floor: number): GuardianDef | null {
  // Static GUARDIANS take precedence for floors 10–100 (canonical definitions)
  if (GUARDIANS[floor]) {
    return { ...GUARDIANS[floor] };
  }
  // Extended system for floors beyond 100 (and compound floors not in GUARDIANS)
  return getExtendedGuardian(floor);
}

/** All guardian floors — merged from static + extended. */
export function getAllGuardianFloors(): number[] {
  const staticFloors = Object.keys(GUARDIANS).map(Number);
  const extendedFloors = [110, 120, 130, 140, ...Array.from({ length: 10 }, (_, i) => 150 + i * 10)];
  const all = new Set([...staticFloors, ...extendedFloors]);
  return Array.from(all).sort((a, b) => a - b);
}

// All guardian floors (extended — kept for backwards compatibility)
export const ALL_GUARDIAN_FLOORS: number[] = [
  10, 20, 30, 40, 50, 60, 80, 90, 100,  // Original (all static floors)
  110,                                    // Compound (90,100 already in static)
  120, 130, 140,                          // Exotic
  ...Array.from({ length: 10 }, (_, i) => 150 + i * 10), // Combo
].sort((a, b) => a - b);

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