import { BlockComponentTypes, EntityComponentTypes, EquipmentSlot, ItemComponentTypes, ItemStack, world } from "@minecraft/server";
const ThirstFoods = [
    { typeId: "minecraft:potion", thirst: 0.5 },
    { typeId: "minecraft:sweet_berries", thirst: 0.1 },
    { typeId: "minecraft:glow_berries", thirst: 0.1, },
    { typeId: "minecraft:mushroom_stew", thirst: 0.3 },
    { typeId: "minecraft:rabbit_stew", thirst: 0.3 },
    { typeId: "minecraft:suspicious_stew", thirst: 0.3 },
    { typeId: "minecraft:beetroot_soup", thirst: 0.3 },
    { typeId: "minecraft:melon_slice", thirst: 0.1 },
    // { typeId: "oct_db:water_flask.filled", thirst: 1 }, // This will be custom
];
export const thirstDecimalAccuracy = 5;
export function initThirst() {
    world.afterEvents.itemCompleteUse.subscribe(result => {
        const thirstFood = ThirstFoods.find(val => val.typeId === result.itemStack.typeId);
        if (!thirstFood)
            return;
        const player = result.source;
        player.setThirst(player.getThirst() + thirstFood.thirst);
    });
}
;
// Water flask
export function initWaterFlask() {
    // Cauldron because item component doesn't register block interaction properly
    world.afterEvents.itemUseOn.subscribe(result => {
        if (!result.itemStack.typeId.startsWith("oct_db:water_flask"))
            return;
        const blockReach = 5;
        const viewDirection = result.source.getViewDirection();
        const headLocation = result.source.getHeadLocation();
        let foundWater = false;
        // Custom water raycast
        for (let i = 0; i < blockReach; i++) {
            const checkLocation = { x: headLocation.x + viewDirection.x * i, y: headLocation.y + viewDirection.y * i, z: headLocation.z + viewDirection.z * i };
            const lookBlock = result.source.dimension.getBlock(checkLocation);
            if (lookBlock.typeId === "minecraft:cauldron") {
                foundWater = true;
                break;
            }
            else if (lookBlock.isAir)
                continue;
            else
                break;
        }
        if (!foundWater)
            return;
        // Set item in hand
        const oldItem = result.itemStack;
        const newItem = new ItemStack("oct_db:water_flask.filled", 1);
        const equippableComp = result.source.getComponent(EntityComponentTypes.Equippable);
        equippableComp.getEquipmentSlot(EquipmentSlot.Mainhand).setItem(newItem);
        // If grabbing from cauldron
        const block = result.source.getBlockFromViewDirection();
        const fluidComp = block?.block?.getComponent(BlockComponentTypes.FluidContainer);
        if (!fluidComp)
            return;
        /**
         * If there's 2 or more levels of water (same amount as water bottle), take 2 levels and fully fill.
         * If there's only 1, then empty the cauldron and only fill the water bottle halfway
         */
        if (fluidComp.fillLevel === 0) {
            return;
        }
        else if (fluidComp.fillLevel >= 2) {
            fluidComp.fillLevel -= 2;
        }
        else {
            fluidComp.fillLevel = 0;
            const oldDurabilityComp = oldItem.getComponent(ItemComponentTypes.Durability);
            const durabilityComp = newItem.getComponent(ItemComponentTypes.Durability);
            durabilityComp.damage += Math.max(0, Math.min(durabilityComp.maxDurability, oldDurabilityComp.damage - durabilityComp.maxDurability / 2));
            equippableComp.getEquipmentSlot(EquipmentSlot.Mainhand).setItem(newItem);
        }
        // SFX
        result.source.dimension.playSound("bucket.fill_water", result.source.location);
    });
    world.beforeEvents.worldInitialize.subscribe(result => {
        result.itemComponentRegistry.registerCustomComponent("oct_db:water_flask.empty", {
            onUse: (result) => {
                refillFlaskFromWater(result);
            }
        });
        result.itemComponentRegistry.registerCustomComponent("oct_db:water_flask.filled", {
            onCompleteUse: (result) => {
                // Set thirst
                playerDrinkWaterFlask(result.source, result.itemStack);
            },
            onUse: (result) => {
                refillFlaskFromWater(result);
            }
        });
    });
}
function refillFlaskFromWater(result) {
    const blockReach = 5;
    const viewDirection = result.source.getViewDirection();
    const headLocation = result.source.getHeadLocation();
    let foundWater = false;
    // Custom water raycast
    for (let i = 0; i < blockReach; i++) {
        const checkLocation = { x: headLocation.x + viewDirection.x * i, y: headLocation.y + viewDirection.y * i, z: headLocation.z + viewDirection.z * i };
        const lookBlock = result.source.dimension.getBlock(checkLocation);
        if (lookBlock.typeId === "minecraft:water") {
            foundWater = true;
            break;
        }
        else if (lookBlock.isAir)
            continue;
        else
            break;
    }
    if (!foundWater)
        return;
    // Set item in hand
    const newItem = new ItemStack("oct_db:water_flask.filled", 1);
    const equippableComp = result.source.getComponent(EntityComponentTypes.Equippable);
    equippableComp.getEquipmentSlot(EquipmentSlot.Mainhand).setItem(newItem);
    // SFX
    result.source.dimension.playSound("bucket.fill_water", result.source.location);
}
;
function playerDrinkWaterFlask(player, waterFlask) {
    const currentThirst = player.getThirst(); // 0 - 1
    const missingThirst = 1 - currentThirst;
    // Get cloned item
    let clonedItem = waterFlask.clone();
    const durabilityComp = clonedItem.getComponent(ItemComponentTypes.Durability);
    // Calculate how much thirst the flask can replenish
    const remainingUses = (durabilityComp.maxDurability - durabilityComp.damage) / 100; // Scaled down by 100
    const usableThirst = Math.min(missingThirst, remainingUses); // Don't replenish more than missing thirst
    // Update thirst
    player.setThirst(currentThirst + usableThirst);
    // Reduce durability
    durabilityComp.damage = Math.min(durabilityComp.maxDurability, durabilityComp.damage + usableThirst * 100); // Scaled by 100 because durability is 0 - 400 not 0 - 4
    // Replace with empty flask if durability is 0
    if (durabilityComp.damage >= durabilityComp.maxDurability) {
        clonedItem = new ItemStack("oct_db:water_flask.empty", 1);
    }
    ;
    // Set item in hand
    const equippableComp = player.getComponent(EntityComponentTypes.Equippable);
    equippableComp.getEquipmentSlot(EquipmentSlot.Mainhand).setItem(clonedItem);
    // console.warn(currentThirst)
}
