import {
    world,
    system,
    EntityComponentTypes,
    EntityInventoryComponent,
    ItemStack,
    Player,
    EquipmentSlot,
    Entity,
} from "@minecraft/server";

/**
 * Adicionar um novo item no inventario de um entidade, essa funcao fazer de maneira simples, sem escolher qual slot do inventario sera adicionado o item.
 * @param {string} itemId - o id do item.
 * @param {Entity} sourceEntity - entidade do inventario em que o item sera adicionar,
 * @param {EntityInventoryComponent} inventory - inventario da entidade
 */
function add_items_inventory(itemId, sourceEntity, inventory) {
    let item = new ItemStack(itemId, 1);
    inventory.container.addItem(item);
    sourceEntity.runCommand("function ent/cons/colletion");
}
function add_items_asphalt(itemId, sourceEntity, inventory) {
        /** @type {EntityInventoryComponent} */

            for (let i = 0; i < inventory.container.size; i++) {
                let itemStack = inventory.container.getItem(i);
                if (itemStack != undefined) {
                    if (itemStack.typeId == "kt_ct:batch_of_cement") {
                        let item = new ItemStack(itemId, itemStack.amount * 9);
                        inventory.container.addItem(item);
                        sourceEntity.runCommand("function ent/cons/colletion");  
                        sourceEntity.runCommand(`replaceitem entity @s slot.inventory ${i} minecraft:air`);                  
                    }
                }
            }
}

/**
 *
 * @param {Entity} sourceEntity
 * @param {string} property
 * @param {number} maxValue
 */
function showFuelPercentageActionBar(sourceEntity, property, maxValue) {
    const typeId = sourceEntity.typeId;
    const location = sourceEntity.location;
    const fuelValue = sourceEntity.getProperty(property);
    if (fuelValue > 0) {
        const percentage = (fuelValue / maxValue) * 100;

        const blocksToShow = Math.ceil(percentage / 10);

        let actionBarMessage = "§6Fuel: ";
        let final_message =
            typeId == "kt_ct:dt_vehicle" || typeId == "kt_ct:lt_vehicle"
                ? "\npress jump to dump load"
                : typeId == "kt_ct:rr_vehicle"
                    ? `\nAsphalt Block: ${sourceEntity.getProperty(
                        "kt_ct:container_asphalth"
                    )}`
                    : "";
        for (let i = 0; i < 10; i++) {
            if (i < blocksToShow) {
                actionBarMessage += "§a■ ";
            } else {
                actionBarMessage += "§c■ ";
            }
        }

        actionBarMessage +=
            `${percentage > 30 ? "§a" : "§c"} (${percentage.toFixed(1)}%)` +
            final_message;

        sourceEntity.dimension
            .getEntities({
                maxDistance: 10,
                minDistance: 0,
                location: location,
            })
            .forEach((victim) => {
                if (
                    victim.typeId == "minecraft:player" &&
                    victim.hasTag("mount")
                ) {
                    victim.onScreenDisplay.setActionBar(actionBarMessage);
                }
            });
    }
    if (sourceEntity.getProperty("kt_ct:oil") == 0) {
        sourceEntity.dimension
            .getEntities({
                type: "minecraft:player",
                location: location,
                maxDistance: 10,
                minDistance: 0,
            })
            .forEach((player) => {
                if (
                    victim.typeId == "minecraft:player" &&
                    victim.hasTag("mount")
                )
                    player.onScreenDisplay.setActionBar("§4oil refill needed");
            });
    }
}

/**
 * @typedef {Object} Operation
 * @property {'+'|'-'|'*'|'/'|'return'} Operation.operation
 * @property {number|string} Operation.value
 */

/**
 *
 * @param {Entity} sourceEntity
 * @param {string} property
 * @param {Operation} operation
 */
function propertyUse(sourceEntity, property, operation) {
    if (typeof operation.value == "number") {
        switch (operation.operation) {
            case "+":
                sourceEntity.setProperty(
                    property,
                    sourceEntity.getProperty(property) + operation.value
                );
                break;
            case "-":
                sourceEntity.setProperty(
                    property,
                    sourceEntity.getProperty(property) - operation.value
                );
                break;
            case "*":
                sourceEntity.setProperty(
                    property,
                    sourceEntity.getProperty(property) * operation.value
                );
                break;
            case "/":
                sourceEntity.setProperty(
                    property,
                    sourceEntity.getProperty(property) / operation.value
                );
                break;
        }
    } else {
        switch (operation.operation) {
            case "+":
                sourceEntity.setProperty(
                    property,
                    sourceEntity.getProperty(property) +
                    sourceEntity.getProperty(operation.value)
                );
                break;
            case "-":
                sourceEntity.setProperty(
                    property,
                    sourceEntity.getProperty(property) -
                    sourceEntity.getProperty(operation.value)
                );
                break;
            case "*":
                sourceEntity.setProperty(
                    property,
                    sourceEntity.getProperty(property) *
                    sourceEntity.getProperty(operation.value)
                );
                break;
            case "/":
                sourceEntity.setProperty(
                    property,
                    sourceEntity.getProperty(property) /
                    sourceEntity.getProperty(operation.value)
                );
                break;
        }
    }
}

