import {
  ARMOR_EFFECT_STATS,
  DYNAMIC_PROPERTY,
  TAGS
}
from "./data.js"
import {
  system,
  world
}
from "@minecraft/server";
export const ARMOR_SET = {
  "4ks_wp:cryo": cryoArmorSet,
  "4ks_wp:flame": flameArmorSet,
  "4ks_wp:demonic": demonicArmorSet,
  "4ks_wp:divine": divineArmorSet,
  "4ks_wp:sculk": sculkArmorSet,
  "4ks_wp:dragon": dragonArmorSet,
  "4ks_wp:bedrock": bedrockArmorSet
}
export const ARMOR_SET_REMOVED = {
  "4ks_wp:cryo": cryoArmorRemoved,
  "4ks_wp:flame": flameArmorRemoved,
  "4ks_wp:demonic": demonicArmorRemoved,
  "4ks_wp:divine": divineArmorRemoved,
  "4ks_wp:sculk": sculkArmorRemoved,
  "4ks_wp:dragon": dragonArmorRemoved,
  "4ks_wp:bedrock": bedrockArmorRemoved
}
export const ON_HIT_TAGS = {}
ON_HIT_TAGS[TAGS.CRYO_ARMOR] = cryoArmorOnHit
ON_HIT_TAGS[TAGS.FLAME_ARMOR] = flameArmorOnHit
export const LOOP_TAGS_CHECK = {}
LOOP_TAGS_CHECK[TAGS.DIVINE_ARMOR] = divineArmorMainHand
LOOP_TAGS_CHECK[TAGS.DEMONIC_ARMOR] = demonicArmorMainHand
LOOP_TAGS_CHECK[TAGS.SCULK_ARMOR] = sculkXray

