/**
 * DebugCommands.js
 * Global command system for testing game functionality.
 * Access via window.debugCommands in the browser console.
 */

import { gameStateManager } from "./GameStateManager.js";
import { itemRegistry } from "../managers/ItemRegistry.js";

/**
 * Debug command system for testing game mechanics.
 * @class
 */
export class DebugCommands {
  constructor() {
    this.gameStateManager = null;
    this.gameLoop = null;
  }

  /**
   * Initializes the debug commands system.
   * Should be called after gameStateManager is initialized.
   */
  init() {
    this.gameStateManager = gameStateManager;
    // GameLoop will be set when it's available
    if (gameStateManager.gameLoop) {
      this.gameLoop = gameStateManager.gameLoop;
    }
  }

  /**
   * Updates the game loop reference.
   * @param {import("./GameLoop.js").GameLoop} loop - Game loop instance
   */
  setGameLoop(loop) {
    this.gameLoop = loop;
  }

  // ============================================
  // EXPLORER & LEVELING COMMANDS
  // ============================================

  /**
   * Adds experience to an explorer and handles leveling.
   * @param {string} unitId - Unit ID (or "first" for first explorer, "all" for all)
   * @param {number} amount - XP amount to add
   * @returns {string} Result message
   */
  addXP(unitId = "first", amount = 100) {
    const units = this._getExplorers(unitId);
    if (units.length === 0) {
      return `No explorers found with ID: ${unitId}`;
    }

    const results = [];
    for (const unit of units) {
      const oldLevel = unit.getLevel();
      unit.gainExperience(amount);

      // Check for level up (simple XP curve: 100 * level^2)
      const mastery = unit.classMastery[unit.activeClassId];
      const xpForNextLevel = 100 * (mastery.level ** 2);
      
      while (mastery.xp >= xpForNextLevel && mastery.level < 30) {
        mastery.level += 1;
        mastery.skillPoints += 1; // Award skill point on level up
        mastery.xp -= xpForNextLevel;
        
        // Recalculate stats if class definition is available
        if (this.gameLoop?.classRegistry) {
          const classDef = this.gameLoop.classRegistry.get(unit.activeClassId);
          if (classDef) {
            unit.recalculateBaseStats(classDef);
            // Recalculate effective stats with equipment
            if (unit.recalculateStats) {
              unit.recalculateStats(
                this.gameLoop.inventoryManager?.itemRegistry || itemRegistry
              );
            }
          }
        }
      }

      const newLevel = unit.getLevel();
      const leveledUp = newLevel > oldLevel;
      results.push(
        `${unit.name} (${unit.id}): +${amount} XP. Level: ${oldLevel} → ${newLevel}. ` +
        `XP: ${mastery.xp}/${100 * (newLevel ** 2)}. ` +
        `Skill Points: ${mastery.skillPoints}. ` +
        (leveledUp ? "✨ LEVELED UP!" : "")
      );
    }

    return results.join("\n");
  }

  /**
   * Sets an explorer's level directly.
   * @param {string} unitId - Unit ID (or "first" for first explorer)
   * @param {number} level - Target level (1-30)
   * @returns {string} Result message
   */
  setLevel(unitId = "first", level = 5) {
    const units = this._getExplorers(unitId);
    if (units.length === 0) {
      return `No explorers found with ID: ${unitId}`;
    }

    level = Math.max(1, Math.min(30, level));

    const results = [];
    for (const unit of units) {
      const mastery = unit.classMastery[unit.activeClassId];
      const oldLevel = mastery.level;
      mastery.level = level;
      
      // Calculate XP for this level (simple curve: sum of 100 * level^2 for all previous levels)
      let totalXP = 0;
      for (let i = 1; i < level; i++) {
        totalXP += 100 * (i ** 2);
      }
      mastery.xp = 0; // Reset XP to 0 for current level
      
      // Award skill points (1 per level, starting from level 2)
      mastery.skillPoints = Math.max(0, level - 1);

      // Recalculate stats
      if (this.gameLoop?.classRegistry) {
        const classDef = this.gameLoop.classRegistry.get(unit.activeClassId);
        if (classDef) {
          unit.recalculateBaseStats(classDef);
          if (unit.recalculateStats) {
            unit.recalculateStats(
              this.gameLoop.inventoryManager?.itemRegistry || itemRegistry
            );
          }
        }
      }

      results.push(
        `${unit.name} (${unit.id}): Level set to ${level} (was ${oldLevel}). ` +
        `Skill Points: ${mastery.skillPoints}`
      );
    }

    return results.join("\n");
  }