/**
 *
 * @param {Entity} entitySource
 * @param {'left'|'right'} direction
 * @returns
 */

function getAdjacentBlockLocation(entitySource, direction) {
    // Obtém o bloco que a entidade está olhando
    const blockView = entitySource.getBlockFromViewDirection({
        maxDistance: 7,
        includePassableBlocks: true,
    });

    // Verifica se há um bloco na direção do olhar
    if (!blockView) {
        return null;
    }

    // Obtém a localização do bloco observado
    const blockLocation = blockView.block.location;

    // Verifica a altura do bloco em relação à altura da entidade
    const entityY = Math.floor(entitySource.location.y + 0.5);
    const blockY = blockLocation.y;

    if (blockY <= entityY - 2) {
        // O bloco está muito abaixo da entidade, não quebrar
        return null;
    } else {
        // Obtém a rotação da entidade em graus
        const rotation = entitySource.getRotation().y;

        // Converte graus para radianos
        const radians = (rotation - 90) * (Math.PI / 180); // Subtrai 90 graus para ajustar a direção para esquerda/direita

        // Calcula o deslocamento nas coordenadas X e Z com base na rotação
        const xOffset =
            Math.round(Math.sin(radians)) * (direction === "left" ? -1 : 1);
        const zOffset =
            Math.round(Math.cos(radians)) * (direction === "left" ? -1 : 1);

        // Calcula as coordenadas do bloco adjacente
        const adjacentBlockLocation = {
            x: blockLocation.x + xOffset,
            y: blockLocation.y,
            z: blockLocation.z + zOffset,
        };

        return adjacentBlockLocation;
    }
}
/**
 *
 * @param {Entity} entitySource
 * @returns
 */
function placeBlocksOnSides(entitySource, blockType) {
    // Obtém a direção da entidade
    const viewDirection = entitySource.getViewDirection();
    const container_asphalth = entitySource.getProperty(
        "kt_ct:container_asphalth"
    );
    if (container_asphalth > 0) {
        // Calcula as coordenadas para o bloco central (3 blocos à frente da entidade)
        const centerX = Math.round(
            entitySource.location.x + viewDirection.x * 3
        );
        const centerY = Math.round(entitySource.location.y - 1); // Altura do bloco em relação à entidade
        const centerZ = Math.round(
            entitySource.location.z + viewDirection.z * 3
        );
        entitySource.runCommand(
            `setblock ${centerX} ${centerY} ${centerZ} ${blockType}`
        );
        if (container_asphalth - 1 > 0) {
            // Calcula as coordenadas para o bloco à direita (2 blocos à frente e 1 à direita)
            const rightX = Math.round(centerX + viewDirection.z);
            const rightY = centerY;
            const rightZ = Math.round(centerZ - viewDirection.x);
            entitySource.runCommand(
                `setblock ${rightX} ${rightY} ${rightZ} ${blockType}`
            );
            if (container_asphalth - 2 > 0) {
                // Calcula as coordenadas para o bloco à esquerda (2 blocos à frente e 1 à esquerda)
                const leftX = Math.round(centerX - viewDirection.z);
                const leftY = centerY;
                const leftZ = Math.round(centerZ + viewDirection.x);
                entitySource.runCommand(
                    `setblock ${leftX} ${leftY} ${leftZ} ${blockType}`
                );
            }
        }
    }
}

/**
 *
 * @param {Vector3} startPos
 * @param {Vector3} endPos
 * @param {string} particleType
 * @param {Entity} sourceEntity
 * @param {number} density
 */
function createParticleLine(
    startPos,
    endPos,
    particleType,
    sourceEntity,
    density = 1
) {
    const dx = endPos.x - startPos.x;
    const dy = endPos.y - startPos.y + 0.5;
    const dz = endPos.z - startPos.z;
    const length = Math.sqrt(dx * dx + dy * dy + dz * dz);

    const stepX = dx / length;
    const stepY = dy / length;
    const stepZ = dz / length;

    const numParticles = Math.ceil(length * density);

    const stepIncrementX = dx / numParticles;
    const stepIncrementY = dy / numParticles;
    const stepIncrementZ = dz / numParticles;

    for (let i = 0; i < numParticles; i++) {
        const posX = startPos.x + stepIncrementX * i;
        const posY = startPos.y + stepIncrementY * i;
        const posZ = startPos.z + stepIncrementZ * i;

        sourceEntity.dimension.spawnParticle(particleType, {
            x: posX,
            y: posY,
            z: posZ,
        });
    }
}

