// ─── Spire Utility Functions ───────────────────────────────────────────────────
// Spire-specific utility functions for room generation, enemy stat scaling, etc.

import type { RoomType, FloorState, EnemyState } from '../types';
import { GUARDIANS, FLOOR_ELEM_CYCLE, PUZZLE_ROOMS } from '../constants';
import { getFloorMaxHP, getFloorElement } from './floor-utils';
import { getEnemyName } from './enemy-utils';
import { isGuardianFloor, getExtendedGuardian } from '../data/guardian-encounters';

// ─── Spire Room Configuration ─────────────────────────────────────────────────

export const SPIRE_CONFIG = {
  minRoomsPerFloor: 5,
  maxRoomsPerFloor: 15,
  guardianRooms: 1,
  puzzleRoomChance: 0.12,
  rareRoomChance: 0.05,
  recoveryRoomChance: 0.4,
  libraryRoomChance: 0.3,
  treasureRoomChance: 0.3,
};

// ─── Room Count ───────────────────────────────────────────────────────────────

export function getRoomsForFloor(floor: number): number {
  if (isGuardianFloor(floor)) return SPIRE_CONFIG.guardianRooms;
  const base = SPIRE_CONFIG.minRoomsPerFloor;
  const range = SPIRE_CONFIG.maxRoomsPerFloor - SPIRE_CONFIG.minRoomsPerFloor;
  // Slight increase in rooms at higher floors
  const floorBonus = Math.min(range, Math.floor(floor / 20));
  const randomVariation = Math.floor(Math.random() * 3);
  return base + floorBonus + randomVariation;
}

// ─── Spire Room Types ─────────────────────────────────────────────────────────

export type SpireRoomType = RoomType | 'recovery' | 'library' | 'treasure';

// ─── Room Generation ──────────────────────────────────────────────────────────

export function generateSpireRoomType(floor: number, roomIndex: number, totalRooms: number): SpireRoomType {
  // Last room on guardian floors is always guardian
  if (isGuardianFloor(floor) && roomIndex === totalRooms - 1) {
    return 'guardian';
  }

  // First room on a floor is never a special room (always combat)
  if (roomIndex === 0) {
    return generateCombatRoomType(floor);
  }

  // Rare rooms (mid-floor)
  if (roomIndex === Math.floor(totalRooms / 2) && Math.random() < SPIRE_CONFIG.rareRoomChance) {
    return generateRareRoomType();
  }

  // Puzzle rooms
  if (floor % 7 === 0 && Math.random() < SPIRE_CONFIG.puzzleRoomChance) {
    return 'puzzle';
  }

  return generateCombatRoomType(floor);
}

function generateCombatRoomType(floor: number): RoomType {
  const roll = Math.random();
  if (roll < 0.12) return 'swarm';
  if (roll < 0.22) return 'speed';
  return 'combat';
}

function generateRareRoomType(): SpireRoomType {
  const roll = Math.random();
  if (roll < SPIRE_CONFIG.recoveryRoomChance) return 'recovery';
  if (roll < SPIRE_CONFIG.recoveryRoomChance + SPIRE_CONFIG.libraryRoomChance) return 'library';
  return 'treasure';
}

// ─── Floor State Generation ───────────────────────────────────────────────────

export function generateSpireFloorState(floor: number, roomIndex: number, totalRooms: number): FloorState {
  const roomType = generateSpireRoomType(floor, roomIndex, totalRooms);
  const element = getFloorElement(floor);
  const baseHP = getFloorMaxHP(floor);

  switch (roomType) {
    case 'guardian': {
      const guardian = GUARDIANS[floor] || getExtendedGuardian(floor);
      if (guardian) {
        return {
          roomType: 'guardian',
          enemies: [{
            id: 'guardian',
            name: guardian.name,
            hp: guardian.hp,
            maxHP: guardian.hp,
            armor: guardian.armor || 0,
            dodgeChance: 0,
            barrier: 0,
            element: guardian.element,
          }],
        };
      }
      // Fallback if no guardian defined for this floor
      return generateCombatRoom(floor, element, baseHP);
    }

    case 'swarm':
      return generateSwarmRoom(floor, element, baseHP);

    case 'speed':
      return generateSpeedRoom(floor, element, baseHP);

    case 'puzzle': {
      const puzzleKeys = Object.keys(PUZZLE_ROOMS);
      const selectedPuzzle = puzzleKeys[Math.floor(Math.random() * puzzleKeys.length)];
      const puzzle = PUZZLE_ROOMS[selectedPuzzle];
      return {
        roomType: 'puzzle',
        enemies: [],
        puzzleProgress: 0,
        puzzleRequired: 1,
        puzzleId: selectedPuzzle,
        puzzleAttunements: puzzle.attunements,
      };
    }

    case 'recovery':
      return {
        roomType: 'recovery',
        enemies: [],
        recoveryProgress: 0,
        recoveryRequired: 1,
      };

    case 'library':
      return {
        roomType: 'library',
        enemies: [],
        libraryProgress: 0,
        libraryRequired: 1,
      };

    case 'treasure':
      return {
        roomType: 'treasure',
        enemies: [],
      };

    default:
      return generateCombatRoom(floor, element, baseHP);
  }
}

