import { BlockPermutation } from '@minecraft/server';
import { getWeightedRandomChoice } from '../util/random';
function getBlockAshLevel(block, options = {}) {
    if (block.isAir || options?.replacesBlocks?.has(block.typeId))
        return 0;
    const level = block.permutation.getState('twb_wisu:level');
    return level || 8;
}
export function incrementAshLevel(block, amount, options = {}) {
    if (amount === 0)
        return;
    let targetBlock = block;
    let level = getBlockAshLevel(block, options);
    if (level === 8)
        return;
    if (level === 0) {
        const below = block.below();
        if (!below || below.isAir) {
            if (!options.disableEntitySpawning) {
                const entity = block.dimension.spawnEntity('twb_wisu:falling_ash', block.bottomCenter());
                entity.setProperty('twb_wisu:level', amount);
            }
            return;
        }
        const belowHeight = getBlockAshLevel(below, options);
        if (belowHeight < 8) {
            targetBlock = below;
            level = belowHeight;
        }
    }
    const newLevel = Math.min(level + amount, 8);
    const remainingAmount = amount - (newLevel - level);
    targetBlock.setPermutation((newLevel === 8)
        ? BlockPermutation.resolve('twb_wisu:ash')
        : BlockPermutation.resolve('twb_wisu:ash_layer', { 'twb_wisu:level': newLevel }));
    if (remainingAmount) {
        const above = targetBlock.above();
        if (above?.isValid())
            incrementAshLevel(above, remainingAmount);
    }
}
export function landAshOnBlock(block, amount, options = {}) {
    let level = getBlockAshLevel(block);
    const adjacentBlocks = [block.north(), block.east(), block.south(), block.west()];
    // eslint-disable-next-line no-param-reassign
    while (level < 8 && amount-- > 0) {
        const blocks = [block];
        const weights = [Math.min(6, amount)];
        for (const adjacentBlock of adjacentBlocks) {
            if (adjacentBlock) {
                const adjacentHeight = getBlockAshLevel(adjacentBlock, options);
                const weight = Math.min(Math.max(level - adjacentHeight, 0), 5);
                if (weight) {
                    blocks.push(adjacentBlock);
                    weights.push(weight);
                }
            }
        }
        const randomBlock = getWeightedRandomChoice(blocks, (_, i) => weights[i]);
        if (randomBlock === block)
            level++;
        incrementAshLevel(randomBlock, 1, options);
    }
    if (level === 8 && amount > 0) {
        const above = block.above();
        if (above)
            landAshOnBlock(above, amount, options);
    }
}
export function turnToFallingAsh(block, level = 8) {
    const above = block.above();
    if (above) {
        if (above.permutation.matches('twb_wisu:ash_layer')) {
            turnToFallingAsh(above, above.permutation.getState('twb_wisu:level'));
            above.setType('minecraft:air');
        }
    }
    const entity = block.dimension.spawnEntity('twb_wisu:falling_ash', block.bottomCenter());
    entity.setProperty('twb_wisu:level', level);
}