function ktColletion(sourceEntity, inventory, location, typeId) {
    sourceEntity.dimension.getEntities({
        maxDistance: typeId == "kt_ct:lt_vehicle" ? 10 : 8,
        minDistance: 1,
        location: location,
    })
        .forEach((victim) => {
            if (victim.typeId == "minecraft:item") {
                let item = victim.getComponent(
                    EntityComponentTypes.Item
                );

                if (items[item.itemStack.typeId]) {
                    inventory.container.addItem(item.itemStack);
                    victim.remove();
                    sourceEntity.runCommand(
                        "function ent/cons/colletion"
                    );
                }
            }
        });
}

function handleExcavator(sourceEntity, location, rotation) {
    sourceEntity.dimension.getEntities({ tags: ["mount"], location: location, maxDistance: 10, minDistance: 0 }).forEach((victim) => {
        if (victim.typeId == "kt_ct:excavator_vehicle") {
            victim.setProperty("kt_ct:head", rotation.x - 30);
        }
    });
    const blockView = sourceEntity.getBlockFromViewDirection({
        maxDistance: 10,
        includePassableBlocks: true,
    });
    const blockLocation = blockView.block.location;
    sourceEntity.runCommand(`fill ${blockLocation.x} ${blockLocation.y} ${blockLocation.z} ${blockLocation.x} ${blockLocation.y + 1} ${blockLocation.z} air destroy`);
}

function handleWlVehicle(sourceEntity, location, rotation) {
    if (rotation.x <= 30) {
        sourceEntity.dimension.getEntities({ tags: ["mount"], location: location, maxDistance: 3, minDistance: 0 }).forEach((victim) => {
            if (victim.typeId == "kt_ct:wl_vehicle") {
                victim.setProperty("kt_ct:head", rotation.x - 30);
            }
        });
    }
    const leftBlockLocation = getAdjacentBlockLocation(sourceEntity, "left");
    const rightBlockLocation = getAdjacentBlockLocation(sourceEntity, "right");
    if (leftBlockLocation && rightBlockLocation) {
        sourceEntity.runCommand(`fill ${leftBlockLocation.x} ${leftBlockLocation.y} ${leftBlockLocation.z} ${rightBlockLocation.x} ${rightBlockLocation.y} ${rightBlockLocation.z} air destroy`);
    }
}

function handleAlturaA(sourceEntity, location, rotation) {
    if (rotation.x <= 30) {
        sourceEntity.dimension.getEntities({ tags: ["mount"], location: location, maxDistance: 3, minDistance: 0 }).forEach((victim) => {
            if (victim.typeId == "kt_ct:fl_vehicle")
                victim.setProperty("kt_ct:head", Math.max(0, Math.min(-rotation.x, 40)));
        });
    }
}

function handleCraneVehicle(sourceEntity, location, rotation) {
    const viewDirection = sourceEntity.getViewDirection()
    sourceEntity.dimension.getEntities({ location, maxDistance: 10, minDistance: 0 }).forEach((victim) => {
        if (victim.typeId == "kt_ct:crane_vehicle") {
            victim.setProperty("kt_ct:head", -Math.round(victim.getRotation().y - rotation.y));
            if (rotation.x <= 50) {
                victim.setProperty("kt_ct:headx", rotation.x - 25);
            }
        }
        const blockView = sourceEntity.getBlockFromViewDirection({
            maxDistance: 15,
            includePassableBlocks: true,
        });
        if (blockView != undefined) {
            const blockLocation = blockView.block.location;
            sourceEntity.runCommand(`fill ${blockLocation.x} ${blockLocation.y} ${blockLocation.z} ${blockLocation.x} ${blockLocation.y} ${blockLocation.z} air destroy`);
        }
    });


}

function handleTest(sourceEntity) {
    if (sourceEntity.getProperty("kt_ct:container_asphalth") > 0) {
        placeBlocksOnSides(sourceEntity, "kt_ct:asphalt");
        try {
            propertyUse(sourceEntity, property[1], { operation: "-", value: 1 });
        } catch (error) {
            sourceEntity.setProperty(property[1], 0);
        }
    }
}

function viewFuelPercentage(sourceEntity, typeId) {
    if (cars[typeId]) {
        showFuelPercentageActionBar(sourceEntity, "kt_ct:fuel", cars[typeId].fuel);
    }
}

function checkGenerator(sourceEntity, location) {
    sourceEntity.dimension.getEntities({ type: "kt_ct:generator_block", location, maxDistance: 10, minDistance: 1 }).forEach((victim) => {
        createParticleLine(location, victim.location, "minecraft:villager_happy", sourceEntity);
        if (sourceEntity.getProperty(property[0]) > 0 && victim.getProperty(property[0]) < 1000) {
            try {
                victim.setProperty(property[0], victim.getProperty(property[0]) + sourceEntity.getProperty(property[0]));
            } catch (error) {
                return;
            }
            sourceEntity.setProperty(property[0], 0);
        }
    });
}

