import { ItemDurabilityComponent } from '@minecraft/server';
import * as mc from "@minecraft/server"

export function highlightBlock(block) {

    let location = block.location;
    let dimension = block.dimension.id;

    let mvm = new mc.MolangVariableMap();
    mvm.setFloat(`variable.dirx`, 0);
    mvm.setFloat(`variable.diry`, 1);
    mvm.setFloat(`variable.dirz`, 0);
    mc.world.getDimension(dimension).spawnParticle('sgs_cake:block_marker', { x: location.x + 0.5, y: location.y - 0.01, z: location.z + 0.5 }, mvm);
    mc.world.getDimension(dimension).spawnParticle('sgs_cake:block_marker', { x: location.x + 0.5, y: location.y + 1.01, z: location.z + 0.5 }, mvm);

    mvm.setFloat(`variable.dirx`, 1);
    mvm.setFloat(`variable.diry`, 0);
    mvm.setFloat(`variable.dirz`, 0);
    mc.world.getDimension(dimension).spawnParticle('sgs_cake:block_marker', { x: location.x + 1.01, y: location.y + 0.5, z: location.z + 0.5 }, mvm);
    mc.world.getDimension(dimension).spawnParticle('sgs_cake:block_marker', { x: location.x - 0.01, y: location.y + 0.5, z: location.z + 0.5 }, mvm);

    mvm.setFloat(`variable.dirx`, 0);
    mvm.setFloat(`variable.diry`, 0);
    mvm.setFloat(`variable.dirz`, 1);
    mc.world.getDimension(dimension).spawnParticle('sgs_cake:block_marker', { x: location.x + 0.5, y: location.y + 0.5, z: location.z + 1.01 }, mvm);
    mc.world.getDimension(dimension).spawnParticle('sgs_cake:block_marker', { x: location.x + 0.5, y: location.y + 0.5, z: location.z + 0.01 }, mvm);
}

export function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

export function randomWholeNum(min, max) {
    const maxPlus1 = max + 1;
    let result = Math.random() * (max - min) + min;
    //return a random whole number
    return Math.round(result);
}

export function randomNum(min, max) {
    //return a random number
    return Math.random() * (max - min) + min;
}

export class itemManager {
    static reduceDurability(player, item, reduceAmount) {
        const comp = item.getComponent(ItemDurabilityComponent.componentId);
        if (comp.damage + reduceAmount <= comp.maxDurability) {
            comp.damage = comp.damage + reduceAmount;
            return item;
        } else {
            player.dimension.playSound("random.break", player.location);
            return undefined;
        }
    }
    static reduceDurabilityEntity(entity, item, reduceAmount) {
        const comp = item.getComponent(ItemDurabilityComponent.componentId);
        if (comp.damage + reduceAmount <= comp.maxDurability) {
            comp.damage = comp.damage + reduceAmount;
            return item;
        } else {
            entity.dimension.playSound("block.turtle_egg.break", entity.location);
            return undefined;
        }
    }
    static addDurability(player, item, addAmount) {
        const comp = item.getComponent(ItemDurabilityComponent.componentId);
        if (comp.damage - addAmount < 0) {
            comp.damage = 0;
            return item;
        } else {
            comp.damage = comp.damage - comp.addAmount;
            return item;
        }
    }
    static reduceAmount(item, reduceBy) {
        const amount = item.amount;
        if (amount - reduceBy <= 0) {
            return undefined;
        } else {
            item.amount = amount - reduceBy;
            return item;
        }
    }
    //TODO needs space check
    static addItemToBlockInventory(item, block) {
        const inventory = block.getComponent(mc.BlockComponentTypes.Inventory).container;
        inventory.addItem(item);
        return true;
    }
}

export class hungerManager {
    static addHunger(player, hunger_add, saturation_add) {
        const hunger = player.getComponent("minecraft:player.hunger");
        const saturation = player.getComponent("minecraft:player.saturation");

        if (hunger.currentValue == hunger.effectiveMax) return false;    //fail if the player cannot eat

        hunger.setCurrentValue(clamp(hunger.currentValue + hunger_add, 0, hunger.effectiveMax));
        saturation.setCurrentValue(clamp(saturation.currentValue + saturation_add, 0, saturation.effectiveMax));

        return true;
    }

    static addHungerAnyways(player, hunger_add, saturation_add) {
        const hunger = player.getComponent("minecraft:player.hunger");
        const saturation = player.getComponent("minecraft:player.saturation");
        hunger.setCurrentValue(clamp(hunger.currentValue + hunger_add, 0, hunger.effectiveMax));
        saturation.setCurrentValue(clamp(saturation.currentValue + saturation_add, 0, saturation.effectiveMax));

        return true;
    }
}

export function clamp(value, min, max) {
    return value > max ? max : value < min ? min : value;
}

export function blockToKey(block) {

    let location = block.location;
    let dimension = block.dimension.id;

    return "sgs_cake_" + dimension + "_" + location.x + "_" + location.y + "_" + location.z;
}

export function targetFamilies(location, dimensionId, radius, entityFamilies) {
    let target_entities = [];
    for (let index = 0; index < entityFamilies.length; index++) {
        target_entities = target_entities.concat(mc.world.getDimension(dimensionId).getEntities({ location: location, families: [entityFamilies[index]], maxDistance: radius }));
    }
    return target_entities;
}