import { ItemStack } from "@minecraft/server"



export class BucketRefillerComponent {
    constructor() {
        this.onPlayerInteract = this.onPlayerInteract.bind(this);
        this.onTick = this.onTick.bind(this);

        this.AQUATIC_ENTITIES = [
            "minecraft:cod",
            "minecraft:salmon",
            "minecraft:tropicalfish",
            "minecraft:pufferfish",
            "minecraft:tadpole",
            "minecraft:axolotl"
        ];
    }
    onPlayerInteract(e) {
        const block = e.block
        const player = e.player
        let selectedSlot = player.selectedSlotIndex;
        let handItem = player.getComponent("inventory").container.getItem(selectedSlot);
        if (handItem?.typeId == "pb_red:redstone_wrench") {
            const AllStates = [
                { state: "minecraft:cardinal_direction", values: ["north", "east", "south", "west"] },
                { state: "minecraft:facing_direction", values: ["north", "east", "south", "west", "up", "down"] }
            ]

            AllStates.some((stateObj) => {
                const currentState = block.permutation.getState(stateObj.state);

                if (currentState !== undefined && currentState !== null) {
                    const stateValues = stateObj.values;
                    const currentStateIndex = stateValues.indexOf(currentState);
                    const nextState = currentStateIndex >= stateValues.length - 1 ? stateValues[0] : stateValues[currentStateIndex + 1];

                    block.setPermutation(block.permutation.withState(stateObj.state, nextState));
                    block.dimension.runCommand(`playsound vr.stutterturn @a ${block.location.x} ${block.location.y} ${block.location.z}`)
                }
            });
            return;
        }

        if (block.permutation.getState('pb_red:fish_bucket') == true) {
            block.setPermutation(block.permutation.withState('pb_red:fish_bucket', false))
            block.dimension.runCommand(`playsound bubble.pop @a ${block.location.x} ${block.location.y} ${block.location.z}`)
        } else {
            block.setPermutation(block.permutation.withState('pb_red:fish_bucket', true))
            block.dimension.runCommand(`playsound bubble.pop @a ${block.location.x} ${block.location.y} ${block.location.z}`)
        }
    }
    getFrontBlock(direction, block) {
        switch (direction) {
            case 'north':
                return block.north();
            case 'south':
                return block.south();
            case 'east':
                return block.east();
            case 'west':
                return block.west();
            case 'up':
                return block.above();
            case 'down':
                return block.below();
        }
    }

    getOppositeDirection(direction) {
        switch (direction) {
            case 'north':
                return 'south';
            case 'south':
                return 'north';
            case 'east':
                return 'west';
            case 'west':
                return 'east';
            case 'up':
                return 'down';
            case 'down':
                return 'up';
        }
    }

