import { world, system } from "@minecraft/server";
export { damageAOE, sprintCollision }

// 玩家的技能

const airDropCooldowns = new Map();
const sprintCooldowns = new Map();
const cooldownDuration = 12 * 20;

system.afterEvents.scriptEventReceive.subscribe((event) => {
    const { id, sourceEntity: player } = event;

    if (!player || player.typeId !== 'minecraft:player') return;

    if (id === 'pm_m8:air_drop' && (player.hasTag(`cs_air_drop`) && (player.hasTag('combat_uniform') || player.hasTag('juggernaut') || player.hasTag('cyclone_suit') || player.hasTag('inferno_exoskeleton') || player.hasTag('pyroclasm')))) {
        const currentTime = system.currentTick;
        const lastAirDropTime = airDropCooldowns.get(player.id) || 0;
        const lastUse = currentTime - lastAirDropTime;

        if (lastUse < cooldownDuration) {
            const remainingTicks = cooldownDuration - lastUse;
            const remainingSeconds = Math.ceil(remainingTicks / 20);
            player.onScreenDisplay.setActionBar(`Air Drop Cooldown: ${remainingSeconds}s remaining`);
        } else {
            airDrop(player);
            player.onScreenDisplay.setActionBar("Skill: Air Drop");
            airDropCooldowns.set(player.id, currentTime);
        }
    }

    if (id === 'pm_m8:sprint_collision' && (player.hasTag(`cs_sprint_collision`) && (player.hasTag('combat_uniform') || player.hasTag('juggernaut') || player.hasTag('cyclone_suit') || player.hasTag('inferno_exoskeleton') || player.hasTag('pyroclasm')))) {
        const currentTime = system.currentTick;
        const lastSprintTime = sprintCooldowns.get(player.id) || 0;
        const lastUse = currentTime - lastSprintTime;

        if (lastUse < cooldownDuration) {
            const remainingTicks = cooldownDuration - lastUse;
            const remainingSeconds = Math.ceil(remainingTicks / 20);
            player.onScreenDisplay.setActionBar(`Sprint Cooldown: ${remainingSeconds}s remaining`);
        } else {
            sprintCollision(player);
            sprintCooldowns.set(player.id, currentTime);
        }
    }
});

function airDrop(player) {
    const view = player.getViewDirection();
    player.applyKnockback(view.x, view.z, 0, -3);
    player.runCommandAsync(`tag @s add pm_m8:air_drop`);
    player.runCommandAsync(`effect @s slow_falling 60 0 true`);

    const checkGroundInterval = system.runInterval(() => {
        if (player.isOnGround) {
            system.clearRun(checkGroundInterval);
            damageAOE(player, "pm_m8:air_drop", 10, 3, 3, 0.5);
            player.removeEffect("slow_falling");
            player.runCommandAsync(`tag @s remove pm_m8:air_drop`);
            player.runCommandAsync(`particle pm_m8:monster10_smoke_01`);
            player.runCommandAsync(`particle pm_m8:monster10_smoke_02`);
            player.runCommandAsync(`playsound random.explode @a[r=16] ~~~ 1 1.4`);
            player.runCommandAsync(`camerashake add @a[r=8] 0.5 0.4`);
        }
    });
}

function sprintCollision(player) {
    player.runCommandAsync(`tag @s add pm_m8:sprint`);
    const nearbyEntities = player.dimension.getEntities({
        location: player.location,
        maxDistance: 3,
        excludeTypes: ["minecraft:item", "minecraft:xp_orb", "minecraft:arrow", "minecraft:thrown_trident", "minecraft:snowball", "minecraft:ender_pearl", "minecraft:player"]
    });

    const totalDamage = 6;
    nearbyEntities.forEach(entity => {
        entity.runCommandAsync(`damage @s ${totalDamage} entity_attack entity @e[tag=pm_m8:sprint]`);
    });

    system.runTimeout(() => {
        player.runCommandAsync(`tag @s remove pm_m8:sprint`);
    }, 5 * 20);
}

function dynamicDamage(player) {
    const inventoryComponent = player.getComponent('minecraft:inventory');
    if (!inventoryComponent) {
        return 1;
    }

    const heldItem = inventoryComponent.container.getItem(player.selectedSlotIndex);
    let damage = 1;

    if (heldItem) {
        const enchantmentsComponent = heldItem.getComponent("minecraft:enchantable");
        if (enchantmentsComponent) {
            const sharpnessEnchantment = enchantmentsComponent.getEnchantment("sharpness");
            const sharpnessLevel = sharpnessEnchantment ? sharpnessEnchantment.level : 0;
            const impalingEnchantment = enchantmentsComponent.getEnchantment("impaling");
            const impalingLevel = impalingEnchantment ? impalingEnchantment.level : 0;
            damage += (impalingLevel + sharpnessLevel) * 1;
        }
    }
    const strengthEffect = player.getEffect("strength");
    if (strengthEffect) {
        const strengthLevel = strengthEffect.amplifier;
        damage += 3 * (strengthLevel + 1);
    }
    return damage;
}

function damageAOE(player, tag, baseDamage, radius, knockbackForce, knockbackY) {
    const playerDimension = player.dimension;
    const nearbyEntities = playerDimension.getEntities({
        location: player.location,
        maxDistance: radius,
        excludeTypes: ["minecraft:item", "minecraft:xp_orb", "minecraft:arrow", "minecraft:thrown_trident", "minecraft:snowball", "minecraft:ender_pearl"],
        excludeTags: [tag],
        excludeFamilies: [ "npc", "tool", "inanimate" ],
    });

    const additionalDamage = dynamicDamage(player);
    const totalDamage = Math.round((baseDamage + additionalDamage) * 1.5);

    nearbyEntities.forEach(entity => {
        entity.runCommand(`damage @s ${totalDamage} entity_attack entity @e[tag=${tag}]`);

        const directionX = entity.location.x - player.location.x;
        const directionZ = entity.location.z - player.location.z;
        entity.applyKnockback(directionX, directionZ, knockbackForce, knockbackY);
    });
}

world.afterEvents.entityHitEntity.subscribe((e) => {
    const damagingEntity = e.damagingEntity
    const hitEntity = e.hitEntity

    if (!damagingEntity.typeId == "minecraft:player") return;
    if (!damagingEntity.hasTag(`pm_m8:frost_active`) || !damagingEntity.hasTag(`inferno_exoskeleton`)) return;

    hitEntity.runCommandAsync(`effect @s slowness 8 1`);
})