import { EquipmentSlot, world, Player } from "@minecraft/server";

var bulletConfig = {
  // урон для каждого снаряда
  "addon:glock18_bullet": {
    "minDamage": 8,
    "maxDamage": 8,
    "minSneakingDamage": 8,
    "maxSneakingDamage": 8
  },
  "addon:m17_bullet": {
    "minDamage": 10,
    "maxDamage": 10,
    "minSneakingDamage": 10,
    "maxSneakingDamage": 10
  },
  "addon:p226_bullet": {
    "minDamage": 8,
    "maxDamage": 8,
    "minSneakingDamage": 8,
    "maxSneakingDamage": 8
  },
  "addon:ak105_bullet": {
    "minDamage": 14,
    "maxDamage": 14,
    "minSneakingDamage": 14,
    "maxSneakingDamage": 14
  },
  "addon:scarh_bullet": {
    "minDamage": 15,
    "maxDamage": 15,
    "minSneakingDamage": 15,
    "maxSneakingDamage": 15
  },
  "addon:mp7_bullet": {
    "minDamage": 12,
    "maxDamage": 12,
    "minSneakingDamage": 12,
    "maxSneakingDamage": 12
  },
  "addon:mac10_bullet": {
    "minDamage": 11,
    "maxDamage": 11,
    "minSneakingDamage": 11,
    "maxSneakingDamage": 11
  },
  "addon:deagle_bullet": {
    "minDamage": 13,
    "maxDamage": 13,
    "minSneakingDamage": 13,
    "maxSneakingDamage": 13
  },
  "addon:sig_m7_bullet": {
    "minDamage": 14,
    "maxDamage": 14,
    "minSneakingDamage": 14,
    "maxSneakingDamage": 14
  },
  "addon:m500_bullet": {
    "minDamage": 15,
    "maxDamage": 15,
    "minSneakingDamage": 15,
    "maxSneakingDamage": 15
  },
  "addon:glock17_bullet": {
    "minDamage": 9,
    "maxDamage": 9,
    "minSneakingDamage": 9,
    "maxSneakingDamage": 9
  }
};

var armorDefense = {
  // единицы защиты для каждой брони
  "minecraft:leather_helmet": 1,
  "minecraft:leather_chestplate": 3,
  "minecraft:leather_leggings": 2,
  "minecraft:leather_boots": 1,
  "minecraft:golden_helmet": 2,
  "minecraft:golden_chestplate": 5,
  "minecraft:golden_leggings": 3,
  "minecraft:golden_boots": 1,
  "minecraft:chainmail_helmet": 2,
  "minecraft:chainmail_chestplate": 5,
  "minecraft:chainmail_leggings": 4,
  "minecraft:chainmail_boots": 1,
  "minecraft:iron_helmet": 2,
  "minecraft:iron_chestplate": 6,
  "minecraft:iron_leggings": 5,
  "minecraft:iron_boots": 2,
  "minecraft:diamond_helmet": 3,
  "minecraft:diamond_chestplate": 8,
  "minecraft:diamond_leggings": 6,
  "minecraft:diamond_boots": 3,
  "minecraft:netherite_helmet": 4,
  "minecraft:netherite_chestplate": 10,
  "minecraft:netherite_leggings": 8,
  "minecraft:netherite_boots": 4,
  "minecraft:turtle_helmet": 2
};

var armorTags = {
  netherite_helmet: 4,
  netherite_chestplate: 10,
  netherite_leggings: 8,
  netherite_boots: 4,
  diamond_helmet: 3,
  diamond_chestplate: 8,
  diamond_leggings: 6,
  diamond_boots: 3,
  iron_helmet: 2,
  iron_chestplate: 6,
  iron_leggings: 5,
  iron_boots: 2,
  chainmail_helmet: 2,
  chainmail_chestplate: 5,
  chainmail_leggings: 4,
  chainmail_boots: 1,
  golden_helmet: 2,
  olden_chestplate: 5,
  golden_leggings: 3,
  golden_boots: 1,
  leather_helmet: 1,
  leather_chestplate: 3,
  leather_leggings: 2,
  leather_boots: 1,
  turtle_helmet: 2
};

var maxArmorDefense = 20;
var armorDefensePercentage = 4;
var ProjectileProtectionProtectionPercentage = 8;
var MaxProtection = 80;

