import { world, ItemStack } from '@minecraft/server';
import { spawnLootAtBlock, playSoundAtBlock, spawnItemAtBlock, shrinkItemStack, getBlockState, updateBlockState, addVec3, insertLootToBlock } from '../../utils/utils.js';
import { getEntityHeldItem, setEntityHeldItem } from '../../utils/players.js';
import { FSBlocks, MCSounds, MCParticles } from '../../constants.js';
import { PlantRecipes } from '../../recipes/recipes.js';

class PotBlockComponent {
    constructor() {
        this.onPlayerInteract = (event) => {
            const block = event.block;
            const player = event.player;
            const potHandler = new PotHandler(block);
            potHandler?.onInteract(player);
        };
        this.onTick = (event) => {
            const block = event.block;
            const potHandler = new PotHandler(block);
            if (!potHandler) {
                return;
            }
            const growthStage = potHandler.getGrowthStage(block.permutation);
            const plantType = potHandler.getPlantType(block.permutation);
            if (plantType === PlantRecipes.EMPTY) {
                return;
            }
            if (growthStage == GrowthStage.STAGE_4) {
                const b = insertLootToBlock(block.below(1), plantType.lootTable);
                if (b) {
                    potHandler.setGrowthStage(GrowthStage.STAGE_1);
                }
                return;
            }
            potHandler.setGrowthStage(potHandler.getNextGrowthStage(growthStage));
        };
    }
}
// This is required for items that register a custom component, that has custom useOn logic. As that is not passed to itemUseOn in blocks then
world.afterEvents.itemStartUseOn.subscribe((event) => {
    const block = event.block;
    const player = event.source;
    if (block.typeId !== FSBlocks.BOTANY_POT) {
        return;
    }
    const addonOwner = event.itemStack?.typeId.split(":")[0];
    if (!PlantRecipes.isCompactRegistered(addonOwner)) {
        return;
    }
    const potHandler = new PotHandler(block);
    if (!potHandler) {
        return;
    }
    potHandler.onInteract(player);
});
class PotHandler {
    constructor(block) {
        if (block?.typeId !== FSBlocks.BOTANY_POT) {
            throw new Error("Block is not a Botany Pot");
        }
        this.block = block;
    }
    onInteract(player) {
        this.block.dimension;
        const item = getEntityHeldItem(player);
        const soilType = this.getSoilType(this.block.permutation);
        const plantType = this.getPlantType(this.block.permutation);
        const growthStage = this.getGrowthStage(this.block.permutation);
        // If crops is fully grown
        if (plantType !== PlantRecipes.EMPTY && growthStage === GrowthStage.STAGE_4) {
            const b = spawnLootAtBlock(this.block.above(1), plantType.lootTable);
            if (b) {
                playSoundAtBlock(this.block, MCSounds.RANDOM_POP);
                this.setGrowthStage(GrowthStage.STAGE_1);
            }
            else {
                console.warn("No loot table found for plant type: " + plantType.name);
            }
            return;
        }
        // Remove Plant
        if (soilType === SoilType.COMPOST && plantType !== PlantRecipes.EMPTY && !item) {
            this.setPlantType(PlantRecipes.EMPTY);
            spawnItemAtBlock(this.block, new ItemStack(plantType.itemId));
            playSoundAtBlock(this.block, MCSounds.COMPOST_FILL);
            return;
        }
        // Check and try to add compost to the pot
        if (soilType === SoilType.EMPTY) {
            if (item?.typeId === FSBlocks.COMPOST) {
                this.setSoilType(SoilType.COMPOST);
                playSoundAtBlock(this.block, MCSounds.COMPOST_FILL);
                const newItemStack = shrinkItemStack(item);
                setEntityHeldItem(player, newItemStack);
            }
            return;
        }
        // Check and try to remove the compost from the pot
        if (soilType === SoilType.COMPOST && !item) {
            this.setSoilType(SoilType.EMPTY);
            playSoundAtBlock(this.block, MCSounds.COMPOST_FILL);
            spawnItemAtBlock(this.block, new ItemStack(FSBlocks.COMPOST));
            return;
        }
        if (plantType === PlantRecipes.EMPTY) {
            const plantTypeFromItem = this.getPlantTypeFromItem(item?.typeId);
            if (!plantTypeFromItem) {
                return;
            }
            const newItemStack = shrinkItemStack(item);
            setEntityHeldItem(player, newItemStack);
            this.setPlantType(plantTypeFromItem);
        }
    }
    getSoilType(blockPermutation) {
        return getBlockState(blockPermutation, PotBlockStates.SOIL);
    }
    getType1(blockPermutation) {
        return getBlockState(blockPermutation, PotBlockStates.TYPE_1);
    }
    getType2(blockPermutation) {
        return getBlockState(blockPermutation, PotBlockStates.TYPE_2);
    }
    getGrowthStage(blockPermutation) {
        return getBlockState(blockPermutation, PotBlockStates.GROWTH_STAGE);
    }
    getPlantType(blockPermutation) {
        const blockType1 = this.getType1(blockPermutation);
        const blockType2 = this.getType2(blockPermutation);
        return this.getPlantTypeFromIds(blockType1, blockType2);
    }
    setSoilType(soilType) {
        updateBlockState(this.block, PotBlockStates.SOIL, soilType);
    }
    setType1(type1) {
        updateBlockState(this.block, PotBlockStates.TYPE_1, type1);
    }
    setType2(type2) {
        updateBlockState(this.block, PotBlockStates.TYPE_2, type2);
    }
    setGrowthStage(growthStage) {
        if (growthStage == GrowthStage.STAGE_4) {
            this.block.dimension.spawnParticle(MCParticles.CROP_GROWTH, addVec3(this.block.center(), 0, 0.25, 0));
        }
        updateBlockState(this.block, PotBlockStates.GROWTH_STAGE, growthStage);
    }
    setPlantType(plantType) {
        this.setType1(plantType.typeIds[0]);
        this.setType2(plantType.typeIds[1]);
    }
    getNextGrowthStage(growthStage) {
        if (growthStage === GrowthStage.STAGE_4) {
            return GrowthStage.STAGE_1;
        }
        return growthStage + 1;
    }
    getPlantTypeFromItem(itemId) {
        for (const plantType of PlantRecipes.RECIPES) {
            if (plantType.itemId === itemId) {
                return plantType;
            }
        }
        return undefined;
    }
    getPlantTypeFromIds(idOne, idTwo) {
        for (const plantType of PlantRecipes.RECIPES) {
            if (plantType.typeIds[0] === idOne && plantType.typeIds[1] === idTwo) {
                return plantType;
            }
        }
        return PlantRecipes.EMPTY;
    }
}
var SoilType;
(function (SoilType) {
    SoilType["EMPTY"] = "empty";
    SoilType["COMPOST"] = "compost";
})(SoilType || (SoilType = {}));
var GrowthStage;
(function (GrowthStage) {
    GrowthStage[GrowthStage["STAGE_1"] = 0] = "STAGE_1";
    GrowthStage[GrowthStage["STAGE_2"] = 1] = "STAGE_2";
    GrowthStage[GrowthStage["STAGE_3"] = 2] = "STAGE_3";
    GrowthStage[GrowthStage["STAGE_4"] = 3] = "STAGE_4";
})(GrowthStage || (GrowthStage = {}));
var PotBlockStates;
(function (PotBlockStates) {
    PotBlockStates["GROWTH_STAGE"] = "ftb_sieves:grow_stage";
    PotBlockStates["TYPE_1"] = "ftb_sieves:type_1";
    PotBlockStates["TYPE_2"] = "ftb_sieves:type_2";
    PotBlockStates["SOIL"] = "ftb_sieves:soil_type";
})(PotBlockStates || (PotBlockStates = {}));

export { GrowthStage, PotBlockComponent, PotBlockStates, PotHandler, SoilType };
