import { system, world, ItemStack } from "@minecraft/server";

const debugMode = false;
const earthworks = false;

// -=-=-=--=-=-=-=-=-=-=-=-=-=-=-=- FINALIZADOS -=-=-=--=-=-=-=-=-=-=-=-=-=-=-=- 

export function isSolid(block) {
    let blockId = block.typeId;
    if (block.isAir || !block.typeId.includes('minecraft:')) return false;
    const nonSolidBlocks = new Set([
        "dandelion", "poppy", "blue_orchid", "allium", "azure_bluet", "red_tulip", "orange_tulip", "white_tulip", "pink_tulip", "oxeye_daisy", "sunflower", "lilac",
        "rose_bush", "peony", "cornflower", "lily_of_the_valley", "tall_grass", "short_grass", "fern", "large_fern", "deadbush", "seagrass", "air", "waterlily", "vine", "ladder", "rail",
        "golden_rail", "activator_rail", "tripwire_hook", "beacon", "web", "snow_layer", "iron_bars", "chain", "scaffolding", "bamboo", "sea_pickle", "conduit",
        "lightning_rod", "sweet_berry_bush", "small_dripleaf_block", "big_dripleaf", "flower_pot", "amethyst_cluster", "budding_amethyst", "pointed_dripstone", 
        "glow_lichen",  "spore_blossom", "hanging_roots", "end_rod", "bell", "lantern", "soul_lantern", "chain", "soul_fire", "bubble_column", "redstone_wire", "rc_fb:vacuum_hopper"
    ]);
    const nonSolidGroups = ["slab", "glass", "carpet", "leaves", "vines", "coral", "torch", "mushroom", "sign", "banner", "frame", "portal", "campfire", "hopper"];
    if (nonSolidGroups.some(word => blockId.includes(word)) || nonSolidBlocks.has(blockId.replace('minecraft:', ''))) return false;
    else return true;
};

export function getRedstonePower(block) {
    const blockRedstonePower = block.getRedstonePower();
    if (blockRedstonePower == 0) {
        for (let face of ['north', 'south', 'east', 'west', 'below', 'above']) {
            const newBlock = block[face]();
            const newBlockRedstonePower = newBlock?.getRedstonePower();
            const avoidBlocks = ['redstone_wire', 'repeater', 'comparator', 'redstone_torch'];
            if ((newBlockRedstonePower > 0 && !avoidBlocks.some(block => newBlock?.typeId.includes(block))) ||
                (newBlock?.typeId.includes('redstone_torch') && newBlock?.permutation.getState('torch_facing_direction') != invertFace[face])) {
                return newBlockRedstonePower;
            };
        };
        const aboveBlock = block.above(); const aboveBlockPower = aboveBlock?.getRedstonePower();
        if (aboveBlock?.typeId == 'minecraft:daylight_detector' && aboveBlockPower > 0) return aboveBlockPower;
    };
    return blockRedstonePower;
};

export const invertFace = { 
    'north': 'south', 'south': 'north', 
    'east': 'west', 'west': 'east', 
    'up': 'down', 'down': 'up', 
    'above': 'below', 'below': 'above',
    
    'above.north': 'below.south', 'below.north': 'above.south',
    'above.south': 'below.north', 'below.south': 'above.north',
    'above.east': 'below.west', 'below.east': 'above.west',
    'above.west': 'below.east', 'below.west': 'above.east',

    'east.north': 'west.south', 'west.north': 'east.south',
    'east.south': 'west.north', 'west.south': 'east.north'
};

export const rotationToFace = { 
    'north': 'north', 'south': 'south', 
    'east': 'east', 'west': 'west', 
    'up': 'above', 'down': 'below'
};

function cardinalFacing(entity) {
    const rotation = entity.getRotation().y;
    if (rotation >= 135 || rotation <= -135) return 'north';
    if (rotation >= -45 && rotation < 45) return 'south';
    if (rotation >= 45 && rotation < 135) return 'west';
    if (rotation > -135 && rotation < -45) return 'east';
};

export function formatTypeId(typeId) {
    return typeId.split(':')[1].replace(/[_-]/g, ' ').split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
};

const interval = 5;
let TPS = 20;
let lastDate = Date.now();
if (debugMode) {
    system.runInterval(() => {
        const currDate = Date.now();
        TPS = interval * 50 / (currDate - lastDate) * 20;
        lastDate = currDate;
        const player = world.getAllPlayers()[0];
        const blockFromView = player?.getBlockFromViewDirection({maxDistance: 10})?.block;
        if (blockFromView) player?.onScreenDisplay.setActionBar(`TPS: §e${TPS.toFixed(2)}  §rBlockId: §e${blockFromView.typeId}`);
        else player?.onScreenDisplay.setActionBar(`TPS: §e${TPS.toFixed(2)}`);
    }, interval);    
};

if (earthworks) {
    system.runInterval(() => {
        const player = world.getAllPlayers()[0];
        for (let x = -25; x < 25; x++) {
            for (let z = -25; z < 25; z++) {
                const block = player.dimension.getBlock({x: player.location.x+x, y: player.location.y-1, z: player.location.z+z});
                if (block?.isLiquid) block.setType('minecraft:grass_block');
            };
        };
    }, 1);    
};


