import { system, world, } from "@minecraft/server";
import { namespace } from "../../../config/_config";
// StepOnEffectBlock class defines blocks that apply effects to entities or players when stepped on.
export class StepOnEffectBlock {
    // Constructor to initialize a StepOnEffectBlock with its properties
    constructor({ id, effects, }) {
        this.id = id;
        this.effects = effects;
    }
    static registerBehavior(config) {
        const block = new StepOnEffectBlock(config);
        this.register(block);
    }
    // Method to register a StepOnEffectBlock
    static register(block) {
        StepOnEffectBlock.blocks.push(block);
    }
    // Initialization method to register the custom step-on effect component with the world
    static initialize() {
        world.beforeEvents.worldInitialize.subscribe((event) => {
            event.blockComponentRegistry.registerCustomComponent(`${namespace}:step_on_effect`, {
                // Apply effect when an entity or player steps on the block
                onStepOn: (event) => {
                    this.applyEffect(event);
                },
                // Stop the effect when an entity or player steps off the block
                onStepOff: (event) => {
                    this.stopEffect(event);
                },
            });
        });
    }
    // Method to apply the effect when an entity or player steps on the block
    static applyEffect(event) {
        const block = event.block; // Get the block being stepped on
        if (!block)
            return;
        // Find the registered StepOnEffectBlock by block type
        const effectBlock = StepOnEffectBlock.blocks.find((block) => block.id === event.block.typeId);
        if (!effectBlock)
            return;
        const player = event.entity; // Get the player/entity stepping on the block
        if (!player)
            return;
        // Mark the player/entity as being on the block
        this.playerOnBlock.set(player, true);
        // Apply each effect defined for the block
        effectBlock.effects?.forEach((effect) => {
            // Handle looping effects
            if (effect.loop && this.playerOnBlock.get(player) === true) {
                // Set an interval to repeatedly apply the effect
                const intervalId = system.runInterval(() => {
                    // Apply the effect to the player/entity
                    player.addEffect(effect.type, effect.duration, effect.properties);
                    // Stop the loop if the player steps off the block
                    if (this.playerOnBlock.get(player) === false) {
                        system.clearRun(intervalId); // Clear the interval if they step off
                    }
                }, 20); // Loop every second (20 ticks)
                // Store the interval ID to clear it when needed
                this.intervalIds.set(player, intervalId);
            }
            else {
                // Apply a single effect if not looping
                player.addEffect(effect.type, effect.duration, effect.properties);
            }
        });
    }
    // Method to stop the effect when the player steps off the block
    static stopEffect(event) {
        const player = event.entity; // Get the player/entity stepping off the block
        // Mark the player/entity as no longer being on the block
        this.playerOnBlock.set(player, false);
        // Clear any active looping effect intervals for the player
        const intervalId = this.intervalIds.get(player);
        if (intervalId !== undefined) {
            system.clearRun(intervalId); // Clear the interval
            this.intervalIds.delete(player); // Remove the stored interval ID
        }
    }
}
// Array to store all registered StepOnEffectBlock instances
StepOnEffectBlock.blocks = [];
// Map to track players/entities standing on the block
StepOnEffectBlock.playerOnBlock = new Map();
// Map to store interval IDs for looping effects
StepOnEffectBlock.intervalIds = new Map();
