import { world, EquipmentSlot, system } from "@minecraft/server";
import * as inv_utils from "./inventory_utils.js";
import * as game from "./game.js";
import * as utils from "./utils.js";

const ARMOR_EFFECTS = {
    "tcs_cwp:fire_helmet": {
        slot: EquipmentSlot.Head,
        effect: { type: "fire_resistance", amplifier: 0 },
        property: "tcs_cwp_has_fire_helmet",
        effectGiven: "tcs_fire_helmet_effect_given"
    },
    "tcs_cwp:snow_helmet": {
        slot: EquipmentSlot.Head,
        effect: { type: "fire_resistance", amplifier: 0 },
        property: "tcs_cwp_has_snow_helmet",
        effectGiven: "tcs_snow_helmet_effect_given"
    },
    "tcs_cwp:phantom_helmet": {
        slot: EquipmentSlot.Head,
        effect: { type: "night_vision", amplifier: 0 },
        property: "tcs_cwp_has_phantom_helmet",
        effectGiven: "tcs_phantom_helmet_effect_given"
    },
    "tcs_cwp:phantom_chestplate": {
        slot: EquipmentSlot.Chest,
        effect: { type: "resistance", amplifier: 0 },
        property: "tcs_cwp_has_phantom_chestplate",
        effectGiven: "tcs_phantom_chestplate_effect_given"
    },
    "tcs_cwp:phantom_leggings": {
        slot: EquipmentSlot.Legs,
        effect: { type: "jump_boost", amplifier: 0 },
        property: "tcs_cwp_has_phantom_leggings",
        effectGiven: "tcs_phantom_leggings_effect_given"
    },
    "tcs_cwp:spider_boots": {
        slot: EquipmentSlot.Feet,
        effect: { type: "jump_boost", amplifier: 0 },
        property: "tcs_cwp_has_spider_boots",
        effectGiven: "tcs_spider_boots_effect_given"
    },
    "tcs_cwp:armadillo_helmet": {
        slot: EquipmentSlot.Head,
        effect: { type: "absorption", amplifier: 0 },
        property: "tcs_cwp_has_armadillo_helmet",
        effectGiven: "tcs_armadilo_helmet_effect_given"
    },
    "tcs_cwp:armadillo_chestplate": {
        slot: EquipmentSlot.Chest,
        effect: { type: "resistance", amplifier: 0 },
        property: "tcs_cwp_has_armadillo_chestplate",
        effectGiven: "tcs_armadilo_chestplate_effect_given"
    },
    "tcs_cwp:armadillo_leggings": {
        slot: EquipmentSlot.Legs,
        effect: { type: "health_boost", amplifier: 0 },
        property: "tcs_cwp_has_armadillo_leggings",
        effectGiven: "tcs_armadilo_leggings_effect_given"
    },
    "tcs_cwp:armadillo_boots": {
        slot: EquipmentSlot.Feet,
        effect: { type: "slowness", amplifier: 0 },
        property: "tcs_cwp_has_armadillo_boots",
        effectGiven: "tcs_armadilo_boots_effect_given"
    }
};

const ARMOR_SETS = {
    FIRE: {
        items: ["tcs_cwp:fire_helmet","tcs_cwp:fire_chestplate","tcs_cwp:fire_leggings","tcs_cwp:fire_boots"],
        prompt: "§c§lSPECIAL ABILITY: §6Fire Blast\n§cACTIVATION: §6Hold Sneak"
    },
    SNOW: {
        items: ["tcs_cwp:snow_helmet","tcs_cwp:snow_chestplate","tcs_cwp:snow_leggings","tcs_cwp:snow_boots"],
        prompt: "§c§lSPECIAL ABILITY: §9Snow Storm\n§cACTIVATION: §9Hold Sneak"
    },
    PHANTOM: {
        items: ["tcs_cwp:phantom_helmet","tcs_cwp:phantom_chestplate","tcs_cwp:phantom_leggings","tcs_cwp:phantom_boots"],
        prompt: "§c§lSPECIAL ABILITY: §9Phantom Flight\n§cACTIVATION: §9Hold Jump"
    },
    SPIDER: {
        items: ["tcs_cwp:spider_helmet","tcs_cwp:spider_chestplate","tcs_cwp:spider_leggings","tcs_cwp:spider_boots"],
        prompt: "§c§lSPECIAL ABILITY: §aCobweb Trap\n§cACTIVATION: §aPunch Enemies"
    },
    ARMADILO: {
        items: ["tcs_cwp:armadillo_helmet","tcs_cwp:armadillo_chestplate","tcs_cwp:armadillo_leggings","tcs_cwp:armadillo_boots"],
        prompt: "§c§lSPECIAL ABILITY: §nArmadillo Shield\n§cACTIVATION: §nHold Sneak"
    },
};