function viewEnergy(sourceEntity, location) {
    try {
        sourceEntity.dimension.getEntities({ type: "minecraft:player", location, maxDistance: 5, minDistance: 0 }).forEach((player) => {
            player.getEntitiesFromViewDirection({ maxDistance: 5 }).forEach((victim) => {
                if (victim.entity.typeId == entityBlocks[0]) {
                    player.onScreenDisplay.setActionBar("Energy being transmitted");
                }
            });
        });
    } catch (error) {
        return;
    }
}

function checkConcreteMixer(sourceEntity, location) {
    try {
        sourceEntity.dimension.getEntities({ type: entityBlocks[1], location, maxDistance: 10, minDistance: 1 }).forEach((victim) => {
            createParticleLine(location, victim.location, "minecraft:redstone_torch_dust_particle", sourceEntity);
            if (sourceEntity.getProperty(property[0]) > 0 && victim.getProperty(property[0]) < 1200) {
                propertyUse(victim, property[0], { operation: "+", value: 5 });
                propertyUse(sourceEntity, property[0], { operation: "-", value: 5 });
            }
        });
    } catch (error) {
        return;
    }
}





const items = {
    "minecraft:dirt": {},
    "minecraft:sand": {},
    "kt_ct:cement": {},
    "kt_ct:asphalt": {},
};

const cars = {
    "kt_ct:ct_vehicle": {
        fuel: 900,
    },
    "kt_ct:dt_vehicle": {
        fuel: 600,
    },
    "kt_ct:lt_vehicle": {
        fuel: 1200,
    },
    "kt_ct:pickup_vehicle": {
        fuel: 1000,
    },
    "kt_ct:rr_vehicle": {
        fuel: 900,
    },
    "kt_ct:wl_vehicle": {
        fuel: 700,
    },
    "kt_ct:fl_vehicle": {
        fuel: 900,
    },
};

const property = ["kt_ct:energy", "kt_ct:container_asphalth"];

const entityBlocks = [
    "kt_ct:generator_block",
    "kt_ct:cm_block",
    "kt_ct:palette_block",
];

let hasJumping = false;

const handlePlayersAndVehicles = () => {
    world.getAllPlayers().forEach((player) => {
        if (player.isJumping && !hasJumping) {
            handleJumping(player);
            hasJumping = true;
        }
        if (!player.isJumping && hasJumping) {
            hasJumping = false;
        }
    });
};

