// ─── Enemy Generator ───────────────────────────────────────────────────────────
// Enemy generation with modifiers: mage, shield, armored, swarm, agile
// Modifiers are combinable (e.g., armored + swarm)

import type { EnemyState } from '../types';
import { getFloorMaxHP, getFloorElement } from './floor-utils';
import { getEnemyName } from './enemy-utils';

// ─── Enemy Modifier Types ─────────────────────────────────────────────────────

export type EnemyModifier = 'mage' | 'shield' | 'armored' | 'swarm' | 'agile';

export interface GeneratedEnemy extends EnemyState {
  modifiers: EnemyModifier[];
}

// ─── Modifier Configuration ───────────────────────────────────────────────────

const MODIFIER_CONFIG = {
  mage: {
    barrierPerFloor: 0.003,
    maxBarrier: 0.4,
    barrierRechargeRate: 0.05, // Recharges 5% of max HP per tick
  },
  shield: {
    shieldAmount: 0.15, // 15% of max HP as one-time flat shield pool (spec §5.1)
  },
  armored: {
    armorPerFloor: 0.003,
    maxArmor: 0.45,
    minArmor: 0.1,
  },
  swarm: {
    minEnemies: 3,
    maxEnemies: 7,
    hpMultiplier: 0.35,
    armorPerFloor: 0.002,
  },
  agile: {
    baseDodge: 0,
    dodgePerFloor: 0.003,
    maxDodge: 0.55,
  },
};

// ─── Modifier Selection ───────────────────────────────────────────────────────

export function selectModifiers(floor: number): EnemyModifier[] {
  const modifiers: EnemyModifier[] = [];

  // Mage: appears floor 15+, more common at higher floors
  if (floor >= 15 && Math.random() < Math.min(0.3, (floor - 15) * 0.01)) {
    modifiers.push('mage');
  }

  // Shield: appears floor 10+, moderate chance
  if (floor >= 10 && Math.random() < Math.min(0.25, (floor - 10) * 0.008)) {
    modifiers.push('shield');
  }

  // Armored: appears floor 5+, common
  if (floor >= 5 && Math.random() < Math.min(0.4, (floor - 5) * 0.012)) {
    modifiers.push('armored');
  }

  // Swarm: appears floor 8+, moderate chance
  if (floor >= 8 && Math.random() < 0.15) {
    modifiers.push('swarm');
  }

  // Agile: appears floor 12+, moderate chance
  if (floor >= 12 && Math.random() < Math.min(0.25, (floor - 12) * 0.008)) {
    modifiers.push('agile');
  }

  // Limit to 2 modifiers max for balance
  if (modifiers.length > 2) {
    // Shuffle and take first 2
    for (let i = modifiers.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [modifiers[i], modifiers[j]] = [modifiers[j], modifiers[i]];
    }
    return modifiers.slice(0, 2);
  }

  return modifiers;
}

// ─── Enemy Generation ─────────────────────────────────────────────────────────

export function generateEnemy(floor: number, modifiers?: EnemyModifier[]): GeneratedEnemy {
  const element = getFloorElement(floor);
  const baseHP = getFloorMaxHP(floor);
  const activeModifiers = modifiers || selectModifiers(floor);

  let hp = baseHP;
  let armor = 0;
  let dodgeChance = 0;
  let barrier = 0;
  let name = getEnemyName(element, floor);

  // Apply modifier effects
  if (activeModifiers.includes('armored')) {
    const progress = Math.min(1, floor / 100);
    armor = Math.min(
      MODIFIER_CONFIG.armored.maxArmor,
      MODIFIER_CONFIG.armored.minArmor + (MODIFIER_CONFIG.armored.maxArmor - MODIFIER_CONFIG.armored.minArmor) * progress
    );
    name = `Armored ${name}`;
  }

  if (activeModifiers.includes('agile')) {
    dodgeChance = Math.min(
      MODIFIER_CONFIG.agile.maxDodge,
      MODIFIER_CONFIG.agile.baseDodge + floor * MODIFIER_CONFIG.agile.dodgePerFloor
    );
    name = `Agile ${name}`;
  }

  if (activeModifiers.includes('mage')) {
    barrier = Math.min(
      MODIFIER_CONFIG.mage.maxBarrier,
      floor * MODIFIER_CONFIG.mage.barrierPerFloor
    );
    name = `Mage ${name}`;
  }

  if (activeModifiers.includes('shield')) {
    name = `${name} (Shielded)`;
  }

  const shieldPool = activeModifiers.includes('shield') ? hp * MODIFIER_CONFIG.shield.shieldAmount : 0;

  return {
    id: 'enemy',
    name,
    hp,
    maxHP: hp,
    armor,
    dodgeChance,
    barrier,
    shieldPool,
    element,
    activeEffects: [],
    effectiveArmor: armor,
    modifiers: activeModifiers,
  };
}

// ─── Swarm Generation ─────────────────────────────────────────────────────────

export function generateSwarm(floor: number, modifiers?: EnemyModifier[]): GeneratedEnemy[] {
  const element = getFloorElement(floor);
  const baseHP = getFloorMaxHP(floor);
  const activeModifiers = modifiers || [];
  const numEnemies = MODIFIER_CONFIG.swarm.minEnemies +
    Math.floor(Math.random() * (MODIFIER_CONFIG.swarm.maxEnemies - MODIFIER_CONFIG.swarm.minEnemies + 1));

  const enemies: GeneratedEnemy[] = [];

  for (let i = 0; i < numEnemies; i++) {
    const enemyName = getEnemyName(element, floor);
    const hp = Math.floor(baseHP * MODIFIER_CONFIG.swarm.hpMultiplier);
    const armor = activeModifiers.includes('armored')
      ? Math.min(0.3, floor * MODIFIER_CONFIG.swarm.armorPerFloor)
      : 0;

    enemies.push({
      id: `swarm_${i}`,
      name: `${enemyName} ${i + 1}`,
      hp,
      maxHP: hp,
      armor,
      dodgeChance: activeModifiers.includes('agile')
        ? Math.min(0.35, 0.15 + floor * 0.003)
        : 0,
      barrier: 0,
      element,
      activeEffects: [],
      effectiveArmor: armor,
      modifiers: activeModifiers,
    });
  }

  return enemies;
}

// ─── Modifier Display ─────────────────────────────────────────────────────────

export function getModifierDisplay(modifier: EnemyModifier): { label: string; icon: string; color: string; desc: string } {
  const displays: Record<EnemyModifier, { label: string; icon: string; color: string; desc: string }> = {
    mage: {
      label: 'Mage',
      icon: '🔮',
      color: '#8B5CF6',
      desc: 'Casts barriers that re-apply occasionally',
    },
    shield: {
      label: 'Shielded',
      icon: '🛡️',
      color: '#3B82F6',
      desc: 'Has a one-time shield that must be broken',
    },
    armored: {
      label: 'Armored',
      icon: '⛰️',
      color: '#F59E0B',
      desc: 'Reduces incoming damage',
    },
    swarm: {
      label: 'Swarm',
      icon: '🐝',
      color: '#EF4444',
      desc: 'Multiple weaker enemies',
    },
    agile: {
      label: 'Agile',
      icon: '💨',
      color: '#10B981',
      desc: 'Can dodge attacks',
    },
  };
  return displays[modifier];
}

export function getModifierDescription(modifiers: EnemyModifier[]): string {
  if (modifiers.length === 0) return 'Standard enemy';
  return modifiers.map((m) => getModifierDisplay(m).label).join(', ');
}