  /**
   * Adds skill points to an explorer.
   * @param {string} unitId - Unit ID (or "first" for first explorer)
   * @param {number} amount - Skill points to add
   * @returns {string} Result message
   */
  addSkillPoints(unitId = "first", amount = 5) {
    const units = this._getExplorers(unitId);
    if (units.length === 0) {
      return `No explorers found with ID: ${unitId}`;
    }

    const results = [];
    for (const unit of units) {
      const mastery = unit.classMastery[unit.activeClassId];
      mastery.skillPoints = (mastery.skillPoints || 0) + amount;
      results.push(
        `${unit.name} (${unit.id}): +${amount} skill points. Total: ${mastery.skillPoints}`
      );
    }

    return results.join("\n");
  }

  // ============================================
  // SKILL TREE COMMANDS
  // ============================================

  /**
   * Unlocks a skill node for an explorer.
   * @param {string} unitId - Unit ID (or "first" for first explorer)
   * @param {string} nodeId - Skill node ID to unlock
   * @returns {string} Result message
   */
  unlockSkill(unitId = "first", nodeId) {
    if (!nodeId) {
      return "Error: nodeId is required. Usage: unlockSkill(unitId, nodeId)";
    }

    const units = this._getExplorers(unitId);
    if (units.length === 0) {
      return `No explorers found with ID: ${unitId}`;
    }

    const results = [];
    for (const unit of units) {
      const mastery = unit.classMastery[unit.activeClassId];
      if (!mastery.unlockedNodes) {
        mastery.unlockedNodes = [];
      }

      if (mastery.unlockedNodes.includes(nodeId)) {
        results.push(`${unit.name} (${unit.id}): Node ${nodeId} already unlocked`);
        continue;
      }

      // Get node cost (default to 1 if we can't determine)
      let cost = 1;
      if (this.gameLoop?.classRegistry) {
        const classDef = this.gameLoop.classRegistry.get(unit.activeClassId);
        // Skill trees are generated dynamically, so we can't get node cost from classDef
        // Default to 1 for now
      }

      // Unlock the node (bypass skill point check for debug)
      mastery.unlockedNodes.push(nodeId);

      // Recalculate stats if unit has the method
      if (unit.recalculateStats && this.gameLoop?.classRegistry) {
        const classDef = this.gameLoop.classRegistry.get(unit.activeClassId);
        if (classDef?.skillTreeData) {
          unit.recalculateStats(
            this.gameLoop.inventoryManager?.itemRegistry || itemRegistry,
            classDef.skillTreeData
          );
        }
      }

      results.push(
        `${unit.name} (${unit.id}): Unlocked skill node ${nodeId} (cost: ${cost})`
      );
    }

    return results.join("\n");
  }