function isWearingFullArmor(player, armorType) {
    const armorSet = ARMOR_SETS[armorType];
    if (!armorSet) return false;
    const items = Array.isArray(armorSet) ? armorSet : armorSet.items;
    if (!items) return false;
    return (
        inv_utils.isWearingItem(player, EquipmentSlot.Head, items[0]) &&
        inv_utils.isWearingItem(player, EquipmentSlot.Chest, items[1]) &&
        inv_utils.isWearingItem(player, EquipmentSlot.Legs, items[2]) &&
        inv_utils.isWearingItem(player, EquipmentSlot.Feet, items[3])
    );
}

function applyPhantomFlightEffects(player) {
    const isFlightActive = player.getDynamicProperty("tcs_phantom_flight_active");
    const isOnGround =
        player.isOnGround !== undefined
            ? player.isOnGround
            : player.getComponent("minecraft:movement")?.isOnGround;
    if (isFlightActive) {
        const lev = player.getEffect("levitation");
        if (!lev || lev.amplifier < 2) {
            player.addEffect("levitation", 10, { amplifier: 2, showParticles: false });
        }
    } else if (!isOnGround) {
        const sf = player.getEffect("slow_falling");
        if (!sf) {
            player.addEffect("slow_falling", 10, { amplifier: 0, showParticles: false });
        }
    }
}

export function onPlayerButtonInput(event) {
    const player = event.player;
    if (event.button === "Sneak") {
        if (event.newButtonState === "Pressed") {
            // Fire
            if (isWearingFullArmor(player, 'FIRE')) {
                player.setDynamicProperty("tcs_sneak_holding_fire", true);
                try {
                    player.playSound("tcs_cwp:fire_armor_activated");
                    player.setDynamicProperty("tcs_fire_sound_last_tick", system.currentTick);
                } catch (e) { }
            }
            // Snow
            if (isWearingFullArmor(player, 'SNOW')) {
                player.setDynamicProperty("tcs_sneak_holding_snow", true);
                try {
                    player.playSound("tcs_cwp:snow_armor_activated");
                    player.setDynamicProperty("tcs_snow_sound_last_tick", system.currentTick);
                } catch (e) { }
            }
            // Armadilo
            if (isWearingFullArmor(player, 'ARMADILO')) {
                player.setDynamicProperty("tcs_sneak_holding_armadillo", true);
                try {
                    player.playSound("tcs_cwp:armadillo_armor_activated");
                    player.setDynamicProperty("tcs_armadillo_sound_last_tick", system.currentTick);
                } catch (e) { }
            }
        } else if (event.newButtonState === "Released") {
            // Reset all sneak holding states
            const wasHoldingFire = player.getDynamicProperty("tcs_sneak_holding_fire");
            const wasHoldingSnow = player.getDynamicProperty("tcs_sneak_holding_snow");
            const wasHoldingArmadillo = player.getDynamicProperty("tcs_sneak_holding_armadillo");
            player.setDynamicProperty("tcs_sneak_holding_fire", false);
            player.setDynamicProperty("tcs_sneak_holding_snow", false);
            player.setDynamicProperty("tcs_sneak_holding_armadillo", false);
            if (wasHoldingFire || wasHoldingSnow || wasHoldingArmadillo) {
            }
        }
    }
    if (event.button === "Jump") {
        if (event.newButtonState === "Pressed") {
            if (isWearingFullArmor(player, 'PHANTOM')) {
                player.setDynamicProperty("tcs_phantom_flight_active", true);
            }
        } else if (event.newButtonState === "Released") {
            player.setDynamicProperty("tcs_phantom_flight_active", false);
        }
    }
}

