import { BlockPermutation, system, world } from "@minecraft/server"
import { sendDebugMessage } from "./JMmcUtils"

function lightEffect(entity) {
    const dimension = entity.dimension
    // find light locations
    const loc = entity.location,
        vert_size = 2,
        horiz_size = 1
    const lightLocations = []
    for (let y = Math.floor(loc.y + vert_size); y >= Math.floor(loc.y); y--) {
        for (let x = Math.floor(loc.x - horiz_size); x <= Math.floor(loc.x + horiz_size); x++) {
            for (let z = Math.floor(loc.z - horiz_size); z <= Math.floor(loc.z + horiz_size); z++) {
                const curBlock = dimension.getBlock({ x: x, y: y, z: z })
                if (curBlock === undefined) continue
                if (curBlock.isAir || curBlock.typeId.includes("light_block")) lightLocations.push({ x: x, y: y, z: z })
            }
        }
    }
    // compare to old locations
    const oldLoc = (entity.getDynamicPropertyIds().includes("lb_ga:light_locations") ? JSON.parse(entity.getDynamicProperty("lb_ga:light_locations")) : [])

    entity.setDynamicProperty("lb_ga:light_locations", JSON.stringify(lightLocations))

    for (let l = lightLocations.length - 1; l >= 0; l--) {
        const curLoc = lightLocations[l],
            oldIndex = oldLoc.findIndex((element) => element.x === curLoc.x && element.y === curLoc.y && element.z === curLoc.z)
        if (oldIndex >= 0) { // location exists in both arrays, remove from both
            lightLocations.splice(l, 1)
            oldLoc.splice(oldIndex, 1)
        }
    }
    // fill in necessary lights
    lightLocations.forEach(loc => {
        const block = dimension.getBlock(loc)
        if (block && block.typeId === "minecraft:air") block.setPermutation(BlockPermutation.resolve("light_block", { "block_light_level": 14 }))
    });
    // remove uneccessary lights
    oldLoc.forEach(loc => {
        const block = dimension.getBlock(loc)
        if (block && block.typeId === "minecraft:light_block_14") block.setPermutation(BlockPermutation.resolve("air"))
    });

    system.run(() => {
        if (!hasHealth(entity)) {
            sendDebugMessage(`entity has no health! removing data...`)
            try {
                JSON.parse(entity.getDynamicProperty("lb_ga:light_locations")).forEach(loc => {
                    dimension.getBlock(loc).setPermutation(BlockPermutation.resolve("air"))
                })
            } catch (error) {
                sendDebugMessage(`§4error removing light blocks from dead lantern: ${error}`)
            }
        }
    })
}

function hasHealth(entity) {
    if (entity.getComponent("health").currentValue >= 1) return true
    return false
}

// lantern behavior
system.runInterval(() => {
    const dimensions = ["overworld", "nether", "the_end"]
    dimensions.forEach(dimension => {
        dimension = world.getDimension(dimension)
        const entities = dimension.getEntities({ type: "lb_ga:glowstone_golem" }).concat(dimension.getEntities({ type: "lb_ga:glowstone_golem_small" }))
        entities.forEach(entity => {
            lightEffect(entity)
        })
    })
})