import * as mc from "@minecraft/server";
import { add_items } from "./machines/add_items";
import "./machines/chest_open";
import { machines, drillPlace, factoryPlace } from "./machines/machines";
import * as connectable from "./blocks/connectable";
import { Vec3 } from "./Vec3";
import { guideBook } from "./machines/forms";
import * as redstoneCapsule from "./items/redstoneCapsule";
import * as redstoneGolem from "./entities/redstoneGolem";
import * as itemConveyor from "./blocks/item_conveyor";

mc.system.afterEvents.scriptEventReceive.subscribe((eventData) => {
    const { id, sourceEntity, message } = eventData;

    add_items(eventData);
    machines(id, sourceEntity, message);
});
mc.world.afterEvents.entityHitEntity.subscribe((data) => {
    const damaged = data.hitEntity;
    const player = data.damagingEntity;
    const equippable = player.getComponent("equippable");
    const item = equippable?.getEquipmentSlot("Mainhand")?.getItem();

    if (player.typeId === `minecraft:player` && item && item.typeId === `cy_cr:redstone_capsule`) {
        redstoneCapsule.captureMob(player, damaged, item, equippable);
    }
});
mc.world.beforeEvents.itemUseOn.subscribe((data) => {
    const item = data.itemStack;
    const player = data.source;
    const block = data.block;

    if (item.typeId === `cy_cr:redstone_capsule`) {
        redstoneCapsule.releaseMob(player, item, block)
    };

    if (item.typeId === `cy_cr:drill_spawn_egg` && block) {
        drillPlace(player, block, data)
    }
});
mc.world.afterEvents.entitySpawn.subscribe((data) => {
    const entity = data.entity;
    if (entity?.typeId.startsWith(`cy_cr:`) && (entity?.typeId.includes(`farm`) || entity?.typeId.includes(`factory`) || entity?.typeId.includes(`propulser`) || entity?.typeId.includes(`trap`) || entity?.typeId.includes(`furnace`))) {
        factoryPlace(entity)
    }
});
//Give Guide Book
mc.world.afterEvents.playerSpawn.subscribe((data) => {
    const player = data.player;

    if (player?.isValid() === true) {
        if (!player?.hasTag(`cy_cr:guide_book`)) {
            const inv = player?.getComponent("inventory").container;
            player?.addTag(`cy_cr:guide_book`);
            inv?.addItem(new mc.ItemStack(`cy_cr:guide_book`));
            inv?.addItem(new mc.ItemStack(`cy_cr:redstone_capsule`))
        }
    }
});
//Use Guide Book
mc.world.afterEvents.itemUse.subscribe((data) => {
    const player = data.source;
    const item = data.itemStack;

    if (item?.typeId === `cy_cr:guide_book`) {
        guideBook(player)
    }
});
//Redstone Golem damage
mc.world.afterEvents.entityHurt.subscribe((data) => {
    const damager = data.damageSource.damagingEntity;
    const damaged = data.hurtEntity;
    const damage = data.damage;

    if (damager?.typeId === `cy_cr:redstone_golem`) {
        redstoneGolem.onDamage(damaged);
    };
    if (damaged && damaged?.typeId === `cy_cr:redstone_golem`) {
        redstoneGolem.onHurt(damaged, damage);
    }
});
//Custom Components
mc.world.beforeEvents.worldInitialize.subscribe((data) => {
    data.blockComponentRegistry.registerCustomComponent(`cy_cr:connectable`, {
        onPlace: data => {
            const block = data.block;
            mc.system.runTimeout(() => {
                if (block?.isValid() === true) {
                    const placed = block.permutation.getState(`cy_cr:placed`) || false;
                    if (placed === false) {
                        connectable.onPlace(block);
                    }
                }
            }, 2)
        },
        onPlayerDestroy: data => {
            const block = data.block;
            const perm = data.destroyedBlockPermutation;
            connectable.onDestroy(block, perm)
        }
    });
    data.blockComponentRegistry.registerCustomComponent(`cy_cr:item_conveyor`, {
        onTick: (data) => {
            const block = data.block;
            itemConveyor.onTick(block);
        }
    });
});
mc.world.afterEvents.projectileHitBlock.subscribe((data) => {
    const entity = data.projectile;

    if (entity.typeId === `cy_cr:tnt_projectile`) {
        entity.triggerEvent(`cy_cr:explode`)
    }
});
mc.world.afterEvents.projectileHitEntity.subscribe((data) => {
    const entity = data.projectile;

    if (entity.typeId === `cy_cr:tnt_projectile`) {
        entity.triggerEvent(`cy_cr:explode`)
    }
});