const handleJumping = (player) => {
    player.dimension.getEntities({
        maxDistance: 6,
        minDistance: 0,
        location: player.location,
        tags: ["has_rider"],
    }).forEach((victim) => {
        if (victim.typeId == "kt_ct:lt_vehicle" || victim.typeId == "kt_ct:dt_vehicle") {
            handleVehicleItemCollection(victim);
        }
        if (victim.typeId == "kt_ct:fl_vehicle") {
            const viewDirection = victim.getViewDirection();
            const relativeLocation = {
                x: victim.location.x + viewDirection.x * 3,
                y: victim.location.y,
                z: victim.location.z + viewDirection.z * 3,
            };
            if (victim.getProperty("kt_ct:items") == 0) {
                victim.dimension
                    .getEntities({
                        maxDistance: 10,
                        minDistance: 0,
                        location: victim.location,
                        closest: 3,
                    })
                    .forEach((entityTransport) => {
                        if (entityTransport.typeId == "kt_ct:palette_block") {
                            victim.setProperty("kt_ct:items", 1);
                            entityTransport.remove();
                        }else if (entityTransport.typeId == "kt_ct:box_long_block") {
                            victim.setProperty("kt_ct:items", 2);
                            entityTransport.remove();
                        }else if (entityTransport.typeId == "kt_ct:box_squared_big_block") {
                            victim.setProperty("kt_ct:items", 3);
                            entityTransport.remove();
                        }else if (entityTransport.typeId == "kt_ct:box_squared_small_block") {
                            victim.setProperty("kt_ct:items", 4);
                            entityTransport.remove();
                        }else if (entityTransport.typeId == "kt_ct:big_box_block") {
                            victim.setProperty("kt_ct:items", 5);
                            entityTransport.remove();
                        }else if (entityTransport.typeId == "kt_ct:small_box_block") {
                            victim.setProperty("kt_ct:items", 9);
                            entityTransport.remove();
                        }else if (entityTransport.typeId == "kt_ct:thread_roll_block") {
                            victim.setProperty("kt_ct:items", 10);
                            entityTransport.remove();
                        }
                    });
            }
            if (victim.getProperty("kt_ct:items") == 1) {
                let rpaz = victim.dimension.getEntities({
                    maxDistance: 4,
                    minDistance: 0,
                    location: victim.location,
                    families: ["transport"],
                });
                if (rpaz.length > 0) {
                    rpaz.forEach((entityTransport) => {
                        /** @type {EntityInventoryComponent} */
                        const inventory2 =
                            entityTransport.getComponent(
                                "inventory"
                            );

                        if (
                            entityTransport.typeId ==
                            "kt_ct:box_long_block"
                        ) {
                            victim.triggerEvent(
                                "inventory_box_long"
                            );
                            victim.setProperty("kt_ct:items", 2);

                            /** @type {EntityInventoryComponent} */
                            let inventoryRpaz =
                                victim.getComponent("inventory");

                            for (
                                let index = 0;
                                index < 27;
                                index++
                            ) {
                                inventory2.container.transferItem(
                                    index,
                                    inventoryRpaz.container
                                );
                            }

                            entityTransport.remove();
                        } else if (
                            entityTransport.typeId ==
                            "kt_ct:box_squared_big_block"
                        ) {
                            
                            victim.setProperty("kt_ct:items", 3);
                            victim.triggerEvent(
                                "inventory_box_squared_big"
                            );
                            /** @type {EntityInventoryComponent} */
                            let inventoryRpaz =
                                victim.getComponent("inventory");

                            for (
                                let index = 0;
                                index < 18;
                                index++
                            ) {
                                inventory2.container.transferItem(
                                    index,
                                    inventoryRpaz.container
                                );
                            }
                            entityTransport.remove();
                        } else if (
                            entityTransport.typeId ==
                            "kt_ct:box_squared_small_block"
                        ) {
                            victim.setProperty("kt_ct:items", 4);
                            victim.triggerEvent(
                                "inventory_box_squared_small"
                            );
                            /** @type {EntityInventoryComponent} */
                            let inventoryRpaz =
                                victim.getComponent("inventory");

                            for (
                                let index = 0;
                                index < 5;
                                index++
                            ) {
                                inventory2.container.transferItem(
                                    index,
                                    inventoryRpaz.container
                                );
                            }
                            entityTransport.remove();
                        } else if (
                            entityTransport.typeId ==
                            "kt_ct:big_box_block"
                        ) {
                            victim.setProperty("kt_ct:items", 5);
                            victim.triggerEvent(
                                "inventory_big_box"
                            );
                            /** @type {EntityInventoryComponent} */
                            let inventoryRpaz =
                                victim.getComponent("inventory");

                            for (
                                let index = 0;
                                index < 18;
                                index++
                            ) {
                                inventory2.container.transferItem(
                                    index,
                                    inventoryRpaz.container
                                );
                            }
                            entityTransport.remove();
                        } else if (
                            entityTransport.typeId ==
                            "kt_ct:oil_barrel_block"
                        ) {
                            victim.setProperty("kt_ct:items", 6);
                            entityTransport.remove();
                        } else if (
                            entityTransport.typeId ==
                            "kt_ct:pipes_riolen_block"
                        ) {
                            victim.setProperty("kt_ct:items", 7);
                            entityTransport.remove();
                        } else if (
                            entityTransport.typeId ==
                            "kt_ct:pipes_small_block"
                        ) {
                            victim.setProperty("kt_ct:items", 8);
                            entityTransport.remove();
                        } else if (
                            entityTransport.typeId ==
                            "kt_ct:small_box_block"
                        ) {
                            victim.setProperty("kt_ct:items", 9);
                            entityTransport.remove();
                        }else if (entityTransport.typeId == "kt_ct:thread_roll_block") {
                            victim.setProperty("kt_ct:items", 10);
                            entityTransport.remove();
                        }                        
                    });
                }else if (victim.getProperty("kt_ct:items") == 1) {
                    victim.dimension.spawnEntity("kt_ct:palette_block", relativeLocation);
                    victim.setProperty("kt_ct:items", 0);
                }                
            }
            if (victim.getProperty("kt_ct:items") > 1) {
                /** @type {EntityInventoryComponent} */
                let inventoryRpaz =
                    victim.getComponent("inventory");
                switch (victim.getProperty("kt_ct:items")) {
                    case 2: {
                        let inventory2 = victim.dimension
                            .spawnEntity(
                                "kt_ct:box_long_block",
                                relativeLocation
                            )
                            .getComponent("inventory");
                        for (let index = 0; index < 27; index++) {
                            inventoryRpaz.container.transferItem(
                                index,
                                inventory2.container
                            );
                        }
                        victim.setProperty("kt_ct:items", 1);

                        victim.triggerEvent("remove_inventory");
                        break;
                    }
                    case 3: {
                        let inventory2 = victim.dimension
                            .spawnEntity(
                                "kt_ct:box_squared_big_block",
                                relativeLocation
                            )
                            .getComponent("inventory");
                        for (let index = 0; index < 18; index++) {
                            inventoryRpaz.container.transferItem(
                                index,
                                inventory2.container
                            );
                        }
                        victim.setProperty("kt_ct:items", 1);
                        victim.triggerEvent("remove_inventory");
                        break;
                    }
                    case 4: {
                        let inventory2 = victim.dimension
                            .spawnEntity(
                                "kt_ct:box_squared_small_block",
                                relativeLocation
                            )
                            .getComponent("inventory");
                        for (let index = 0; index < 5; index++) {
                            inventoryRpaz.container.transferItem(
                                index,
                                inventory2.container
                            );
                        }
                        victim.setProperty("kt_ct:items", 1);
                        victim.triggerEvent("remove_inventory");
                        break;
                    }
                    case 5: {
                        let inventory2 = victim.dimension
                            .spawnEntity(
                                "kt_ct:big_box_block",
                                relativeLocation
                            )
                            .getComponent("inventory");
                        for (let index = 0; index < 18; index++) {
                            inventoryRpaz.container.transferItem(
                                index,
                                inventory2.container
                            );
                        }
                        victim.setProperty("kt_ct:items", 1);
                        victim.triggerEvent("remove_inventory");
                        break;
                    }
                    case 6: {
                        victim.dimension.spawnEntity(
                            "kt_ct:oil_barrel_block",
                            relativeLocation
                        );
                        victim.setProperty("kt_ct:items", 1);
                        victim.triggerEvent("remove_inventory");
                        break;
                    }
                    case 7: {
                        victim.dimension.spawnEntity(
                            "kt_ct:pipes_riolen_block",
                            relativeLocation
                        );
                        victim.setProperty("kt_ct:items", 1);
                        victim.triggerEvent("remove_inventory");
                        break;
                    }
                    case 8: {
                        victim.dimension.spawnEntity(
                            "kt_ct:pipes_small_block",
                            relativeLocation
                        );
                        victim.setProperty("kt_ct:items", 1);
                        victim.triggerEvent("remove_inventory");
                        break;
                    }
                    case 9: {
                        victim.dimension.spawnEntity(
                            "kt_ct:small_box_block",
                            relativeLocation
                        );
                        victim.setProperty("kt_ct:items", 1);
                        victim.triggerEvent("remove_inventory");
                        break;
                    }
                    case 10: {
                        victim.dimension.spawnEntity(
                            "kt_ct:thread_roll_block",
                            relativeLocation
                        );
                        victim.setProperty("kt_ct:items", 1);
                        victim.triggerEvent("remove_inventory");
                        break;
                    }
                    
                }
            }
        }
    });
};

