import { ItemStack, Direction } from '@minecraft/server';
import { getBlocksAround, isBlockContainer, getBlockFromDirection, getBlockContainer, updateBlockState, getBlockState } from '../../utils/utils.js';
import { FSItemTags, ToolTier } from '../../constants.js';
import { addItemToDrawerV2 } from '../../compact/storage_drawers.js';

class GeneratorBlockCustomComponent {
    constructor() {
        this.onTick = (event, parameters) => {
            const generatorData = parameters.params;
            const block = event.block;
            const generatorStage = getStage(block.permutation);
            const blocked = getBlocked(block.permutation);
            const containerAround = getBlocksAround(block)
                .some(block => isBlockContainer(block) || block.hasTag(FSItemTags.STORAGE_DRAWER));
            // If there is no container around, we set the stage to STAGE_0 this is because updating state stops reading from the block
            if (!containerAround) {
                if (generatorStage !== GeneratorStage.STAGE_0) {
                    setStage(block, GeneratorStage.STAGE_0);
                }
                return;
            }
            const blockTier = getBlockTier(block);
            const amount = getAmountForTier(blockTier);
            if (generatorStage === GeneratorStage.STAGE_EMPTY) {
                const blocksAround = getBlocksAround(block);
                for (const blockAround of blocksAround) {
                    if (blockAround.hasTag(FSItemTags.STORAGE_DRAWER)) {
                        addItemToDrawerV2(blockAround, new ItemStack(generatorData.block, amount));
                        setStage(block, getNextGeneratorStage(generatorStage));
                        return;
                    }
                }
                for (let directionKey in Direction) {
                    const direction = Direction[directionKey];
                    const blockAround = getBlockFromDirection(block, direction);
                    if (!blockAround) {
                        continue;
                    }
                    const container = getBlockContainer(blockAround);
                    if (!container) {
                        continue;
                    }
                    const extraItems = container.addItem(new ItemStack(generatorData.block, amount));
                    if (extraItems) {
                        if (!blocked) {
                            setBlocked(block, true);
                        }
                        return;
                    }
                    if (blocked) {
                        setBlocked(block, false);
                    }
                    break;
                }
            }
            setStage(block, getNextGeneratorStage(generatorStage));
        };
    }
}
function setStage(block, generatorStage) {
    updateBlockState(block, GeneratorBlockStates.STAGE, generatorStage);
}
function getStage(blockPermutation) {
    return getBlockState(blockPermutation, GeneratorBlockStates.STAGE);
}
function getBlocked(blockPermutation) {
    return getBlockState(blockPermutation, GeneratorBlockStates.BLOCKED);
}
function setBlocked(block, blocked) {
    updateBlockState(block, GeneratorBlockStates.BLOCKED, blocked);
}
class GeneratorLookAtHandler {
    constructor(tag, message) {
        this.tag = tag;
        this.message = message;
    }
    onLookat(player, block) {
        const stage = getBlocked(block.permutation);
        if (stage) {
            player.onScreenDisplay.setActionBar({
                "translate": this.message
            });
        }
    }
    isValid(player, block) {
        return block.getTags().includes(this.tag);
    }
}
var GeneratorStage;
(function (GeneratorStage) {
    GeneratorStage[GeneratorStage["STAGE_0"] = 0] = "STAGE_0";
    GeneratorStage[GeneratorStage["STAGE_1"] = 1] = "STAGE_1";
    GeneratorStage[GeneratorStage["STAGE_2"] = 2] = "STAGE_2";
    GeneratorStage[GeneratorStage["STAGE_3"] = 3] = "STAGE_3";
    GeneratorStage[GeneratorStage["STAGE_4"] = 4] = "STAGE_4";
    GeneratorStage[GeneratorStage["STAGE_5"] = 5] = "STAGE_5";
    GeneratorStage[GeneratorStage["STAGE_6"] = 6] = "STAGE_6";
    GeneratorStage[GeneratorStage["STAGE_7"] = 7] = "STAGE_7";
    GeneratorStage[GeneratorStage["STAGE_8"] = 8] = "STAGE_8";
    GeneratorStage[GeneratorStage["STAGE_9"] = 9] = "STAGE_9";
    GeneratorStage[GeneratorStage["STAGE_EMPTY"] = 10] = "STAGE_EMPTY";
})(GeneratorStage || (GeneratorStage = {}));
var GeneratorBlockStates;
(function (GeneratorBlockStates) {
    GeneratorBlockStates["STAGE"] = "ftb_sieves:gen_stage";
    GeneratorBlockStates["BLOCKED"] = "ftb_sieves:blocked";
})(GeneratorBlockStates || (GeneratorBlockStates = {}));
function getNextGeneratorStage(generatorStage) {
    if (generatorStage === GeneratorStage.STAGE_EMPTY) {
        return GeneratorStage.STAGE_0;
    }
    return generatorStage + 1;
}
function getBlockTier(block) {
    if (block.hasTag("ftb_sieves:tier_cobble")) {
        return ToolTier.STONE;
    }
    if (block.hasTag("ftb_sieves:tier_iron")) {
        return ToolTier.IRON;
    }
    if (block.hasTag("ftb_sieves:tier_gold")) {
        return ToolTier.GOLD;
    }
    if (block.hasTag("ftb_sieves:tier_diamond")) {
        return ToolTier.DIAMOND;
    }
    if (block.hasTag("ftb_sieves:tier_netherite")) {
        return ToolTier.NETHERITE;
    }
    return ToolTier.WOOD;
}
function getAmountForTier(tier) {
    switch (tier) {
        case ToolTier.WOOD:
            return 1;
        case ToolTier.STONE:
            return 1;
        case ToolTier.IRON:
            return 8;
        case ToolTier.GOLD:
            return 16;
        case ToolTier.DIAMOND:
            return 32;
        case ToolTier.NETHERITE:
            return 64;
        default:
            return 0;
    }
}

export { GeneratorBlockCustomComponent, GeneratorBlockStates, GeneratorLookAtHandler, GeneratorStage, getNextGeneratorStage };