  /**
   * Unlocks all skill nodes for an explorer.
   * @param {string} unitId - Unit ID (or "first" for first explorer)
   * @returns {string} Result message
   */
  unlockAllSkills(unitId = "first") {
    const units = this._getExplorers(unitId);
    if (units.length === 0) {
      return `No explorers found with ID: ${unitId}`;
    }

    const results = [];
    for (const unit of units) {
      if (!this.gameLoop?.classRegistry) {
        results.push(`${unit.name}: Cannot unlock all skills - class registry not available`);
        continue;
      }

      const classDef = this.gameLoop.classRegistry.get(unit.activeClassId);
      if (!classDef) {
        results.push(`${unit.name}: Class definition not found`);
        continue;
      }

      // Skill trees are generated dynamically, so we can't easily get all node IDs
      // For now, return a helpful message
      results.push(
        `${unit.name} (${unit.id}): Note - Skill trees are generated dynamically. ` +
        `Use unlockSkill(unitId, nodeId) with specific node IDs. ` +
        `To see available nodes, open the character sheet for this unit.`
      );
    }

    return results.join("\n");
  }

  // ============================================
  // INVENTORY COMMANDS
  // ============================================

  /**
   * Adds an item to inventory (hub stash or run stash).
   * @param {string} itemDefId - Item definition ID
   * @param {number} quantity - Quantity to add (default: 1)
   * @param {string} target - "hub" or "run" (default: "hub")
   * @returns {string} Result message
   */
  addItem(itemDefId, quantity = 1, target = "hub") {
    if (!itemDefId) {
      return "Error: itemDefId is required. Usage: addItem(itemDefId, quantity, target)";
    }

    const itemDef = itemRegistry.get(itemDefId);
    if (!itemDef) {
      return `Error: Item definition not found: ${itemDefId}`;
    }

    const itemInstance = {
      uid: `ITEM_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      defId: itemDefId,
      isNew: true,
      quantity: quantity,
    };

    if (target === "run" && this.gameLoop?.inventoryManager?.runStash) {
      this.gameLoop.inventoryManager.runStash.addItem(itemInstance);
      return `Added ${quantity}x ${itemDefId} to run stash`;
    } else if (this.gameStateManager?.hubStash) {
      this.gameStateManager.hubStash.addItem(itemInstance);
      // Save hub stash
      if (this.gameStateManager._saveHubStash) {
        this.gameStateManager._saveHubStash();
      }
      return `Added ${quantity}x ${itemDefId} to hub stash`;
    } else {
      return "Error: No stash available";
    }
  }

  /**
   * Adds currency to hub stash.
   * @param {number} shards - Aether shards to add
   * @param {number} cores - Ancient cores to add (optional)
   * @returns {string} Result message
   */
  addCurrency(shards = 1000, cores = 0) {
    if (!this.gameStateManager?.hubStash) {
      return "Error: Hub stash not available";
    }

    this.gameStateManager.hubStash.currency.aetherShards =
      (this.gameStateManager.hubStash.currency.aetherShards || 0) + shards;
    if (cores > 0) {
      this.gameStateManager.hubStash.currency.ancientCores =
        (this.gameStateManager.hubStash.currency.ancientCores || 0) + cores;
    }

    // Save hub stash
    if (this.gameStateManager._saveHubStash) {
      this.gameStateManager._saveHubStash();
    }

    return `Added ${shards} Aether Shards${cores > 0 ? ` and ${cores} Ancient Cores` : ""} to hub stash`;
  }

  // ============================================
  // COMBAT COMMANDS
  // ============================================

  /**
   * Kills an enemy (or all enemies).
   * @param {string} enemyId - Enemy unit ID (or "all" for all enemies)
   * @returns {string} Result message
   */
  killEnemy(enemyId = "all") {
    if (!this.gameLoop?.unitManager) {
      return "Error: Game loop or unit manager not available";
    }

    const enemies = this._getEnemies(enemyId);
    if (enemies.length === 0) {
      return `No enemies found${enemyId !== "all" ? ` with ID: ${enemyId}` : ""}`;
    }

    const results = [];
    for (const enemy of enemies) {
      if (this.gameLoop.handleUnitDeath) {
        this.gameLoop.handleUnitDeath(enemy);
      } else {
        // Fallback: set health to 0 and remove from unit manager
        enemy.currentHealth = 0;
        if (this.gameLoop.unitManager.removeUnit) {
          this.gameLoop.unitManager.removeUnit(enemy.id);
        }
      }
      results.push(`Killed ${enemy.name} (${enemy.id})`);
    }

    return results.join("\n");
  }

  /**
   * Heals a unit to full health.
   * @param {string} unitId - Unit ID (or "all" for all player units)
   * @returns {string} Result message
   */
  healUnit(unitId = "all") {
    if (!this.gameLoop?.unitManager) {
      return "Error: Game loop or unit manager not available";
    }

    const units = unitId === "all"
      ? this.gameLoop.unitManager.getUnitsByTeam("PLAYER")
      : [this.gameLoop.unitManager.getUnitById(unitId)].filter(Boolean);

    if (units.length === 0) {
      return `No units found${unitId !== "all" ? ` with ID: ${unitId}` : ""}`;
    }

    const results = [];
    for (const unit of units) {
      const oldHP = unit.currentHealth;
      unit.currentHealth = unit.maxHealth;
      results.push(`${unit.name} (${unit.id}): Healed ${unit.maxHealth - oldHP} HP (${oldHP} → ${unit.maxHealth})`);
    }

    return results.join("\n");
  }

  // ============================================
  // MISSION & NARRATIVE COMMANDS
  // ============================================

  /**
   * Triggers mission victory.
   * @returns {string} Result message
   */
  triggerVictory() {
    if (!this.gameStateManager?.missionManager) {
      return "Error: Mission manager not available";
    }

    // Complete all primary objectives
    if (this.gameStateManager.missionManager.currentObjectives) {
      this.gameStateManager.missionManager.currentObjectives.forEach((obj) => {
        obj.complete = true;
        obj.current = obj.target_count || 1;
      });
    }

    // Trigger victory check
    this.gameStateManager.missionManager.checkVictory();

    return "Mission victory triggered!";
  }

  /**
   * Completes a specific objective.
   * @param {string} objectiveId - Objective ID (or index as number)
   * @returns {string} Result message
   */
  completeObjective(objectiveId) {
    if (!this.gameStateManager?.missionManager) {
      return "Error: Mission manager not available";
    }

    const objectives = this.gameStateManager.missionManager.currentObjectives || [];
    let objective = null;

    if (typeof objectiveId === "number") {
      objective = objectives[objectiveId];
    } else {
      objective = objectives.find((obj) => obj.id === objectiveId);
    }

    if (!objective) {
      return `Error: Objective not found: ${objectiveId}`;
    }

    objective.complete = true;
    objective.current = objective.target_count || 1;

    // Check victory
    this.gameStateManager.missionManager.checkVictory();

    return `Objective completed: ${objective.type} (${objective.id || "unnamed"})`;
  }

  /**
   * Triggers the next narrative sequence.
   * @param {string} narrativeId - Narrative ID (optional, uses current mission's narrative if not provided)
   * @returns {string} Result message
   */
  triggerNarrative(narrativeId = null) {
    if (!this.gameStateManager?.narrativeManager) {
      return "Error: Narrative manager not available";
    }

    if (narrativeId) {
      // Load and start specific narrative
      this.gameStateManager.narrativeManager
        .loadSequence(narrativeId)
        .then(() => {
          this.gameStateManager.narrativeManager.startSequence(narrativeId);
        })
        .catch((error) => {
          console.error("Error loading narrative:", error);
        });
      return `Triggered narrative: ${narrativeId}`;
    } else {
      // Try to trigger current mission's intro/outro
      const missionDef = this.gameStateManager.missionManager?.currentMissionDef;
      if (missionDef?.narrative) {
        const narrativeToUse =
          missionDef.narrative.intro_success ||
          missionDef.narrative.intro ||
          missionDef.narrative.outro_success;
        if (narrativeToUse) {
          this.gameStateManager.narrativeManager
            .loadSequence(narrativeToUse)
            .then(() => {
              this.gameStateManager.narrativeManager.startSequence(narrativeToUse);
            })
            .catch((error) => {
              console.error("Error loading narrative:", error);
            });
          return `Triggered narrative: ${narrativeToUse}`;
        }
      }
      return "Error: No narrative specified and no mission narrative found";
    }
  }

  // ============================================
  // UTILITY COMMANDS
  // ============================================

  /**
   * Lists all available commands in a readable format.
   * Uses console formatting for better readability.
   */
  help() {
    console.log(
      "%c=== DEBUG COMMANDS HELP ===\n",
      "font-weight: bold; font-size: 16px; color: #4CAF50;"
    );

    console.log(
      "%cEXPLORER & LEVELING:",
      "font-weight: bold; color: #2196F3;"
    );
    console.log("  %caddXP(unitId, amount)%c          - Add XP to explorer(s)", "color: #FF9800;", "color: inherit;");
    console.log("                          unitId: \"first\", \"all\", or specific ID");
    console.log("  %csetLevel(unitId, level)%c        - Set explorer level directly (1-30)", "color: #FF9800;", "color: inherit;");
    console.log("  %caddSkillPoints(unitId, amount)%c - Add skill points to explorer", "color: #FF9800;", "color: inherit;");
    console.log("");

    console.log(
      "%cSKILL TREE:",
      "font-weight: bold; color: #2196F3;"
    );
    console.log("  %cunlockSkill(unitId, nodeId)%c    - Unlock a specific skill node", "color: #FF9800;", "color: inherit;");
    console.log("  %cunlockAllSkills(unitId)%c         - Unlock all skill nodes for explorer", "color: #FF9800;", "color: inherit;");
    console.log("");

    console.log(
      "%cINVENTORY:",
      "font-weight: bold; color: #2196F3;"
    );
    console.log("  %caddItem(itemDefId, quantity, target)%c - Add item", "color: #FF9800;", "color: inherit;");
    console.log("                          target: \"hub\" or \"run\"");
    console.log("  %caddCurrency(shards, cores)%c     - Add currency to hub stash", "color: #FF9800;", "color: inherit;");
    console.log("");

    console.log(
      "%cCOMBAT:",
      "font-weight: bold; color: #2196F3;"
    );
    console.log("  %ckillEnemy(enemyId)%c             - Kill enemy", "color: #FF9800;", "color: inherit;");
    console.log("                          enemyId: \"all\" or specific ID");
    console.log("  %chealUnit(unitId)%c               - Heal unit to full", "color: #FF9800;", "color: inherit;");
    console.log("                          unitId: \"all\" or specific ID");
    console.log("");

    console.log(
      "%cMISSION & NARRATIVE:",
      "font-weight: bold; color: #2196F3;"
    );
    console.log("  %ctriggerVictory()%c                - Trigger mission victory", "color: #FF9800;", "color: inherit;");
    console.log("  %ccompleteObjective(objectiveId)%c   - Complete a specific objective", "color: #FF9800;", "color: inherit;");
    console.log("  %ctriggerNarrative(narrativeId)%c   - Trigger narrative sequence", "color: #FF9800;", "color: inherit;");
    console.log("");

    console.log(
      "%cUTILITY:",
      "font-weight: bold; color: #2196F3;"
    );
    console.log("  %chelp()%c                          - Show this help", "color: #FF9800;", "color: inherit;");
    console.log("  %clistIds()%c                        - List all available IDs", "color: #FF9800;", "color: inherit;");
    console.log("  %clistPlayerIds()%c                  - List player unit IDs only", "color: #FF9800;", "color: inherit;");
    console.log("  %clistEnemyIds()%c                   - List enemy unit IDs only", "color: #FF9800;", "color: inherit;");
    console.log("  %clistItemIds(limit)%c               - List item IDs only (default limit: 100)", "color: #FF9800;", "color: inherit;");
    console.log("  %clistUnits()%c                      - List all units with details", "color: #FF9800;", "color: inherit;");
    console.log("  %clistItems(limit)%c                 - List available items with details (default limit: 50)", "color: #FF9800;", "color: inherit;");
    console.log("  %cgetState()%c                      - Get current game state info", "color: #FF9800;", "color: inherit;");
    console.log("");

    console.log(
      "%cQUICK EXAMPLES:",
      "font-weight: bold; color: #9C27B0;"
    );
    console.log("  %cdebugCommands.addXP(\"first\", 500)", "color: #4CAF50; font-family: monospace;");
    console.log("  %cdebugCommands.setLevel(\"all\", 10)", "color: #4CAF50; font-family: monospace;");
    console.log("  %cdebugCommands.addItem(\"ITEM_SWORD_T1\", 1, \"hub\")", "color: #4CAF50; font-family: monospace;");
    console.log("  %cdebugCommands.killEnemy(\"all\")", "color: #4CAF50; font-family: monospace;");
    console.log("  %cdebugCommands.triggerVictory()", "color: #4CAF50; font-family: monospace;");
    console.log("");

    console.log(
      "%cTIP: Use listIds() to see all available IDs for commands!",
      "font-style: italic; color: #757575;"
    );

    return "Help displayed above. Check the console for formatted output.";
  }

  /**
   * Lists all units in the game.
   * @returns {string} Unit list
   */
  listUnits() {
    if (!this.gameLoop?.unitManager) {
      return "Error: Game loop or unit manager not available";
    }

    const allUnits = this.gameLoop.unitManager.getAllUnits();
    if (allUnits.length === 0) {
      return "No units found";
    }

    const playerUnits = allUnits.filter((u) => u.team === "PLAYER");
    const enemyUnits = allUnits.filter((u) => u.team === "ENEMY");

    let result = `Total Units: ${allUnits.length}\n\n`;
    
    if (playerUnits.length > 0) {
      result += "PLAYER UNITS:\n";
      playerUnits.forEach((unit) => {
        const level = unit.getLevel ? unit.getLevel() : "?";
        result += `  - ${unit.name} (${unit.id}) - Level ${level} - HP: ${unit.currentHealth}/${unit.maxHealth}\n`;
      });
    }

    if (enemyUnits.length > 0) {
      result += "\nENEMY UNITS:\n";
      enemyUnits.forEach((unit) => {
        result += `  - ${unit.name} (${unit.id}) - HP: ${unit.currentHealth}/${unit.maxHealth}\n`;
      });
    }

    return result;
  }

  /**
   * Lists player unit IDs only (for use with commands).
   * @returns {string} Player IDs list
   */
  listPlayerIds() {
    if (!this.gameLoop?.unitManager) {
      return "Error: Game loop or unit manager not available";
    }

    const playerUnits = this.gameLoop.unitManager.getUnitsByTeam("PLAYER");
    if (playerUnits.length === 0) {
      return "No player units found";
    }

    let result = "PLAYER UNIT IDs:\n";
    playerUnits.forEach((unit) => {
      const level = unit.getLevel ? unit.getLevel() : "?";
      result += `  "${unit.id}" - ${unit.name} (Level ${level})\n`;
    });
    result += `\nUse with: addXP("${playerUnits[0]?.id}", 100) or addXP("first", 100) or addXP("all", 100)`;

    return result;
  }

  /**
   * Lists enemy unit IDs only (for use with commands).
   * @returns {string} Enemy IDs list
   */
  listEnemyIds() {
    if (!this.gameLoop?.unitManager) {
      return "Error: Game loop or unit manager not available";
    }

    const enemyUnits = this.gameLoop.unitManager.getUnitsByTeam("ENEMY");
    if (enemyUnits.length === 0) {
      return "No enemy units found";
    }

    let result = "ENEMY UNIT IDs:\n";
    enemyUnits.forEach((unit) => {
      result += `  "${unit.id}" - ${unit.name} (HP: ${unit.currentHealth}/${unit.maxHealth})\n`;
    });
    result += `\nUse with: killEnemy("${enemyUnits[0]?.id}") or killEnemy("all")`;

    return result;
  }

  /**
   * Lists available items in the registry.
   * @param {number} limit - Maximum number of items to show (default: 50)
   * @returns {string} Item list
   */
  listItems(limit = 50) {
    const items = Array.from(itemRegistry.getAll ? itemRegistry.getAll() : []);
    if (items.length === 0) {
      return "No items found in registry";
    }

    let result = `Available Items (showing ${Math.min(limit, items.length)} of ${items.length}):\n\n`;
    items.slice(0, limit).forEach((item) => {
      result += `  - ${item.id} (${item.type || "UNKNOWN"})`;
      if (item.name) {
        result += `: ${item.name}`;
      }
      result += "\n";
    });

    if (items.length > limit) {
      result += `\n... and ${items.length - limit} more items`;
    }

    return result;
  }

  /**
   * Lists item IDs only (for use with addItem command).
   * @param {number} limit - Maximum number of items to show (default: 100)
   * @returns {string} Item IDs list
   */
  listItemIds(limit = 100) {
    const items = Array.from(itemRegistry.getAll ? itemRegistry.getAll() : []);
    if (items.length === 0) {
      return "No items found in registry";
    }

    let result = "ITEM IDs:\n";
    items.slice(0, limit).forEach((item) => {
      result += `  "${item.id}"`;
      if (item.name) {
        result += ` - ${item.name}`;
      }
      if (item.type) {
        result += ` (${item.type})`;
      }
      result += "\n";
    });

    if (items.length > limit) {
      result += `\n... and ${items.length - limit} more items (use listItems() to see all)`;
    }

    result += `\nUse with: addItem("${items[0]?.id}", 1, "hub")`;

    return result;
  }

  /**
   * Lists all available IDs (players, enemies, items, objectives, narratives).
   * @returns {string} Comprehensive ID list
   */
  listIds() {
    let result = "=== AVAILABLE IDs ===\n\n";

    // Player IDs
    if (this.gameLoop?.unitManager) {
      const playerUnits = this.gameLoop.unitManager.getUnitsByTeam("PLAYER");
      if (playerUnits.length > 0) {
        result += "PLAYER UNIT IDs:\n";
        playerUnits.forEach((unit) => {
          result += `  "${unit.id}" - ${unit.name}\n`;
        });
        result += "\n";
      }
    }

    // Enemy IDs
    if (this.gameLoop?.unitManager) {
      const enemyUnits = this.gameLoop.unitManager.getUnitsByTeam("ENEMY");
      if (enemyUnits.length > 0) {
        result += "ENEMY UNIT IDs:\n";
        enemyUnits.forEach((unit) => {
          result += `  "${unit.id}" - ${unit.name}\n`;
        });
        result += "\n";
      }
    }

    // Item IDs
    const items = Array.from(itemRegistry.getAll ? itemRegistry.getAll() : []);
    if (items.length > 0) {
      result += `ITEM IDs (showing first 20 of ${items.length}):\n`;
      items.slice(0, 20).forEach((item) => {
        result += `  "${item.id}"`;
        if (item.name) {
          result += ` - ${item.name}`;
        }
        result += "\n";
      });
      if (items.length > 20) {
        result += `  ... and ${items.length - 20} more (use listItemIds() to see all)\n`;
      }
      result += "\n";
    }

    // Objective IDs
    if (this.gameStateManager?.missionManager?.currentObjectives) {
      const objectives = this.gameStateManager.missionManager.currentObjectives;
      if (objectives.length > 0) {
        result += "OBJECTIVE IDs:\n";
        objectives.forEach((obj, idx) => {
          result += `  ${idx} or "${obj.id || `objective_${idx}`}" - ${obj.type}\n`;
        });
        result += "\n";
      }
    }

    // Mission ID
    if (this.gameStateManager?.missionManager?.activeMissionId) {
      result += `ACTIVE MISSION ID:\n  "${this.gameStateManager.missionManager.activeMissionId}"\n\n`;
    }

    // Narrative IDs (from current mission)
    if (this.gameStateManager?.missionManager?.currentMissionDef?.narrative) {
      const narrative = this.gameStateManager.missionManager.currentMissionDef.narrative;
      result += "NARRATIVE IDs (from current mission):\n";
      if (narrative.intro) result += `  "${narrative.intro}" - Intro\n`;
      if (narrative.intro_success) result += `  "${narrative.intro_success}" - Intro Success\n`;
      if (narrative.outro_success) result += `  "${narrative.outro_success}" - Outro Success\n`;
      if (narrative.outro_failure) result += `  "${narrative.outro_failure}" - Outro Failure\n`;
      result += "\n";
    }

    result += "Use listPlayerIds(), listEnemyIds(), or listItemIds() for detailed lists.";

    return result;
  }

  /**
   * Gets current game state information.
   * @returns {string} State info
   */
  getState() {
    let result = "Game State:\n\n";
    
    result += `Current State: ${this.gameStateManager?.currentState || "UNKNOWN"}\n`;
    result += `Game Running: ${this.gameLoop?.isRunning || false}\n`;
    result += `Game Paused: ${this.gameLoop?.isPaused || false}\n`;

    if (this.gameStateManager?.missionManager) {
      const mm = this.gameStateManager.missionManager;
      result += `\nMission: ${mm.activeMissionId || "None"}\n`;
      if (mm.currentObjectives) {
        result += `Objectives: ${mm.currentObjectives.length}\n`;
        mm.currentObjectives.forEach((obj, idx) => {
          result += `  ${idx + 1}. ${obj.type} - ${obj.complete ? "✓" : "✗"} (${obj.current || 0}/${obj.target_count || 0})\n`;
        });
      }
    }

    if (this.gameLoop?.turnSystem) {
      const activeUnit = this.gameLoop.turnSystem.getActiveUnit();
      if (activeUnit) {
        result += `\nActive Unit: ${activeUnit.name} (${activeUnit.id})\n`;
      }
    }

    return result;
  }

  // ============================================
  // HELPER METHODS
  // ============================================

  /**
   * Gets explorer units by ID or special keywords.
   * @param {string} unitId - Unit ID, "first", or "all"
   * @returns {Array} Array of explorer units
   * @private
   */
  _getExplorers(unitId) {
    if (!this.gameLoop?.unitManager) {
      return [];
    }

    if (unitId === "all") {
      return this.gameLoop.unitManager.getUnitsByTeam("PLAYER");
    } else if (unitId === "first") {
      const units = this.gameLoop.unitManager.getUnitsByTeam("PLAYER");
      return units.length > 0 ? [units[0]] : [];
    } else {
      const unit = this.gameLoop.unitManager.getUnitById(unitId);
      return unit && unit.team === "PLAYER" ? [unit] : [];
    }
  }

  /**
   * Gets enemy units by ID or special keywords.
   * @param {string} enemyId - Enemy ID or "all"
   * @returns {Array} Array of enemy units
   * @private
   */
  _getEnemies(enemyId) {
    if (!this.gameLoop?.unitManager) {
      return [];
    }

    if (enemyId === "all") {
      return this.gameLoop.unitManager.getUnitsByTeam("ENEMY");
    } else {
      const unit = this.gameLoop.unitManager.getUnitById(enemyId);
      return unit && unit.team === "ENEMY" ? [unit] : [];
    }
  }
}

// Create singleton instance
export const debugCommands = new DebugCommands();

// Make it globally available
if (typeof window !== "undefined") {
  window.debugCommands = debugCommands;
}