    onTick(e) {
        const block = e.block;
        let direction = this.getOppositeDirection(block.permutation.getState('minecraft:cardinal_direction'));
        let frontBlock = this.getFrontBlock(direction, block);
        const above = block.above();
        const below = block.below();

        if (!above || !below || !frontBlock) return;

        if (!this.isValidContainer(below) || !this.isValidContainer(above)) return;

        let emptyBucketSlot = this.findItemInInventory(above, "minecraft:bucket");
        let glassBottle = false
        if (emptyBucketSlot === -1) {
            glassBottle = true
            emptyBucketSlot = this.findItemInInventory(above, "minecraft:glass_bottle");
        };
        if (emptyBucketSlot === -1) return;

        let emptySlotBelow = this.findEmptySlotInInventory(below);
        if (emptySlotBelow === -1) return;

        if (glassBottle) {
            if (frontBlock.permutation.matches("minecraft:water") && (frontBlock.permutation.getState("liquid_depth") == 0)) {
                let bucketType = "minecraft:potion";
                frontBlock.setType("minecraft:air");
                this.transferItem(above, below, emptyBucketSlot, bucketType, emptySlotBelow);
                return;
            }
        }

        if (block.permutation.getState('pb_red:fish_bucket') === false) {
            if ((frontBlock.permutation.matches("minecraft:water") || frontBlock.permutation.matches("minecraft:lava")) && (frontBlock.permutation.getState("liquid_depth") == 0)) {
                let bucketType = frontBlock.permutation.matches("minecraft:water") ? "minecraft:water_bucket" : "minecraft:lava_bucket";
                frontBlock.setType("minecraft:air");
                this.transferItem(above, below, emptyBucketSlot, bucketType, emptySlotBelow);
            }
            if (frontBlock.permutation.matches("minecraft:cauldron") && frontBlock.permutation.getState("fill_level") == 6) {
                let bucketType;
                switch (frontBlock.permutation.getState("cauldron_liquid")) {
                    case "lava":
                        bucketType = "minecraft:lava_bucket"
                        break;
                    case "powder_snow":
                        bucketType = "minecraft:powder_snow_bucket"
                        break;
                    case "water":
                        bucketType = "minecraft:water_bucket"
                        break;
                }
                frontBlock.setType("minecraft:cauldron");
                this.transferItem(above, below, emptyBucketSlot, bucketType, emptySlotBelow);
            }
        }

        const entities = block.dimension.getEntities({
            location: frontBlock.location,
            maxDistance: 1
        });

        for (const entity of entities) {
            if (this.AQUATIC_ENTITIES.includes(entity.typeId)) {
                let bucketType = `minecraft:${entity.typeId.replace('minecraft:', '')}_bucket`;
                if (entity.typeId == "minecraft:tropicalfish")
                    bucketType = "minecraft:tropical_fish_bucket"
                entity.remove();
                this.transferItem(above, below, emptyBucketSlot, bucketType, emptySlotBelow);
                return;
            } else if (entity.typeId === "minecraft:cow") {

                const milkCooldownTag = entity.getTags().find(tag => tag.startsWith('pb_red_milk_cooldown:'));
                const milkCooldownTime = milkCooldownTag ? parseInt(milkCooldownTag.split(':')[1]) : 0;
                const cooldownExpired = Date.now() - milkCooldownTime > 1 * 10 * 1000;

                if ((milkCooldownTag ? cooldownExpired : true) && !entity.getComponent("minecraft:is_baby")) {
                    if (milkCooldownTag)
                        entity.removeTag(milkCooldownTag)
                    entity.addTag(`pb_red_milk_cooldown:${Date.now()}`);
                    this.transferItem(above, below, emptyBucketSlot, "minecraft:milk_bucket", emptySlotBelow);
                    return;
                }
            }
        }
    }

    findItemInInventory(block, itemId) {
        let inventory = block.getComponent("minecraft:inventory").container;
        for (let slot = 0; slot < inventory.size; slot++) {
            let item = inventory.getItem(slot);
            if (item && item.typeId === itemId) {
                return slot;
            }
        }
        return -1;
    }

    findEmptySlotInInventory(block) {
        let inventory = block.getComponent("minecraft:inventory").container;
        for (let slot = 0; slot < inventory.size; slot++) {
            let item = inventory.getItem(slot);
            if (!item) {
                return slot;
            }
        }
        return -1;
    }

    transferItem(sourceBlock, destinationBlock, sourceSlot, newItemType, destinationSlot) {
        let sourceInventory = sourceBlock.getComponent("minecraft:inventory").container;
        let destinationInventory = destinationBlock.getComponent("minecraft:inventory").container;

        let sourceItem = sourceInventory.getItem(sourceSlot);
        if (sourceItem.amount > 1) {
            sourceInventory.setItem(sourceSlot, new ItemStack(sourceItem.typeId, sourceItem.amount - 1));
        } else {
            sourceInventory.setItem(sourceSlot, null);
        }

        destinationInventory.setItem(destinationSlot, new ItemStack(newItemType, 1));
        sourceBlock.dimension.runCommand(`playsound random.swim @a ${sourceBlock.location.x} ${sourceBlock.location.y} ${sourceBlock.location.z}`)

    }

    isValidContainer(block) {
        if (!block) return;
        const validContainers = [
            "minecraft:chest",
            "minecraft:hopper",
            "minecraft:barrel",
            "minecraft:dropper",
            "minecraft:dispenser",
            "minecraft:trapped_chest",
            //shulker box
            "minecraft:undyed_shulker_box",
            "minecraft:black_shulker_box",
            "minecraft:blue_shulker_box",
            "minecraft:brown_shulker_box",
            "minecraft:cyan_shulker_box",
            "minecraft:gray_shulker_box",
            "minecraft:green_shulker_box",
            "minecraft:light_blue_shulker_box",
            "minecraft:light_gray_shulker_box",
            "minecraft:lime_shulker_box",
            "minecraft:magenta_shulker_box",
            "minecraft:orange_shulker_box",
            "minecraft:pink_shulker_box",
            "minecraft:purple_shulker_box",
            "minecraft:red_shulker_box",
            "minecraft:white_shulker_box",
            "minecraft:yellow_shulker_box",


        ];
        return validContainers.includes(block.typeId);
    }
}