import { ItemStack, BlockPermutation, system, world } from '@minecraft/server';
import { dimensions, locomotiveFamily, railTypes, getDirectionFromRailState, isRail } from './trainsAddOn';
import { queryBlock } from './JM_Utils';

const blockBlacklist = [
        "minecraft:water", "minecraft:flowing_water", "minecraft:lava", "minecraft:flowing_lava", "minecraft:dragon_egg", 
        "minecraft:end_portal", "minecraft:end_portal_frame", "minecraft:structure_void", "minecraft:portal", "minecraft:bedrock", 
        "minecraft:reinforced_deepslate", "minecraft:border_block", "minecraft:barrier"
    ]
for (let i = 0; i < 16; i++) {
    blockBlacklist.push(`minecraft:light_block_${i}`)    
}

system.runInterval(() => {
    dimensions.forEach(element => {
        const dimension = world.getDimension(element);
        const players = dimension.getPlayers();
        // drill functionality
        dimension.getEntities({families:[locomotiveFamily]}).forEach(locomotive => {
            const carBlock = queryBlock(locomotive.location,dimension);
            if (!carBlock) return
            const rideableComponent = locomotive.getComponent('rideable');
            const riders = rideableComponent.getRiders();
            for (let r = 0; r < riders.length; r++) {
                let rider = riders[r];
                if (players.includes(rider)) {
                    if (locomotive.typeId === "lifeboat_ta:drill") {
                        const railState = carBlock?.permutation.getState("rail_direction");
                        // let carVel = locomotive.getVelocity();
                        let direction = getDirectionFromRailState(railState, locomotive);
                        drill(carBlock, direction, dimension);
                        placeRail(locomotive, carBlock, direction);
                    }
                }
            }
        });
    });
});

function drill(carBlock, direction, dimension) {
    if (direction == 90) { //west
        let blockInFront = carBlock.west();
        for (let y = 0; y < 3; y++) {
            for (let z = -1; z < 2; z++) {
                let blockLocation = {x: blockInFront.x, y: blockInFront.y + y, z: blockInFront.z + z};
                if (blockLocation.y > dimension.heightRange.max) {}
                else {
                    let block = dimension.getBlock(blockLocation);
                    if (block.location.y !== block.dimension.heightRange.max) {
                        let aboveBlock = block.above();
                        let aboveBlockNorth = aboveBlock.north();
                        let aboveBlockSouth = aboveBlock.south();
                        if (isRail(aboveBlockNorth) || isRail(aboveBlockSouth)) {
                        }
                        else if (isRail(aboveBlock)) {
                        }
                        else if ((!blockBlacklist.includes(block.type.id) && !isRail(block)) && !isRail(aboveBlock)) {
                            dimension.runCommand(`setblock ${block.x} ${block.y} ${block.z} air destroy`);
                        }
                    }
                    else {
                        if ((!blockBlacklist.includes(block.type.id) && !isRail(block))) {
                            dimension.runCommand(`setblock ${block.x} ${block.y} ${block.z} air destroy`);
                        }
                    }
                }
            }
        }
    }
    if (direction == 270) { //east
        let blockInFront = carBlock.east();
        for (let y = 0; y < 3; y++) {
            for (let z = -1; z < 2; z++) {
                let blockLocation = {x: blockInFront.x, y: blockInFront.y + y, z: blockInFront.z + z};
                if (blockLocation.y > dimension.heightRange.max) {}
                else {
                    let block = dimension.getBlock(blockLocation);
                    if (block.location.y !== block.dimension.heightRange.max) {
                        let aboveBlock = block.above();
                        let aboveBlockNorth = aboveBlock.north();
                        let aboveBlockSouth = aboveBlock.south();
                        if (isRail(aboveBlockNorth) || isRail(aboveBlockSouth)) {
                        }
                        else if (isRail(aboveBlock)) {
                        }
                        else if ((!blockBlacklist.includes(block.type.id) && !isRail(block)) && !isRail(aboveBlock)) {
                            dimension.runCommand(`setblock ${block.x} ${block.y} ${block.z} air destroy`);
                        }
                    }
                    else {
                        if ((!blockBlacklist.includes(block.type.id) && !isRail(block))) {
                            dimension.runCommand(`setblock ${block.x} ${block.y} ${block.z} air destroy`);
                        }
                    }
                }
            }
        }
    }
    if (direction == 180) { //North
        let blockInFront = carBlock.north();
        for (let y = 0; y < 3; y++) {
            for (let x = -1; x < 2; x++) {
                let blockLocation = {x: blockInFront.x + x, y: blockInFront.y + y, z: blockInFront.z};
                if (blockLocation.y > dimension.heightRange.max) {}
                else {
                    let block = dimension.getBlock(blockLocation);
                    if (block.location.y !== block.dimension.heightRange.max) {
                        let aboveBlock = block.above();
                        let aboveBlockEast = aboveBlock.east();
                        let aboveBlockWest = aboveBlock.west();
                        if (isRail(aboveBlockEast) || isRail(aboveBlockWest)) {
                        }
                        else if (isRail(aboveBlock)) {
                        }
                        else if ((!blockBlacklist.includes(block.type.id) && !isRail(block)) && !isRail(aboveBlock)) {
                            dimension.runCommand(`setblock ${block.x} ${block.y} ${block.z} air destroy`);
                        }
                    }
                    else {
                        if ((!blockBlacklist.includes(block.type.id) && !isRail(block))) {
                            dimension.runCommand(`setblock ${block.x} ${block.y} ${block.z} air destroy`);
                        }
                    }
                }
            }
        }
    }
    if (direction == 0) { //South
        let blockInFront = carBlock.south();
        for (let y = 0; y < 3; y++) {
            for (let x = -1; x < 2; x++) {
                let blockLocation = {x: blockInFront.x + x, y: blockInFront.y + y, z: blockInFront.z};
                if (blockLocation.y > dimension.heightRange.max) {}
                else {
                    let block = dimension.getBlock(blockLocation);
                    if (block.location.y !== block.dimension.heightRange.max) {
                        let aboveBlock = block.above();
                        let aboveBlockEast = aboveBlock.east();
                        let aboveBlockWest = aboveBlock.west();
                        if (isRail(aboveBlockEast) || isRail(aboveBlockWest)) {
                        }
                        else if (isRail(aboveBlock)) {
                        }
                        else if ((!blockBlacklist.includes(block.type.id) && !isRail(block)) && !isRail(aboveBlock)) {
                            dimension.runCommand(`setblock ${block.x} ${block.y} ${block.z} air destroy`);
                        }
                    }
                    else {
                        if ((!blockBlacklist.includes(block.type.id) && !isRail(block))) {
                            dimension.runCommand(`setblock ${block.x} ${block.y} ${block.z} air destroy`);
                        }
                    }
                }
            }
        }
    }
}