function generateCombatRoom(floor: number, element: string, baseHP: number): FloorState {
  const armor = getSpireEnemyArmor(floor);
  const barrier = getSpireEnemyBarrier(floor, element);
  const enemyName = getEnemyName(element, floor);

  return {
    roomType: 'combat',
    enemies: [{
      id: 'enemy',
      name: enemyName,
      hp: baseHP,
      maxHP: baseHP,
      armor,
      dodgeChance: 0,
      barrier,
      element,
    }],
  };
}

function generateSwarmRoom(floor: number, element: string, baseHP: number): FloorState {
  const numEnemies = 3 + Math.floor(Math.random() * 5); // 3-7 enemies
  const enemies: EnemyState[] = [];

  for (let i = 0; i < numEnemies; i++) {
    enemies.push({
      id: `swarm_${i}`,
      name: `${getEnemyName(element, floor)} ${i + 1}`,
      hp: Math.floor(baseHP * 0.35),
      maxHP: Math.floor(baseHP * 0.35),
      armor: Math.floor(floor / 15) * 0.02,
      dodgeChance: 0,
      barrier: 0,
      element,
    });
  }

  return { roomType: 'swarm', enemies };
}

function generateSpeedRoom(floor: number, element: string, baseHP: number): FloorState {
  const dodgeChance = Math.min(0.55, 0.20 + floor * 0.005);
  const armor = getSpireEnemyArmor(floor);

  return {
    roomType: 'speed',
    enemies: [{
      id: 'agile_enemy',
      name: `Agile ${getEnemyName(element, floor)}`,
      hp: baseHP,
      maxHP: baseHP,
      armor,
      dodgeChance,
      barrier: getSpireEnemyBarrier(floor, element),
      element,
    }],
  };
}

// ─── Enemy Stat Scaling ───────────────────────────────────────────────────────

export function getSpireEnemyArmor(floor: number): number {
  if (floor < 10) return 0;
  const baseChance = Math.min(0.5, (floor - 10) * 0.01);
  if (Math.random() > baseChance) return 0;
  const minArmor = 0.05;
  const maxArmor = 0.30;
  const progress = Math.min(1, (floor - 10) / 90);
  return minArmor + (maxArmor - minArmor) * progress * Math.random();
}

export function getSpireEnemyBarrier(floor: number, element: string): number {
  if (floor < 15) return 0;
  const barrierElements = ['light', 'water', 'earth'];
  const baseChance = barrierElements.includes(element) ? 0.12 : 0.06;
  const floorBonus = Math.min(0.2, (floor - 15) * 0.003);
  if (Math.random() > Math.min(0.35, baseChance + floorBonus)) return 0;
  const progress = Math.min(1, (floor - 15) / 85);
  return 0.1 + progress * 0.2;
}

// ─── Insight Calculation ──────────────────────────────────────────────────────

export function calcInsight(floor: number, isGuardian: boolean): number {
  const base = Math.floor(Math.pow(floor, 1.2));
  return isGuardian ? Math.floor(base * 2.5) : base;
}

// ─── Room Type Display ────────────────────────────────────────────────────────

export function getSpireRoomTypeDisplay(roomType: SpireRoomType): { label: string; icon: string; color: string } {
  const displays: Record<string, { label: string; icon: string; color: string }> = {
    combat: { label: 'Combat', icon: '⚔️', color: '#EF4444' },
    swarm: { label: 'Swarm', icon: '🐝', color: '#F59E0B' },
    speed: { label: 'Speed', icon: '💨', color: '#3B82F6' },
    guardian: { label: 'Guardian', icon: '🛡️', color: '#EF4444' },
    puzzle: { label: 'Puzzle', icon: '🧩', color: '#8B5CF6' },
    recovery: { label: 'Recovery', icon: '💚', color: '#10B981' },
    library: { label: 'Ancient Library', icon: '📚', color: '#6366F1' },
    treasure: { label: 'Treasure', icon: '💎', color: '#F59E0B' },
  };
  return displays[roomType] || { label: 'Unknown', icon: '❓', color: '#6B7280' };
}
