/*console.warn(`Dummy Minigame Script Loaded`);*/
import {
    world,
    system
} from "@minecraft/server";

world.afterEvents.entityDie.subscribe((e) => {
    const player = e.deadEntity;
    const damagingEntity = e.damageSource?.damagingEntity;

    if (player.typeId !== "minecraft:player" || damagingEntity?.typeId !== "aria_ah:chicken") return;

    resetDummy(damagingEntity);
});


system.afterEvents.scriptEventReceive.subscribe((e) => {
    if (!e.sourceEntity || e.sourceEntity?.typeId !== "aria_ah:chicken") return;

    if (e.id === "aria_ah:check_for_target") {
        const nearestTarget = e.sourceEntity.dimension.getPlayers({
            location: e.sourceEntity.location,
            maxDistance: 3,
            closest: 1
        }).filter(t => t.getGameMode() !== "creative")[0];

        if (nearestTarget) {
            let isTargetAvailable = true;

            e.sourceEntity.dimension.getEntities().forEach(entity => {
                if (entity.getDynamicProperty("dummy2Target") === nearestTarget.name) {
                    isTargetAvailable = false;
                }
            });

            if (isTargetAvailable) {
                e.sourceEntity.setDynamicProperty("dummy2Target", nearestTarget.name);
                e.sourceEntity.setDynamicProperty("miniGameState");
                e.sourceEntity.triggerEvent("aria:is_on_minigame");
            }
        }
    } else if (e.id === "aria_ah:minigame") {
        handleMinigame(e.sourceEntity);
    } else if (e.id === "aria_ah:clear_target") { // new scriptevent to clean the dynamic property.     
        e.sourceEntity.clearDynamicProperties();
        e.sourceEntity.dimension.runCommand('say script reset target')
    }
});



let damageDelay = 40;

function handleMinigame(dummy) {
    const actions = ["jump", "sneak", "lookGesture", "lookGestureHorizontal"];
    const targetName = dummy.getDynamicProperty("dummy2Target") || "none";

    const dimension = dummy.dimension;
    const player = dimension.getPlayers({
        name: targetName
    })[0];

    if (!player) {
        dummy.setDynamicProperty("dummy2Target", "none");
        resetDummy(dummy);
        return;
    }

    damageDelay--;
    if (damageDelay === 0) {
        player.applyDamage(1, {
            cause: "entityAttack",
            damagingEntity: dummy
        });
        damageDelay = 10;
    }

    player.addEffect("slowness", 15, {
        amplifier: 3,
        showParticles: false
    });
    player.addEffect("weakness", 15, {
        amplifier: 255,
        showParticles: false
    });
    player.addEffect("darkness", 15, {
        amplifier: 2,
        showParticles: false
    });

    dummy.runCommand(`execute as @s at @e[type=player,name="${player.name}",c=1] rotated ~ 0 run tp @s ^^0.1^ facing @e[type=player,name="${player.name}",c=1]`);

    let state = dummy.getDynamicProperty("miniGameState");
    if (!state) {
        state = initializeMinigame(player, actions);
    } else {
        state = JSON.parse(state);
    }

    processMiniGameState(player, dummy, state, actions);
    dummy.setDynamicProperty("miniGameState", JSON.stringify(state));
}

function initializeMinigame(player, actions) {
    const sequence = Array.from({
        length: Math.floor(Math.random() * 2) + 1
    }, () => ({
        action: actions[Math.floor(Math.random() * actions.length)],
        requiredCount: Math.floor(Math.random() * 5) + 1,
        currentCount: 0,
        completed: false,
    }));
    showActionBar(player, sequence[0]);
    return {
        sequence,
        currentEvent: 0,
        completed: false,
        errorOccurred: false
    };
}

function processMiniGameState(player, dummy, state, actions) {
    if (state.completed) return;

    const event = state.sequence[state.currentEvent];
    if (!event) return;

    handleEventAction(player, state, event, actions);

    if (event.currentCount >= event.requiredCount) {
        event.completed = true;
        state.currentEvent++;
        if (state.currentEvent < state.sequence.length) {
            showActionBar(player, state.sequence[state.currentEvent]);
        } else {
            completeMinigame(player, dummy, state);
        }
    } else {
        showProgress(player, event);
    }
}