function activateFireSpecial(player) {
    const entities = utils.getMobsInRadius(player.dimension, player.location, 7);
    for (const entity of entities) {
        if (entity.id === player.id) continue;
        try {
            entity.applyDamage(2);
            entity.addEffect("slowness", 60, { amplifier: 1, showParticles: true });
            entity.setOnFire(1, true);
        } catch (e) { }
    }
    return true;
}
function activateSnowSpecial(player) {
    const entities = utils.getMobsInRadius(player.dimension, player.location, 5);
    for (const entity of entities) {
        if (entity.id === player.id) continue;
        try {
            entity.applyDamage(2);
            entity.addEffect("slowness", 60, { amplifier: 1, showParticles: true });
        } catch (e) { }
    }
    return true;
}

function activateArmadiloSpecial(player) {
    try {
        player.addEffect("resistance", 100, { amplifier: 2, showParticles: false });
    } catch (e) { }
    return true;
}


export function onTick() {
    for (const player of world.getAllPlayers()) {
        handleArmorSpecialsTick(player);
        handleSpiderHelmetLightTick(player);
        for (const [armorId, armor] of Object.entries(ARMOR_EFFECTS)) {
            if (armor.effect) handleArmorPiece(player, { ...armor, id: armorId });
        }
        handleFireBootsParticlesTick(player);
        handlePhantomBootsSlowfallTick(player);
        handleSnowBootsFootstepsTick(player);
        // Apply Phantom flight effects per tick while wearing the set
        if (isWearingFullArmor(player, 'PHANTOM')) {
            applyPhantomFlightEffects(player);
        } else {
            player.setDynamicProperty("tcs_phantom_flight_active", false);
        }
        // Handle continuous sneak specials (Fire, Snow, Armadillo)
        handleContinuousSneakSpecials(player);
    }
}

function handleArmorSpecialsTick(player) {
    // Fire one-time prompts on full set transitions
    const previousFullSet = player.getDynamicProperty("tcs_cwp_full_set") || "";
    const currentFullSet = getCurrentFullArmorType(player);
    if (currentFullSet !== previousFullSet) {
        player.setDynamicProperty("tcs_cwp_full_set", currentFullSet);
        const prompt = ARMOR_SETS[currentFullSet]?.prompt;
        if (prompt) utils.actionBarTimed(player, "@s", prompt, 100);
    }
}

function getCurrentFullArmorType(player) {
    if (isWearingFullArmor(player, 'FIRE')) return 'FIRE';
    if (isWearingFullArmor(player, 'SNOW')) return 'SNOW';
    if (isWearingFullArmor(player, 'PHANTOM')) return 'PHANTOM';
    if (isWearingFullArmor(player, 'SPIDER')) return 'SPIDER';
    if (isWearingFullArmor(player, 'ARMADILO')) return 'ARMADILO';
    return "";
}

function handleSpiderHelmetLightTick(player) {
    if (inv_utils.isWearingItem(player, EquipmentSlot.Head, "tcs_cwp:spider_helmet")) {
        const pos = {
            x: Math.floor(player.location.x),
            y: Math.floor(player.location.y) + 1.6,
            z: Math.floor(player.location.z),
        };
        const hadPos = player.getDynamicProperty("tcs_cwp_light_block_active");
        const last = hadPos
            ? {
                  x: player.getDynamicProperty("tcs_spider_light_x"),
                  y: player.getDynamicProperty("tcs_spider_light_y"),
                  z: player.getDynamicProperty("tcs_spider_light_z"),
              }
            : undefined;
        if (
            last &&
            (last.x !== pos.x || last.y !== pos.y || last.z !== pos.z)
        ) {
            player.dimension.runCommandAsync(
                `fill ${last.x} ${last.y} ${last.z} ${last.x} ${last.y} ${last.z} air replace light_block["block_light_level"=15]`
            );
        }
        player.dimension.runCommandAsync(
            `fill ${pos.x} ${pos.y} ${pos.z} ${pos.x} ${pos.y} ${pos.z} light_block["block_light_level"=15] replace air`
        );
        player.setDynamicProperty("tcs_cwp_light_block_active", true);
        player.setDynamicProperty("tcs_spider_light_x", pos.x);
        player.setDynamicProperty("tcs_spider_light_y", pos.y);
        player.setDynamicProperty("tcs_spider_light_z", pos.z);
    } else {
        const hadPos = player.getDynamicProperty("tcs_cwp_light_block_active");
        if (hadPos) {
            const lastX = player.getDynamicProperty("tcs_spider_light_x");
            const lastY = player.getDynamicProperty("tcs_spider_light_y");
            const lastZ = player.getDynamicProperty("tcs_spider_light_z");
            player.dimension.runCommandAsync(
                `setblock ${lastX} ${lastY} ${lastZ} air replace`
            );
            player.setDynamicProperty("tcs_cwp_light_block_active", false);
        }
    }
}