const handleVehicleItemCollection = (vehicle) => {
    /** @type {EntityInventoryComponent} */
    const inventory = vehicle.getComponent("inventory");
    for (let i = 0; i < inventory.container.size; i++) {
        let slot = inventory.container.getSlot(i)
        if (slot.isValid()) {
            const itemStack = slot;
            if (itemStack instanceof ItemStack) {
                const distanceBehind = inventory.container.size === 27 ? 15 : 8;
                const { x, y, z } = calculateSpawnPosition(vehicle, distanceBehind);
                vehicle.dimension.spawnItem(itemStack, { x, y, z });
                vehicle.runCommand("function ent/cons/drop");
            }
        }
    }
    inventory.container.clearAll();
};

const calculateSpawnPosition = (vehicle, distanceBehind) => {
    const { x, y, z } = vehicle.location;
    const entityRotation = vehicle.getRotation();
    const radians = entityRotation.y * (Math.PI / 180);
    const spawnX = x + Math.sin(radians) * distanceBehind;
    const spawnY = y;
    const spawnZ = z - Math.cos(radians) * distanceBehind;
    return { x: spawnX, y: spawnY, z: spawnZ };
};

const handleVehiclesInOverworld = () => {
    const overworldEntities = world.getDimension("overworld").getEntities();
    overworldEntities.forEach((entity) => {
        if (entity.typeId.includes("vehicle")) {
            handleVehicle(entity);
        }
    });
};

const handleVehicle = (entity) => {
    // Verifica e atualiza a propriedade de luz do veículo com base no tempo do dia
    if (entity.typeId.includes("vehicle")) {
        const isDaytime = world.getTimeOfDay() <= 12000;
        const currentLightState = entity.getProperty("kt_ct:light");
        const desiredLightState = isDaytime ? 0 : 1;

        if (currentLightState !== desiredLightState) {
            entity.setProperty("kt_ct:light", desiredLightState);
        }

        // Verifica e atualiza o inventário do veículo "kt_ct:rr_vehicle"
        if (entity.typeId === "kt_ct:rr_vehicle") {
            updateAsphaltInventory(entity);
        }
    }
};

/**
 * 
 * @param {Entity} vehicle 
 */