function handleEventAction(player, state, event, actions) {
    const handlers = {
        jump: handleJump,
        sneak: handleSneak,
        lookGesture: handleLookGesture,
        lookGestureHorizontal: handleLookGestureHorizontal,
    };

    if (
        (event.action === "jump" && player.isSneaking) ||
        (event.action === "sneak" && player.isJumping)
    ) {
        if (!event.hasErrored) {
            player.sendMessage({ rawtext: [{ translate: "aria_ah.minigame.wrong_input" }]});
            event.hasErrored = true;
            state.sequence = initializeMinigame(player, actions).sequence;
            state.currentEvent = 0;
            showActionBar(player, state.sequence[0]);
        }
        return;
    }

    handlers[event.action]?.(player, state, event);
}

function handleJump(player, state, event) {
    if (!state.isJumpingPressed && player.isJumping) {
        state.isJumpingPressed = true;
        event.currentCount++;
        showProgress(player, event);
    }
    if (!player.isJumping) state.isJumpingPressed = false;
}

function handleSneak(player, state, event) {
    if (!state.isSneakingPressed && player.isSneaking) {
        state.isSneakingPressed = true;
        event.currentCount++;
        showProgress(player, event);
    }
    if (!player.isSneaking) state.isSneakingPressed = false;
}

function handleLookGesture(player, state, event) {
    const gestures = event.gestureSequence ?? ["up", "down", "up"];
    const step = event.currentStep ?? 0;
    const rotation = player.getRotation().x;

    if (
        (gestures[step] === "up" && rotation < -20) ||
        (gestures[step] === "down" && rotation > 20)
    ) {
        event.currentStep = step + 1;
        if (event.currentStep >= gestures.length) {
            event.currentCount++;
            event.currentStep = 0;
        }
        showProgress(player, event);
    }
    event.gestureSequence = gestures;
}

function handleLookGestureHorizontal(player, state, event) {
    const gestures = event.gestureSequence ?? ["left", "right", "left"];
    const step = event.currentStep ?? 0;
    const rotation = player.getRotation().y;

    if (
        (gestures[step] === "left" && rotation < -30) ||
        (gestures[step] === "right" && rotation > 30)
    ) {
        event.currentStep = step + 1;
        if (event.currentStep >= gestures.length) {
            event.currentCount++;
            event.currentStep = 0;
        }
        showProgress(player, event);
    }
    event.gestureSequence = gestures;
}

function showActionBar(player, event) {
    const messages = {
        jump: `Jump ${event.requiredCount} times!`,
        sneak: `Sneak ${event.requiredCount} times!`,
        lookGesture: `Move your head up and down ${event.requiredCount} times!`,
        lookGestureHorizontal: `Move your head left and right ${event.requiredCount} times!`,
    };
    player.onScreenDisplay.setActionBar(messages[event.action]);
}

function showProgress(player, event) {
    const actions = {
        jump: "Jump",
        sneak: "Sneak",
        lookGesture: "Move your head up and down",
        lookGestureHorizontal: "Move your head left and right",
    };
    const message = `${actions[event.action] || event.action} ${event.requiredCount - event.currentCount} times!`;
    player.onScreenDisplay.setActionBar(message);
}

function completeMinigame(player, dummy, state) {
    state.completed = true;
    resetDummy(dummy);
    player.onScreenDisplay.setActionBar("");
}



function resetDummy(dummy) {
    dummy.triggerEvent(`aria:reset`);
    dummy.triggerEvent(`aria:set_cooldown_15`);

    dummy.clearDynamicProperties();

    dummy.dimension.spawnParticle("minecraft:knockback_roar_particle", {
        x: dummy.location.x,
        y: dummy.location.y + 0.15,
        z: dummy.location.z
    });
    dummy.dimension.spawnParticle("minecraft:knockback_roar_particle", {
        x: dummy.location.x,
        y: dummy.location.y + 1.15,
        z: dummy.location.z
    });
    dummy.dimension.playSound("mob.enderdragon.flap", {
        x: dummy.location.x,
        y: dummy.location.y + 0.25,
        z: dummy.location.z
    }, {
        volume: 1,
        pitch: 2
    });
    dummy.dimension.playSound("mob.bat.takeoff", {
        x: dummy.location.x,
        y: dummy.location.y + 0.25,
        z: dummy.location.z
    }, {
        volume: 1,
        pitch: 1.45
    });

    dummy.runCommand(`camerashake add @a[r=35] 3 0.15 rotational`);

    const dir = dummy.getViewDirection();

    dummy.applyKnockback(
        {
            x: dir.x * -4.5,
            z: dir.z * -4.5
        },
        0.5
    );
}