function handleFireBootsParticlesTick(player) {
    if (!inv_utils.isWearingItem(player, EquipmentSlot.Feet, "tcs_cwp:fire_boots")) return;
    const currentTick = system.currentTick;
    const lastTick = player.getDynamicProperty("tcs_fire_boots_particle_tick") || 0;
    if (currentTick - lastTick <= 60) return;
    const pos = {
        x: player.location.x,
        y: player.location.y + 1,
        z: player.location.z,
    };
    // player.dimension.spawnParticle(
    //     "tcs_cwp:amethyst_staff_hit",
    //     pos,
    //     undefined
    // );
    player.setDynamicProperty("tcs_fire_boots_particle_tick", currentTick);
}

function handlePhantomBootsSlowfallTick(player) {
    if (!inv_utils.isWearingItem(player, EquipmentSlot.Feet, "tcs_cwp:phantom_boots")) return;
    const vel = player.getVelocity ? player.getVelocity() : player.velocity;
    const currentTick = system.currentTick;
    if (!(vel && vel.y > 0.15)) return;
    const lastTick = player.getDynamicProperty("tcs_cwp_phantom_boots_cooldown_tick") || 0;
    if (currentTick - lastTick <= 100) return;
    player.addEffect("slow_falling", 60, {
        amplifier: 0,
        showParticles: false,
    });
    player.setDynamicProperty("tcs_cwp_phantom_boots_cooldown_tick", currentTick);
}

function handleSnowBootsFootstepsTick(player) {
    if (!inv_utils.isWearingItem(player, EquipmentSlot.Feet, "tcs_cwp:snow_boots")) return;
    const currentTick = system.currentTick;
    const lastTick = player.getDynamicProperty("tcs_cwp_snow_boots_particle_tick") || 0;
    if (currentTick - lastTick <= 60) return;
    const pos = {
        x: player.location.x,
        y: player.location.y,
        z: player.location.z,
    };
    // player.dimension.spawnParticle(
    //     "tcs_cwp:amethyst_staff_hit",
    //     pos,
    //     undefined
    // );
    player.setDynamicProperty("tcs_cwp_snow_boots_particle_tick", currentTick);
}

