const DatapackLoader = require("./DatapackLoader");

class CombatService {
  initializeBattle(player, hostiles) {
    const equipmentStats = this.calculateEquipmentStats(player.equipment);

    const playerMaxHp = 100 + (equipmentStats.health || 0);
    const playerAtk = 25 + (equipmentStats.attack || 0);
    const playerDef = equipmentStats.defence || 0;
    const playerRes = equipmentStats.resistance || 0;

    const battle = {
      player: {
        id: player.id,
        name: player.username || "Commander",
        hp: playerMaxHp,
        maxHp: playerMaxHp,
        atk: playerAtk,
        def: playerDef,
        res: playerRes,
        stats: equipmentStats,
      },
      enemies: hostiles.map((h, index) => {
        const hHp = h.stats?.health || 50;
        return {
          ...h,
          instanceId: `mob_${index}`,
          id: h.id,
          name: h.displayName || h.name || `Hostile ${index + 1}`,
          hp: hHp,
          maxHp: hHp,
          atk: h.stats?.attack || 10,
          def: h.stats?.defence || 0,
          res: h.stats?.resistance || 0,
          isDead: false,
          rewardGiven: false,
          gainXp: h.gainXp || 0,
          credits: h.credits || 0,
          loot: h.loot || [],
        };
      }),
      turnOrder: ["player", ...hostiles.map((_, i) => `mob_${i}`)],
      currentTurnIndex: 0,
      turnStartTime: Date.now(),
      isOver: false,
    };

    return battle;
  }

  calculateEquipmentStats(equipment) {
    const totals = { health: 0, attack: 0, defence: 0, resistance: 0 };
    if (!equipment) return totals;

    Object.values(equipment).forEach((itemId) => {
      if (!itemId) return;
      const itemData = DatapackLoader.getItem(itemId);
      if (itemData && itemData.stats) {
        Object.entries(itemData.stats).forEach(([key, value]) => {
          const lowerKey = key.toLowerCase();
          if (lowerKey.includes("health") || lowerKey === "hp")
            totals.health += value;
          else if (lowerKey.includes("attack") || lowerKey.includes("atk"))
            totals.attack += value;
          else if (lowerKey.includes("def")) totals.defence += value;
          else if (lowerKey.includes("res")) totals.resistance += value;
        });
      }
    });
    return totals;
  }

  handleAttack(battle, targetInstanceId) {
    const attackerId = battle.turnOrder[battle.currentTurnIndex];
    const log = [];

    if (attackerId === "player") {
      const target = battle.enemies.find(
        (e) => e.instanceId === targetInstanceId,
      );
      if (target && !target.isDead) {
        const dmg = Math.max(
          1,
          Math.round(battle.player.atk - target.def * 0.5),
        );
        target.hp = Math.max(0, target.hp - dmg);
        log.push(`Commander dealt ${dmg} damage to ${target.name}`);
        if (target.hp === 0) {
          target.isDead = true;
          log.push(`${target.name} neutralized.`);
        }
      }
    } else {
      const enemy = battle.enemies.find((e) => e.instanceId === attackerId);
      if (enemy && !enemy.isDead && battle.player.hp > 0) {
        const dmg = Math.max(
          1,
          Math.round(enemy.atk - battle.player.def * 0.5),
        );
        battle.player.hp = Math.max(0, battle.player.hp - dmg);
        log.push(`${enemy.name} deals ${dmg} damage to Commander`);
        if (battle.player.hp === 0) battle.isOver = true;
      }
    }
    return log;
  }

  handleSkip(battle) {
    return [
      `Sequence timeout: ${battle.turnOrder[battle.currentTurnIndex]} skipped turn.`,
    ];
  }
}

module.exports = new CombatService();
