import { system, world } from "@minecraft/server";
import { filterEntities } from "./utils"; // Assuming this is the correct path
export class DynamicEffect {
    constructor(params) {
        this.targetStates = new Map(); // to track target states
        this.intervalTimers = new Map(); // to track interval timers
        this.filter = params.filter;
        this.effects = params.effects;
        this.conditions = params.conditions;
        this.dynamicProperty = params.dynamicProperty; // Assign the dynamic property
    }
    getOptions() {
        return this.effects;
    }
    static register(effect) {
        system.runInterval(() => {
            const targets = world.getDimension("overworld").getEntities(); // Adjusted to get all entities, not just players
            targets.forEach((target) => {
                const targetId = target.id; // using entity ID as a unique identifier
                // Dynamic property check
                const allowedGlobal = world.getDynamicProperty("namespace:allow_effects");
                const allowedSpecific = effect.dynamicProperty
                    ? world.getDynamicProperty(effect.dynamicProperty)
                    : true; // Default to true if no dynamicProperty is provided
                if (allowedGlobal === false || allowedSpecific === false)
                    return;
                const isStartConditionMet = effect.conditions.startCondition(target, []);
                const isIntervalConditionMet = effect.conditions.intervalCondition(target, []);
                const isEndConditionMet = effect.conditions.endCondition(target, []);
                if (!effect.targetStates.has(targetId)) {
                    effect.targetStates.set(targetId, false);
                    effect.intervalTimers.set(targetId, new Map());
                }
                const wasStartConditionMet = effect.targetStates.get(targetId);
                if (filterEntities(target, effect.filter)) {
                    if (isStartConditionMet && !wasStartConditionMet) {
                        effect.triggerStartEffects(target);
                        effect.targetStates.set(targetId, true);
                    }
                    else if (isIntervalConditionMet && wasStartConditionMet) {
                        effect.triggerIntervalEffects(target, targetId);
                    }
                    else if (isEndConditionMet && wasStartConditionMet) {
                        effect.triggerEndEffects(target);
                        effect.targetStates.set(targetId, false);
                    }
                }
            });
        }, 1);
    }
    triggerStartEffects(target) {
        if (this.effects.onStart) {
            if (this.effects.onStart.particles) {
                this.effects.onStart.particles.forEach((particle) => {
                    try {
                        target.dimension.spawnParticle(particle, target.location);
                    }
                    catch (error) { }
                });
            }
            if (this.effects.onStart.sounds) {
                this.effects.onStart.sounds.forEach((sound) => {
                    try {
                        target.dimension.playSound(sound, target.location);
                    }
                    catch (error) { }
                });
            }
        }
    }
    triggerIntervalEffects(target, targetId) {
        const intervalTimers = this.intervalTimers.get(targetId);
        const currentTime = system.currentTick;
        if (this.effects.onInterval) {
            if (this.effects.onInterval.particles) {
                this.effects.onInterval.particles.forEach((effect) => {
                    const lastTriggerTime = intervalTimers?.get(effect.type) || 0;
                    if (currentTime - lastTriggerTime >= effect.interval) {
                        try {
                            target.dimension.spawnParticle(effect.type, target.location);
                        }
                        catch (error) { }
                        intervalTimers?.set(effect.type, currentTime);
                    }
                });
            }
            if (this.effects.onInterval.sounds) {
                this.effects.onInterval.sounds.forEach((effect) => {
                    const lastTriggerTime = intervalTimers?.get(effect.type) || 0;
                    if (currentTime - lastTriggerTime >= effect.interval) {
                        try {
                            target.dimension.playSound(effect.type, target.location);
                        }
                        catch (error) { }
                        intervalTimers?.set(effect.type, currentTime);
                    }
                });
            }
        }
    }
    triggerEndEffects(target) {
        if (this.effects.onEnd) {
            if (this.effects.onEnd.particles) {
                this.effects.onEnd.particles.forEach((particle) => {
                    try {
                        target.dimension.spawnParticle(particle, target.location);
                    }
                    catch (error) { }
                });
            }
            if (this.effects.onEnd.sounds) {
                this.effects.onEnd.sounds.forEach((sound) => {
                    try {
                        target.dimension.playSound(sound, target.location);
                    }
                    catch (error) { }
                });
            }
        }
    }
}