function checkGetInventoryForRails(locomotive) {
    const inventoryComponent = locomotive.getComponent('inventory');
    const inventorySize = inventoryComponent.inventorySize;
    for (let i = 0; i < inventorySize; i++) {
        let item = inventoryComponent.container.getItem(i);
        if (item !== undefined) {
            let itemId = item.typeId;
            if (railTypes.includes(itemId.split(":")[1])) {
                let check = {rail: item, i: i};
                return check;
            } 
            else {
                return undefined;
            }
        }
        else {
            return undefined;
        }
    }
}

function placeRail(locomotive, carBlock, direction) {
    let railCheck = checkGetInventoryForRails(locomotive);
    let blockInFront;
    let flatRailState;
    let slopedRailState;
    if (direction == 0) {
        blockInFront = carBlock.south();
        flatRailState = 0;
        slopedRailState = 5;
    }
    else if (direction == 90) {
        blockInFront = carBlock.west();
        flatRailState = 1;
        slopedRailState = 2;
    }
    else if (direction == 180) {
        blockInFront = carBlock.north();
        flatRailState = 0;
        slopedRailState = 5;
    }
    else if (direction == 270) {
        blockInFront = carBlock.east();
        flatRailState = 1;
        slopedRailState = 2;
    }
    else {
        return;
    }
    let blockBelow = blockInFront.below();
    if (!blockBelow.permutation.matches('minecraft:air') && (!isRail(blockBelow))) {
        if (!isRail(blockInFront) && blockInFront.permutation.matches('minecraft:air')) {
            if (railCheck !== undefined) {
                let railPerm = BlockPermutation.resolve(railCheck.rail.typeId, {'rail_direction': flatRailState});
                blockInFront.setPermutation(railPerm);
                decrementInventory(locomotive, railCheck);
            }
        }
    }
    else {
        if (blockBelow.location.y !== blockBelow.dimension.heightRange.min) {
            let belowBelow = blockBelow.below();
            if (!belowBelow.permutation.matches('minecraft:air') && (!isRail(blockBelow))) {
                if (railCheck !== undefined) {
                    let railPerm = BlockPermutation.resolve(railCheck.rail.typeId, {'rail_direction': slopedRailState});
                    blockBelow.setPermutation(railPerm);
                    decrementInventory(locomotive, railCheck)
                }
            }
        }
    }
}

function decrementInventory(locomotive, railCheck) {
    const inventoryComponent = locomotive.getComponent('inventory');
    const inventorySize = inventoryComponent.inventorySize;
    const i = railCheck.i;
    const item = railCheck.rail; 
    const itemId = item.typeId;
    if (item.amount > 1) {
        let newAmount = item.amount - 1
        let updatedItemStack = new ItemStack(itemId, newAmount);
        inventoryComponent.container.setItem(i, updatedItemStack);
    }
    else {
        let containerSlots = [];
        for (let j = 0; j < inventorySize; j++) {
            if (j === i) {}
            else {
                if (inventoryComponent.container.getItem(j) === undefined) {}
                else {
                    let container = inventoryComponent.container.getItem(j);
                    containerSlots.push(container);
                }
            }
        }
        inventoryComponent.container.clearAll();
        containerSlots.forEach(itemStack => {
            inventoryComponent.container.addItem(itemStack);
        });
    }
}