const updateAsphaltInventory = (vehicle) => {
    /** @type {EntityInventoryComponent} */
    let inventory = vehicle.getComponent("inventory");
    if (inventory.container.isValid()) {
        for (let i = 0; i < inventory.container.size; i++) {
            let itemStack = inventory.container.getItem(i);
            if (itemStack != undefined) {
                if (itemStack.typeId == "kt_ct:asphalt") {
                    const currentAsphaltAmount = vehicle.getProperty("kt_ct:container_asphalth");
                    const newAsphaltAmount = currentAsphaltAmount + itemStack.amount;
                    vehicle.setProperty("kt_ct:container_asphalth", newAsphaltAmount);
                    vehicle.runCommand(`replaceitem entity @s slot.inventory ${i} minecraft:air`);
                }
            }
        }
    }
};

system.runInterval(() => {
    handlePlayersAndVehicles();
    handleVehiclesInOverworld();
});

system.afterEvents.scriptEventReceive.subscribe((event) => {
    const { sourceEntity, id, message } = event;
    try {
        /** @type {EntityInventoryComponent} */
        const inventory = sourceEntity.getComponent("inventory");
        const rotation = sourceEntity.getRotation();
        const location = sourceEntity.location;
        const typeId = sourceEntity.typeId;

        switch (id) {
            case "kt:colletion": {
                ktColletion(sourceEntity, inventory, location, typeId);
                break;
            }
            case "kt:handleWl": {
                handleWlVehicle(sourceEntity, location, rotation);
                break;
            }
            case "kt:hExcavator": {
                handleExcavator(sourceEntity, location, rotation)
                break;
            }
            case "kt:hCrane": {
                handleCraneVehicle(sourceEntity, location, rotation);
                break;
            }
            case "kt:f_l": {
                handleAlturaA(sourceEntity, location, rotation);
                break;
            }
            case "a:test": {
                handleTest(sourceEntity);
                break;
            }
            case "a:drop_cement": {
                add_items_inventory("kt_ct:cement", sourceEntity, inventory);
                break;
            }
            case "a:drop_asphalt": {
                add_items_asphalt("kt_ct:asphalt", sourceEntity, inventory);
                break;
            }
            case "a:view_fuel": {
                viewFuelPercentage(sourceEntity, typeId);
                break;
            }
            case "a:check_generator": {
                checkGenerator(sourceEntity, location);
                break;
            }
            case "a:view_energy": {
                viewEnergy(sourceEntity, location);
                break;
            }
            case "a:check_cmixer": {
                checkConcreteMixer(sourceEntity, location);
                break;
            }

        }
    } catch (error) {
        return;
    }
});

world.afterEvents.entitySpawn.subscribe((event) => {
    const { entity, cause } = event;
    try {
        if (entity.typeId == "kt_ct:rr_vehicle") {
            if (entity.nameTag == "")
                entity.nameTag = ` §6Insert asphalt blocks§r`;
            else
                entity.nameTag = `${entity.nameTag}\n §6Insert asphalt blocks§r`;
        }
        if (entity.getProperty("kt_cl:inventory")) {
            if (entity.nameTag == "ent_co:asphalt_driller")
                entity.nameTag = ` §6Press open §ainventory§r`;
            else
                entity.nameTag = `${entity.nameTag}\n §6Press open §ainventory§r`;
        }
        if (entity.getProperty("kt_ct:pick")) {
            if (entity.nameTag == "")
                entity.nameTag = `§6Press SPACE to pick up\n§6Press SPACE to place§r`;
            else
                entity.nameTag = `${entity.nameTag}\n§6Press SPACE to pick up\n§6Press SPACE to place§r`;
        }
    } catch (error) {
        return;
    }
    if (entity.typeId.includes("vehicle"))
        entity.runCommand("playsound spawn.vehicle @a[r=10]");
});

const getItem = (source) => {
    /**
     * @type {EntityEquippableComponent}
     */
    const hascomponetWquippable = source.hasComponent('minecraft:equippable');
    if (source && source.typeId === "minecraft:player" && hascomponetWquippable) {
        const componet = source.getComponent('minecraft:equippable');
        if (componet.getEquipment(EquipmentSlot.Mainhand) != undefined) {
            return componet.getEquipment(EquipmentSlot.Mainhand);
        }
        else {
            return new ItemStack('minecraft:stick', 1)
        }
    }
}

const events = [
    "kt_ct:deactivative",
    "kt_ct:refuel",
    "kt_ct:reoil",
    "kt_ct:active",
    "kt_ct:color_red",
    "kt_ct:color_blue",
    "kt_ct:color_yellow",
    "kt_ct:color_default"
]

const sounds = [
    "desactive.vehicle",
    "refueled.vehicle",
]

/**
 * 
 * @param {Entity} source
 * @param {string} event 
 * @param {Array} sound 
 * @param {ItemStack} spawnItem
 */