function handleContinuousSneakSpecials(player) {
    const currentTick = system.currentTick;
    const INTERVAL_TICKS = 20; 
    const SOUND_INTERVAL_TICKS = 100; 
    
    // Fire special
    if (player.getDynamicProperty("tcs_sneak_holding_fire") && isWearingFullArmor(player, 'FIRE')) {
        const lastTick = player.getDynamicProperty("tcs_fire_special_last_tick") || 0;
        if (currentTick - lastTick >= INTERVAL_TICKS) {
            activateFireSpecial(player);
            player.setDynamicProperty("tcs_fire_special_last_tick", currentTick);
        }
        const lastSoundTick = player.getDynamicProperty("tcs_fire_sound_last_tick") || 0;
        if (currentTick - lastSoundTick >= SOUND_INTERVAL_TICKS) {
            try {
                player.playSound("tcs_cwp:fire_armor_ambient");
                player.setDynamicProperty("tcs_fire_sound_last_tick", currentTick);
            } catch (e) { }
        }
    } else {
        player.setDynamicProperty("tcs_fire_special_last_tick", 0);
        player.setDynamicProperty("tcs_fire_sound_last_tick", 0);
    }
    
    // Snow special
    if (player.getDynamicProperty("tcs_sneak_holding_snow") && isWearingFullArmor(player, 'SNOW')) {
        const lastTick = player.getDynamicProperty("tcs_snow_special_last_tick") || 0;
        if (currentTick - lastTick >= INTERVAL_TICKS) {
            activateSnowSpecial(player);
            player.setDynamicProperty("tcs_snow_special_last_tick", currentTick);
        }
        const lastSoundTick = player.getDynamicProperty("tcs_snow_sound_last_tick") || 0;
        if (currentTick - lastSoundTick >= SOUND_INTERVAL_TICKS) {
            try {
                player.playSound("tcs_cwp:snow_armor_activated");
                player.setDynamicProperty("tcs_snow_sound_last_tick", currentTick);
            } catch (e) { }
        }
    } else {
        player.setDynamicProperty("tcs_snow_special_last_tick", 0);
        player.setDynamicProperty("tcs_snow_sound_last_tick", 0);
    }
    
    // Armadillo special
    if (player.getDynamicProperty("tcs_sneak_holding_armadillo") && isWearingFullArmor(player, 'ARMADILO')) {
        const lastTick = player.getDynamicProperty("tcs_armadillo_special_last_tick") || 0;
        if (currentTick - lastTick >= INTERVAL_TICKS) {
            activateArmadiloSpecial(player);
            player.setDynamicProperty("tcs_armadillo_special_last_tick", currentTick);
        }
        const lastSoundTick = player.getDynamicProperty("tcs_armadillo_sound_last_tick") || 0;
        if (currentTick - lastSoundTick >= SOUND_INTERVAL_TICKS) {
            try {
                //player.playSound("tcs_cwp:armadillo_armor_ambient");
                player.setDynamicProperty("tcs_armadillo_sound_last_tick", currentTick);
            } catch (e) { }
        }
    } else {
        player.setDynamicProperty("tcs_armadillo_special_last_tick", 0);
        player.setDynamicProperty("tcs_armadillo_sound_last_tick", 0);
    }
}