function sleep(tick) {
  return new Promise(resolve => {
    system.runTimeout(() => {
      resolve(tick)
    }, tick)
  })
}
async function demonicArmorMainHand(player) {
  const equippable = player.getComponent("minecraft:equippable");
  const mainhand = equippable?.getEquipment("Mainhand")?.typeId
  if (mainhand?.includes("_sword") || mainhand?.includes("_cutlass") || mainhand?.includes("_battleaxe") || mainhand?.includes("_club") || mainhand?.includes("_dagger") || mainhand?.includes("_gladius") || mainhand?.includes("_greatsword") || mainhand?.includes("_halberd") || mainhand?.includes("_khopesh") || mainhand?.includes("_mace") || mainhand?.includes("_mace") || mainhand?.includes("_spear") || mainhand?.includes("trident") || mainhand?.includes("_javelin")) {
    if (player.hasTag(TAGS.CUSTOM_MAIN_HAND_SWORD)) return
    player.runCommand(`/effect @s strength ${ARMOR_EFFECT_STATS.demonic_armor_sword_strength_duration} ${ARMOR_EFFECT_STATS.demonic_armor_sword_strength_level} ${ARMOR_EFFECT_STATS.demonic_armor_sword_strength_hide_effect}`)
    player.runCommand(`/effect @s speed ${ARMOR_EFFECT_STATS.demonic_armor_sword_speed_duration} ${ARMOR_EFFECT_STATS.demonic_armor_sword_speed_level} ${ARMOR_EFFECT_STATS.demonic_armor_sword_speed_hide_effect}`)
    player.runCommand(`/effect @s haste 0 0`)
    player.addTag(TAGS.CUSTOM_MAIN_HAND_SWORD)
    player.removeTag(TAGS.CUSTOM_MAIN_HAND_TOOLS)
  } else if ((mainhand?.includes("_pickaxe") || mainhand?.includes("_hoe") || mainhand?.includes("_axe") || mainhand?.includes("_shovel"))) {
    if (player.hasTag(TAGS.CUSTOM_MAIN_HAND_TOOLS)) return
    player.runCommand(`/effect @s strength 0 0`)
    player.runCommand(`/effect @s speed 0 0`)
    player.runCommand(`/effect @s haste ${ARMOR_EFFECT_STATS.demonic_armor_tools_haste_duration} ${ARMOR_EFFECT_STATS.demonic_armor_tools_haste_level} ${ARMOR_EFFECT_STATS.demonic_armor_tools_haste_hide_effect}`)
    player.addTag(TAGS.CUSTOM_MAIN_HAND_TOOLS)
    player.removeTag(TAGS.CUSTOM_MAIN_HAND_SWORD)
  } else if (player.hasTag(TAGS.CUSTOM_MAIN_HAND_SWORD)) {
    player.runCommand(`/effect @s strength 0 0`)
    player.runCommand(`/effect @s speed 0 0`)
    player.removeTag(TAGS.CUSTOM_MAIN_HAND_SWORD)
  } else if (player.hasTag(TAGS.CUSTOM_MAIN_HAND_TOOLS)) {
    player.runCommand(`/effect @s haste 0 0`)
    player.removeTag(TAGS.CUSTOM_MAIN_HAND_TOOLS)
  }
}
async function sculkXray(player) {
  if (player.isSneaking && !player.getDynamicProperty(DYNAMIC_PROPERTY.sculk_xray_scanning)) {
    const cooldownEndTick = player.getDynamicProperty(DYNAMIC_PROPERTY.sculk_delay) ?? 0;
    const currentDelayTick = Math.round((system.currentTick - cooldownEndTick) / 20)
    if (currentDelayTick < 25 && currentDelayTick >= 7) {
      const messageDelay = player.getDynamicProperty(DYNAMIC_PROPERTY.sculk_message_time) ?? 0;
      if (system.currentTick - messageDelay >= 20) {
        player.setDynamicProperty(DYNAMIC_PROPERTY.sculk_message_time, system.currentTick);
        player.runCommand(`/titleraw @s actionbar { "rawtext": [ { "translate": "4ks_wp:text.xray.scanning.cooldown", "with": ["${25 - currentDelayTick}"] } ] }`);
      }
      return
    }
    player.setDynamicProperty(DYNAMIC_PROPERTY.sculk_delay, system.currentTick);
    player.setDynamicProperty(DYNAMIC_PROPERTY.sculk_xray_scanning, true);
    const position = player.location;
    player.runCommand(`/tellraw @s { "rawtext": [ { "translate": "4ks_wp:text.xray.scanning" } ] }`);
    player.runCommand(`/playsound beacon.activate @s ~~~ 1.0 5.0`)
    const maxRadius = 25;
    let count = 0;
    for (let radius = 1; radius <= maxRadius; radius++) {
      for (let x = -radius; x <= radius; x++) {
        for (let y = -radius; y <= radius; y++) {
          for (let z = -radius; z <= radius; z++) {
            // Skip blocks inside the previous radius
            if (Math.abs(x) < radius && Math.abs(y) < radius && Math.abs(z) < radius) continue;
            const blockPosition = {
              x: position.x + x,
              y: position.y + y,
              z: position.z + z
            };
            const block = player.dimension.getBlock(blockPosition);
            count++;
            if (!block) continue;
            // Delay processing every 1000 blocks to prevent lag
            if (count % 1000 === 0) {
              await sleep(1);
            }
            const foundPosition = {
              x: block.location.x,
              y: block.location.y,
              z: block.location.z
            };
            if (block.permutation.matches("minecraft:diamond_ore") || block.permutation.matches("minecraft:deepslate_diamond_ore") || block.permutation.matches("minecraft:ancient_debris") || block.permutation.matches("mob_spawner")) {
              player.runCommand(`/summon 4ks_wp:xray_entity ${foundPosition.x} ${foundPosition.y} ${foundPosition.z}`);
            } else if (block.permutation.matches("minecraft:chest") || block.permutation.matches("minecraft:trapped_chest")) {
              const direction = block.permutation.getState("minecraft:cardinal_direction");
              const rotation = direction === "north" ? -180 : direction === "south" ? 0 : direction === "west" ? 90 : -90;
              player.runCommand(`/summon 4ks_wp:xray_entity ${foundPosition.x} ${foundPosition.y} ${foundPosition.z} ${rotation}`);
            }
          }
        }
      }
    }
    player.runCommand(`/tellraw @s { "rawtext": [ { "translate": "4ks_wp:xray.scanning.done" } ] }`);
    player.runCommand("/playsound random.levelup @s");
    player.setDynamicProperty(DYNAMIC_PROPERTY.sculk_xray_scanning, false);
  }
}
async function dragonArmorSet(player) {
  player.addTag(TAGS.DRAGON_ARMOR)
  player.runCommand("/effect @s resistance infinite 0 true")
  player.runCommand("/effect @s strength infinite 0 true")
}
async function dragonArmorRemoved(player) {
  player.removeTag(TAGS.DRAGON_ARMOR)
  player.runCommand("/effect @s resistance 0 0 true")
  player.runCommand("/effect @s strength 0 0 true")
}
async function bedrockArmorSet(player) {
  player.addTag(TAGS.BEDROCK_ARMOR)
}
async function bedrockArmorRemoved(player) {
  player.removeTag(TAGS.BEDROCK_ARMOR)
}
async function sculkArmorSet(player) {
  player.addTag(TAGS.SCULK_ARMOR)
  player.runCommand("/effect @s strength infinite 1 true")
  player.runCommand("/effect @s resistance infinite 1 true")
}
async function sculkArmorRemoved(player) {
  player.removeTag(TAGS.SCULK_ARMOR)
  player.runCommand("/effect @s strength 0 0 true")
  player.runCommand("/effect @s resistance 0 0 true")
}
async function demonicArmorSet(player) {
  player.addTag(TAGS.DEMONIC_ARMOR)
  player.runCommand("/effect @s resistance infinite 2 true")
}
async function demonicArmorRemoved(player) {
  player.removeTag(TAGS.DEMONIC_ARMOR)
  player.runCommand("/effect @s resistance 0 0 true")
  player.runCommand(`/effect @s strength 0 0`)
  if (!player.hasTag("4ksspwp") && !player.hasTag("4ksscutlass")) player.runCommand(`/effect @s speed 0 0`)
  player.runCommand(`/effect @s haste 0 0`)
  player.runCommand("/effect @s resistance 0 0 true")
}
async function divineArmorSet(player) {
  player.addTag(TAGS.DIVINE_ARMOR)
  player.runCommand("/effect @s resistance infinite 1 true")
}
async function divineArmorRemoved(player) {
  player.removeTag(TAGS.DIVINE_ARMOR)
  player.runCommand("/effect @s resistance 0 0 true")
  player.runCommand(`/effect @s strength 0 0`)
  if (!player.hasTag("4ksspwp") && !player.hasTag("4ksscutlass")) player.runCommand(`/effect @s speed 0 0`)
  player.runCommand(`/effect @s haste 0 0`)
  player.runCommand("/effect @s resistance 0 0 true")
}
async function divineArmorMainHand(player) {
  const equippable = player.getComponent("minecraft:equippable");
  const mainhand = equippable?.getEquipment("Mainhand")?.typeId
  if (mainhand?.includes("_sword") || mainhand?.includes("_cutlass") || mainhand?.includes("_battleaxe") || mainhand?.includes("_club") || mainhand?.includes("_dagger") || mainhand?.includes("_gladius") || mainhand?.includes("_greatsword") || mainhand?.includes("_halberd") || mainhand?.includes("_khopesh") || mainhand?.includes("_mace") || mainhand?.includes("_mace") || mainhand?.includes("_spear") || mainhand?.includes("trident") || mainhand?.includes("_javelin")) {
    if (player.hasTag(TAGS.CUSTOM_MAIN_HAND_SWORD)) return
    player.runCommand(`/effect @s strength ${ARMOR_EFFECT_STATS.divine_armor_sword_strength_duration} ${ARMOR_EFFECT_STATS.divine_armor_sword_strength_level} ${ARMOR_EFFECT_STATS.divine_armor_sword_strength_hide_effect}`)
    player.runCommand(`/effect @s speed ${ARMOR_EFFECT_STATS.divine_armor_sword_speed_duration} ${ARMOR_EFFECT_STATS.divine_armor_sword_speed_level} ${ARMOR_EFFECT_STATS.divine_armor_sword_speed_hide_effect}`)
    player.runCommand(`/effect @s haste 0 0`)
    player.addTag(TAGS.CUSTOM_MAIN_HAND_SWORD)
    player.removeTag(TAGS.CUSTOM_MAIN_HAND_TOOLS)
  } else if ((mainhand?.includes("_pickaxe") || mainhand?.includes("_hoe") || mainhand?.includes("_axe") || mainhand?.includes("_shovel"))) {
    if (player.hasTag(TAGS.CUSTOM_MAIN_HAND_TOOLS)) return
    player.runCommand(`/effect @s strength 0 0`)
    player.runCommand(`/effect @s speed 0 0`)
    player.runCommand(`/effect @s haste ${ARMOR_EFFECT_STATS.divine_armor_tools_haste_duration} ${ARMOR_EFFECT_STATS.divine_armor_tools_haste_level} ${ARMOR_EFFECT_STATS.divine_armor_tools_haste_hide_effect}`)
    player.addTag(TAGS.CUSTOM_MAIN_HAND_TOOLS)
    player.removeTag(TAGS.CUSTOM_MAIN_HAND_SWORD)
  } else if (player.hasTag(TAGS.CUSTOM_MAIN_HAND_SWORD)) {
    player.runCommand(`/effect @s strength 0 0`)
    player.runCommand(`/effect @s speed 0 0`)
    player.removeTag(TAGS.CUSTOM_MAIN_HAND_SWORD)
  } else if (player.hasTag(TAGS.CUSTOM_MAIN_HAND_TOOLS)) {
    player.runCommand(`/effect @s haste 0 0`)
    player.removeTag(TAGS.CUSTOM_MAIN_HAND_TOOLS)
  }
}
async function cryoArmorSet(player) {
  player.runCommand(`/effect @s water_breathing ${ARMOR_EFFECT_STATS.cryo_armor_water_breathing_duration} ${ARMOR_EFFECT_STATS.cryo_armor_water_breathing_level} ${ARMOR_EFFECT_STATS.cryo_armor_water_breathing_hide_particle_effect}`)
  player.addTag(TAGS.CRYO_ARMOR)
}
async function cryoArmorRemoved(player) {
  player.runCommand(`/effect @s water_breathing 0 0 true`)
  player.removeTag(TAGS.CRYO_ARMOR)
}
async function cryoArmorOnHit(player, victim) {
  player.runCommand(`/effect @s slowness ${ARMOR_EFFECT_STATS.cryo_armor_slowness_duration} ${ARMOR_EFFECT_STATS.cryo_armor_slowness_level} ${ARMOR_EFFECT_STATS.cryo_armor_slowness_hide_particle_effect}`)
}
async function flameArmorSet(player) {
  player.runCommand(`/effect @s fire_resistance ${ARMOR_EFFECT_STATS.flame_armor_fire_resistance_duration} ${ARMOR_EFFECT_STATS.flame_armor_fire_resistance_level} ${ARMOR_EFFECT_STATS.flame_armor_fire_resistance_hide_particle_effect}`)
  player.addTag(TAGS.FLAME_ARMOR)
}
async function flameArmorRemoved(player) {
  player.runCommand(`/effect @s fire_resistance 0 0 true`)
  player.removeTag(TAGS.FLAME_ARMOR)
}
async function flameArmorOnHit(player, victim) {
  player.setOnFire(5, true)
}