// -=-=-=--=-=-=-=-=-=-=-=-=-=-=-=- EM PROGRESSO -=-=-=--=-=-=-=-=-=-=-=-=-=-=-=- 

export function getDistance(vetorA, vetorB) {
    const dx = vetorB.x - vetorA.x;
    const dy = vetorB.y - vetorA.y;
    const dz = vetorB.z - vetorA.z;
    return Math.hypot(dx, dy, dz);
};

export function getSegment(initialValue, currentValue, parts) {
    const segmentSize = initialValue / parts;
    return Math.min(parts, Math.ceil(currentValue / segmentSize));
};


export class somarVetores {
    constructor(vetorA, vetorB) {
        this.x = vetorA.x + vetorB.x;
        this.y = vetorA.y + vetorB.y;
        if (vetorA.z !== undefined || vetorB.z !== undefined) this.z = (vetorA.z || 0) + (vetorB.z || 0);
        else this.z = undefined;
    };
};

export class multiplicarVetores {
    constructor(vetor, num) {
        this.x = vetor.x * num;
        this.y = vetor.y * num;
        this.z = vetor.y * num;
    };
};

export class vetor {
    static distance(vetorA, vetorB) {
        if (!vetorA || !vetorB) return undefined;
        const dx = vetorA.x - vetorB.x;
        const dy = vetorA.y - vetorB.y;
        const dz = vetorA.z - vetorB.z;
        return Math.sqrt(dx * dx + dy * dy + dz * dz);
    };
    static subtract(vetorA, vetorB) {
        if (!vetorA || !vetorB) return undefined;
        const dx = vetorA.x - vetorB.x;
        const dy = vetorA.y - vetorB.y;
        const dz = vetorA.z - vetorB.z;
        return { x: dx, y: dy, z: dz };
    };
    static createCircle(startblock, radius, numBlocks) {
        if (!startblock || !radius || !numBlocks) return [];
        const suavidade = (2 * Math.PI) / numBlocks;
        const blockLocations = [];
        for (let i = 0; i < numBlocks; i++) {
            const x = startblock.center().x + radius * Math.cos(i * suavidade);
            const z = startblock.center().z + radius * Math.sin(i * suavidade);
            const y = startblock.center().y;
            blockLocations.push({x, y, z});
        };
        return blockLocations;
    };
};

export function replaceItem(player, searchId, replaceId, setDamage) {
    const playerInv = player.getComponent('minecraft:inventory').container;
    for (let slot = 0; slot < playerInv.size; slot++) {
        const itemSearched = playerInv.getItem(slot);
        if (itemSearched?.typeId == searchId) {
            let itemSearchedDurability = itemSearched.getComponent('minecraft:durability');
            let itemEnchant = itemSearched.getComponent('minecraft:enchantable');
            let itemSearchedLore = itemSearched.getLore();
            const replacementItem = new ItemStack(replaceId, itemSearched.amount);
            if (setDamage) replacementItem.getComponent('minecraft:durability').damage = setDamage;
            else if (itemSearchedDurability) replacementItem.getComponent('minecraft:durability').damage = itemSearchedDurability.damage;
            if (itemEnchant) replacementItem.getComponent('minecraft:enchantable')?.addEnchantments(itemEnchant.getEnchantments());
            replacementItem.setLore(itemSearchedLore);
            playerInv.setItem(slot, replacementItem);
            return;
        };
    };
};

export function removeItem(player, searchId, amount) {
    const playerInv = player.getComponent('minecraft:inventory').container;
    for (let slot = 0; slot < playerInv.size; slot++) {
        const itemSearched = playerInv.getItem(slot);
        if (itemSearched?.typeId == searchId) {
            if (itemSearched.amount < amount) return;
            const replacementItem = new ItemStack(itemSearched?.typeId, itemSearched.amount > amount ?  itemSearched.amount-amount : 1);
            if (amount) playerInv.setItem(slot, itemSearched.amount > amount ? replacementItem : undefined);
            return true;
        };
    };
};

export function searchItem(player, searchId) {
    const playerInv = player.getComponent('minecraft:inventory').container;
    for (let slot = 0; slot < playerInv.size; slot++) {
        const itemSearched = playerInv.getItem(slot);
        if (itemSearched?.typeId == searchId) return true;
    };
};

export function damageDurability(itemStack, source, amount) {
    let itemDurability = itemStack.getComponent('minecraft:durability');
    if (itemDurability?.maxDurability - (itemDurability?.damage + (amount ? amount : 1)) <= 0) {
        source.getComponent('minecraft:equippable')?.setEquipment('Mainhand',); 
        return;
    };
    if (itemDurability) itemDurability.damage += amount ? amount : 1; 
    const handItem = source.getComponent('minecraft:equippable').getEquipment('Mainhand');
    if (handItem?.typeId == itemStack?.typeId) source.getComponent('minecraft:equippable')?.setEquipment('Mainhand', itemStack);
};