export function onEntityHurt(event) {
    const attacker = event.damageSource?.damagingEntity;
    const target = event.hurtEntity;
    if (!target) return;

    // Spider Leather Chestplate: Poison 1
    if (
        attacker &&
        attacker.typeId === "minecraft:player" &&
        inv_utils.isWearingItem(attacker, EquipmentSlot.Chest, "tcs_cwp:spider_chestplate")
    ) {
        const equippable = attacker.getComponent("minecraft:equippable");
        const heldItem = equippable?.getEquipment(EquipmentSlot.Mainhand);
        if (!heldItem) {
            target.addEffect("poison", 40, { amplifier: 0, showParticles: true });
        }
    }

    // Snow Chestplate: Slowness 1
    if (
        attacker &&
        attacker.typeId === "minecraft:player" &&
        inv_utils.isWearingItem(attacker, EquipmentSlot.Chest, "tcs_cwp:snow_chestplate")
    ) {
        const equippable = attacker.getComponent("minecraft:equippable");
        const heldItem = equippable?.getEquipment(EquipmentSlot.Mainhand);
        if (!heldItem) {
            target.addEffect("slowness", 40, { amplifier: 0, showParticles: true });
        }
    }

    // Spider Leather Full Set Bonus: Web Attacks
    if (
        attacker &&
        attacker.typeId === "minecraft:player" &&
        isWearingFullArmor(attacker, 'SPIDER')
    ) {
        const pos = {
            x: Math.floor(target.location.x),
            y: Math.floor(target.location.y),
            z: Math.floor(target.location.z),
        };
        target.dimension.runCommandAsync(
            `setblock ${pos.x} ${pos.y} ${pos.z} web replace`
        );
        // Check particle cooldown (20 ticks)
        const currentTick = system.currentTick;
        const PARTICLE_COOLDOWN = 20;
        const lastParticleTick = attacker.getDynamicProperty("tcs_cwp:spider_crawling_last_particle_tick");
        const canShowParticles = (lastParticleTick === undefined || (currentTick - lastParticleTick >= PARTICLE_COOLDOWN));
        
        if (canShowParticles) {
            try {
                target.dimension.spawnParticle(
                    "tcs_cwp:on_hit_spider_crawling",
                    target.location
                );
                attacker.setDynamicProperty("tcs_cwp:spider_crawling_last_particle_tick", currentTick);
            } catch (e) { }
        }
    }

    // Spider Leather Leggings: Minor Poison Resistance
    if (
        target.typeId === "minecraft:player" &&
        inv_utils.isWearingItem(target, EquipmentSlot.Legs, "tcs_cwp:spider_leggings")
    ) {
        if (event.damageSource && event.damageSource.cause === "magic") {
            const healthComp = target.getComponent("minecraft:health");
            if (healthComp && healthComp.currentValue > 0) {
                const maxHealth = healthComp.defaultValue ?? healthComp.value;
                const newHealth = Math.min(healthComp.currentValue + 2, maxHealth);
                healthComp.setCurrentValue(newHealth);
            }
        }
    }

    // Snow Boots: Freeze Protection
    if (
        target.typeId === "minecraft:player" &&
        inv_utils.isWearingItem(target, EquipmentSlot.Feet, "tcs_cwp:snow_boots")
    ) {
        if (event.damageSource && event.damageSource.cause === "freezing") {
            const healthComp = target.getComponent("minecraft:health");
            if (healthComp && healthComp.currentValue > 0) {
                const maxHealth = healthComp.defaultValue ?? healthComp.value;
                const newHealth = Math.min(healthComp.currentValue + 2, maxHealth);
                healthComp.setCurrentValue(newHealth);
            }
        }
    }

    // Snow Leggings: Icy Shield
    if (inv_utils.isWearingItem(target, EquipmentSlot.Legs, "tcs_cwp:snow_leggings")) {
        if (attacker && attacker.addEffect) {
            attacker.addEffect("slowness", 40, { amplifier: 0, showParticles: true });
        }
    }

    // Fire chestplate: Firey Fists
    if (
        attacker &&
        attacker.typeId === "minecraft:player" &&
        inv_utils.isWearingItem(attacker, EquipmentSlot.Chest, "tcs_cwp:fire_chestplate")
    ) {
        const equippable = attacker.getComponent("minecraft:equippable");
        const heldItem = equippable?.getEquipment(EquipmentSlot.Mainhand);
        if (!heldItem) {
            try {
                target.setOnFire(2, true);
            } catch (e) { }
        }
    }

    // Fire leggings
    if (inv_utils.isWearingItem(target, EquipmentSlot.Legs, "tcs_cwp:fire_leggings")) {
        if (attacker) {
            try {
                attacker.setOnFire(2, true);
            } catch (e) { }
        }
    }
}

function handleArmorPiece(player, armor) {
    const hadPiece = player.getDynamicProperty(armor.property);
    const hasPiece = inv_utils.isWearingItem(player, armor.slot, armor.id);
    const effectPresent = hasEffect(player, armor.effect);
    const effectGiven = player.getDynamicProperty(armor.effectGiven);

    if (!hasPiece) {
        if (hadPiece && effectPresent && effectGiven) {
            removeEffect(player, armor.effect);
        }
        player.setDynamicProperty(armor.property, false);
        player.setDynamicProperty(armor.effectGiven, false);
        return false;
    }
    player.setDynamicProperty(armor.property, true);
    if (!effectPresent) {
        applyEffect(player, armor.effect);
        player.setDynamicProperty(armor.effectGiven, true);
    }
    return true;
}

function hasEffect(player, effect) {
    const playerEffect = player.getEffect(effect.type);
    if (!playerEffect) return false;
    if (playerEffect.amplifier < effect.amplifier) return false;
    return true;
}

function applyEffect(player, effect) {
    player.addEffect(effect.type, 9999999, {
        amplifier: effect.amplifier,
        showParticles: false,
    });
}

function removeEffect(player, effect) {
    player.removeEffect(effect.type);
}