function hitEntityAction(source, event, sound) {
    if (source != undefined) {
        source.triggerEvent(event);
        if (sound != undefined) {
            source.runCommand(`playsound ${sound} @a[r=10]`)
        }
    }
}

function damagingEntityAction(source, sound, actionbar, removeItem, addItem) {
    if (source != undefined) {
        if (sound != undefined) {
            source.runCommand(`playsound ${sound} @a[r=10]`)
        }
        if (actionbar != undefined && actionbar != '') {
            source.onScreenDisplay.setActionBar(actionbar);
        }
        if (removeItem != undefined && removeItem != '') {
            source.runCommand(`clear @s ${removeItem} 0 1`);
        }
        if (addItem != undefined && addItem != '') {
            source.runCommand(`clear @s ${addItem} 1`);
        }
    }
}

world.afterEvents.entityHitEntity.subscribe((event) => {
    const { damagingEntity, hitEntity } = event;
    const mainhandItem = getItem(damagingEntity);
    if (hitEntity.hasComponent("minecraft:variant")) {
        const variant = hitEntity.getComponent("minecraft:variant").value;
        if (mainhandItem.typeId == "kt_cl:keys" && variant == 0) {
            hitEntity.triggerEvent(events[3]);
            hitEntity.runCommand("playsound active.vehicle @a[r=10]");
            if (hitEntity.typeId == 'kt_ct:crane_vehicle')
                damagingEntity.runCommand('give @s kt_ct:changing_seats 1')
        } else if (mainhandItem.typeId == "minecraft:stick" && variant == 1) {
            if (hitEntity.getProperty("kt_ct:head") != undefined) {
                hitEntity.setProperty("kt_ct:head", 0);
            }
            if (hitEntity.getProperty("kt_ct:headx") != undefined) {
                hitEntity.setProperty("kt_ct:headx", 0);
            }
            if (hitEntity.typeId == 'kt_ct:crane_vehicle')
                damagingEntity.runCommand('clear @s kt_ct:changing_seats 0 1')
            hitEntityAction(hitEntity, events[0], sounds[0])

        }
    }

    if (damagingEntity.typeId == "minecraft:player" && hitEntity.typeId.includes("vehicle")) {
        const locationHitEntity = hitEntity.location;
        if (mainhandItem.typeId == "kt_cl:fuel") {

            hitEntityAction(hitEntity, events[1])
            damagingEntityAction(damagingEntity, sounds[1], "Vehicle refueled!", "kt_cl:fuel")

        } else if (mainhandItem.typeId == "kt_cl:oil") {

            hitEntityAction(hitEntity, events[2])
            damagingEntityAction(damagingEntity, "reoiled.vehicle", "Oil level OK", "kt_cl:oil");

        } else if (mainhandItem.typeId == "kt_cl:remove_vehicle") {
            damagingEntity.runCommand(
                "playsound removetool.vehicle @a[r=4]"
            );
            const itemStack = new ItemStack(
                hitEntity.typeId + "_spawn_egg",
                1
            );
            hitEntity.remove();
            damagingEntity.dimension.spawnItem(
                itemStack,
                locationHitEntity
            );
            damagingEntity.runCommand(
                "stopsound @s"
            );
        } else if (mainhandItem.typeId == "kt_cl:colors") {
            damagingEntity.runCommand(
                "playsound colortool.vehicle @a[r=4]"
            );
            switch (hitEntity.getComponent("minecraft:skin_id").value) {
                case 0: {
                    hitEntity.triggerEvent(events[4]);
                    break;
                }
                case 1: {
                    hitEntity.triggerEvent(events[5]);
                    break;
                }
                case 2: {
                    hitEntity.triggerEvent(events[6]);
                    break;
                }
                case 3: {
                    hitEntity.triggerEvent(events[7]);
                    break;
                }
            }
        } else if (mainhandItem.typeId == "kt_ct:changing_seats") {
            if (hitEntity.typeId == 'kt_ct:crane_vehicle' && hitEntity.getProperty('kt_ct:seat') == 0) {
                hitEntity.triggerEvent('kt_ct:other_seat')
                damagingEntity.onScreenDisplay.setActionBar(`[§9${damagingEntity.nameTag}§r] §6Seat replaced for cabin with wrecking ball§r`);
                damagingEntity.playSound("random.pop");
            } else if (hitEntity.typeId == 'kt_ct:crane_vehicle' && hitEntity.getProperty('kt_ct:seat') == 1) {
                hitEntity.triggerEvent('kt_ct:prime_seat')
                damagingEntity.onScreenDisplay.setActionBar(`[§9${damagingEntity.nameTag}§r] §6Seat changed for vehicle controller's cabin§r`)
                damagingEntity.playSound("random.pop")
            } else return
        }
    }
});

