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

const activeLights = new Set();

world.afterEvents.entitySpawn.subscribe((event) => {
    const entity = event.entity;
    addDlEntity(entity);
});

world.afterEvents.entityLoad.subscribe((event) => {
    const entity = event.entity;
    addDlEntity(entity);
});

world.beforeEvents.entityRemove.subscribe((event) => {
    const entity = event.removedEntity;
    removeDlEntity(entity);

});

world.afterEvents.entityDie.subscribe((event) => {
    const entity = event.deadEntity;
    removeDlEntity(entity);

});

system.afterEvents.scriptEventReceive.subscribe((event) => {
    const { id, message, sourceEntity } = event;
    if (id == 'oct_eg:pet' && message == 'despawned') {
        removeDlEntity(sourceEntity);
        system.runTimeout(() => { sourceEntity.remove(); }, 1);
    }

});

system.runInterval(() => { handleDlEntities(); }, 2);

function addDlEntity(entity) {
    if (entity.getComponent('type_family')?.hasTypeFamily('oct_eg.dynamic_light')) {

        // Check if already tracked
        if (activeLights.has(entity.id)) return;

        // Add to tracked list
        activeLights.add(entity.id);
    }
}
function removeDlEntity(entity) {
    // Remove the stored dynamic light
    const lightLocProp = entity?.getDynamicProperty('oct_eg.dl_loc');
    if (lightLocProp) {
        //console.info(`§2Removed dynamic light at ${lightLocProp}`);
        const lightLoc = JSON.parse(lightLocProp);
        removeDynamicLight(entity, lightLoc);
    }

    // Remove from tracked list
    entity.setDynamicProperty('oct_eg.dl_stop', true);
    activeLights.delete(entity.id);
}
function handleDlEntities() {
    for (const dl of activeLights) {
        const entity = world.getEntity(dl);
        if (!entity || !entity.isValid()) return;

        // Update the dynamic light location
        const curLoc = entity.location;
        const oldLocProp = entity?.getDynamicProperty('oct_eg.dl_loc');
        const oldLoc = oldLocProp ? JSON.parse(oldLocProp) : { x: 0, y: 0, z: 0 };

        // Check if the location has changed
        if (curLoc.x !== oldLoc.x || curLoc.y !== oldLoc.y || curLoc.z !== oldLoc.z) {

            // Update the dynamic light
            updateDynamicLight(entity, oldLoc, curLoc);

        }
    }
}

function updateDynamicLight(entity, oldLoc, curLoc) {

    const max_intensity = 10;
    const min_intensity = 5;
    const HpComp = entity?.getComponent('health');
    const HpPercentage = HpComp ? HpComp.currentValue / HpComp.effectiveMax : 1;
    const intensity = Math.floor(HpPercentage * (max_intensity - min_intensity) + min_intensity);

    removeDynamicLight(entity, oldLoc);
    addDynamicLight(entity, curLoc, intensity);
}
function addDynamicLight(entity, location, intensity = 15) {
    system.run(() => {
        if (!entity.isValid()) return;

        if (entity?.getDynamicProperty('oct_eg.dl_stop')) return;

        const Hp = entity?.getComponent('health').currentValue;
        if (Hp <= 0) return;

        const block = entity.dimension.getBlock(location);
        if (block.isAir === false) return;

        const blockPlaced = entity.runCommand(`setblock ${location.x} ${location.y} ${location.z} light_block_${intensity}`);

        // Update the stored location
        if (blockPlaced) entity.setDynamicProperty('oct_eg.dl_loc', JSON.stringify(location));
    })


}
function removeDynamicLight(entity, location) {
    const dimension = entity.dimension;
    system.run(() => {
        if (!entity.isValid()) return;

        const block = entity.dimension.getBlock(location);
        if (!block.typeId.startsWith('minecraft:light_block_')) return;

        const blockPlaced = dimension.runCommand(`setblock ${location.x} ${location.y} ${location.z} air`);
    })

}