function calculateBaseDefense(entity) {
  let totalDefense = 0;
  const equipment = entity.getComponent("equippable");
  if (!equipment) {
    const tags = entity.getTags();
    if (tags.length <= 0) return 0;
    for (const tag of tags) {
      if (tag in armorTags) {
        totalDefense += armorTags[tag];
      }
    }
    return Math.min(totalDefense, maxArmorDefense);
  }
  const armorSlots = [EquipmentSlot.Head, EquipmentSlot.Chest, EquipmentSlot.Legs, EquipmentSlot.Feet];
  for (const slot of armorSlots) {
    const item = equipment.getEquipment(slot);
    if (item && item.typeId in armorDefense) {
      totalDefense += armorDefense[item.typeId];
    }
  }
  return Math.min(totalDefense, maxArmorDefense);
}

function calculateProjectileProtection(entity) {
  let totalProtection = 0;
  const equipment = entity.getComponent("equippable");
  if (!equipment) return 0;
  const armorSlots = [EquipmentSlot.Head, EquipmentSlot.Chest, EquipmentSlot.Legs, EquipmentSlot.Feet];
  for (const slot of armorSlots) {
    const item = equipment.getEquipment(slot);
    if (item) {
      const enchants = item.getComponent("enchantable");
      if (enchants) {
        const projectileProtection = enchants.getEnchantment("projectile_protection");
        if (projectileProtection) {
          totalProtection += projectileProtection.level;
        }
      }
    }
  }
  const protectionPercent = Math.min(totalProtection * ProjectileProtectionProtectionPercentage, MaxProtection);
  return protectionPercent;
}

function calculateResistanceReduction(entity) {
  const resistanceEffect = entity.getEffect("resistance");
  if (!resistanceEffect) return 0;
  
  const resistanceLevel = resistanceEffect.amplifier + 1;
  
  // Эффект Стойкости уменьшает урон на 20% за каждый уровень
  const reductionPercent = Math.min(resistanceLevel * 20, 100);
  
  return reductionPercent;
}

function getRandomDamage(bulletId) {
  const cfg = bulletConfig[bulletId];
  return Math.floor(Math.random() * (cfg.maxDamage - cfg.minDamage + 1)) + cfg.minDamage;
}

function getRandomSneakingDamage(bulletId) {
  const cfg = bulletConfig[bulletId];
  return Math.floor(Math.random() * (cfg.maxSneakingDamage - cfg.minSneakingDamage + 1)) + cfg.minSneakingDamage;
}

function isUsingShield(entity) {
  // Проверяем, является ли сущность игроком
  if (!(entity instanceof Player)) return false;
  
  // Проверяем, приседает ли игрок
  if (!entity.isSneaking) return false;
  
  // Проверяем наличие щита в руках
  const equipment = entity.getComponent("equippable");
  if (!equipment) return false;
  
  // Проверяем главную руку и дополнительную руку
  const mainhandItem = equipment.getEquipment(EquipmentSlot.Mainhand);
  const offhandItem = equipment.getEquipment(EquipmentSlot.Offhand);
  
  if (mainhandItem && mainhandItem.typeId === "minecraft:shield") return true;
  if (offhandItem && offhandItem.typeId === "minecraft:shield") return true;
  
  return false;
}

// Объединённая обработка события попадания пули
world.afterEvents.projectileHitEntity.subscribe(async (ev) => {
  const source = ev.source;
  const proj = ev.projectile;
  const projId = proj.typeId;
  const entity = ev.getEntityHit().entity;

  if (!source || !proj || !entity) return;

  // Проверяем, использует ли игрок щит
  if (isUsingShield(entity)) {
    return;
  }

  if (bulletConfig[projId]) {
    let damage = 0;
    if (source.isSneaking) {
      damage = getRandomSneakingDamage(projId);
    } else {
      damage = getRandomDamage(projId);
    }

    const baseDefense = calculateBaseDefense(entity);
    const baseReduction = Math.min(baseDefense * armorDefensePercentage, 80);
    const baseMultiplier = 1 - baseReduction / 100;
    let remainingDamage = damage * baseMultiplier;

    const projectileProtection = calculateProjectileProtection(entity);
    if (projectileProtection > 0) {
      const protectionMultiplier = 1 - projectileProtection / 100;
      remainingDamage *= protectionMultiplier;
    }

    // Применяем уменьшение урона от эффекта Стойкости
    const resistanceReduction = calculateResistanceReduction(entity);
    if (resistanceReduction > 0) {
      const resistanceMultiplier = 1 - resistanceReduction / 100;
      remainingDamage *= resistanceMultiplier;
    }

    // Наносим повреждение цели
    entity.applyDamage(remainingDamage, { cause: "override" });

    // Получаем здоровье пострадавшего объекта
    const health = entity.getComponent("minecraft:health")?.currentValue ?? null;

    // Отправляем командные эвенты игроку
    if (source instanceof Player && health !== null) {
      if (health > 0) {
        await source.runCommandAsync("event entity @s hitmarker");
      } else {
        await source.runCommandAsync("event entity @s hitmarker_kill");
      }
    }
  }
});