import { world, system, EntityComponentTypes, GameMode } from "@minecraft/server";
import { removeFromHeldItemStack } from "./helper";
import { startTrackingBouncyToy } from "./fetching";
import * as forms from "./forms";

// Dog Treats
world.beforeEvents.playerInteractWithEntity.subscribe((e) => {
    const { player, target, itemStack } = e;

    if (!target.isValid) return; // Invalid entity

    if (!itemStack || !itemStack.hasTag("oct_dogs:is_dog_treat")) return; // No treat

    if (!target.getComponent(EntityComponentTypes.TypeFamily)?.hasTypeFamily("oct_dogs:dog")) return; // Not a dog

    // Cancel interaction
    e.cancel = true;

    const isOwnDog = target.getComponent(EntityComponentTypes.Tameable)?.tamedToPlayer === player;

    system.run(() => {
        if (isOwnDog) {
            //world.sendMessage(`This is my dog!`);
            forms.openTrickMenu(player, target);
        }
        removeFromHeldItemStack(player, itemStack, 1);
        player.dimension.playSound("random.eat", target.location);
    })
});

// Dog Toys
class OctThrowableToy {
    static initialize(event) {
        event.itemComponentRegistry.registerCustomComponent("oct_dogs:throwable_toy", new this());
    }

    onUse(e, p) {
        const player = e.source;
        const itemStack = e.itemStack;
        const { projectile_entity, speed_multiplier = 1, y_velocity = 0 } = p.params;

        const viewDirection = player.getViewDirection();
        const HeadLocation = player.getHeadLocation();

        // Spawn projectile entity
        try {
            const projectile = player.dimension.spawnEntity(
                projectile_entity,
                { x: HeadLocation.x, y: HeadLocation.y - 0.2, z: HeadLocation.z }
            );
            const impulse = {
                x: viewDirection.x * speed_multiplier,
                y: (viewDirection.y * speed_multiplier) + y_velocity,
                z: viewDirection.z * speed_multiplier
            };

            // Shoot projectile entity
            projectile.setRotation(viewDirection);
            projectile.applyImpulse(impulse);
            projectile.setProperty("oct_dogs:is_flying", true);
            startTrackingBouncyToy(projectile, p.params);

            // Sounds
            switch (itemStack.typeId) {
                case "oct_dogs:ball":
                    player.dimension.playSound("oct_dogs.dog_toy.ball.throw", player.location);
                    break;
                case "oct_dogs:tennis_ball":
                    player.dimension.playSound("oct_dogs.dog_toy.ball.throw", player.location);
                    break;
                case "oct_dogs:frisbee":
                    player.dimension.playSound("oct_dogs.dog_toy.frisbee.throw", player.location);
                    break;
                case "oct_dogs:chewy_bone":
                    player.dimension.playSound("oct_dogs.dog_toy.ball.throw", player.location);
                    player.dimension.playSound("oct_dogs.dog_toy.squeaky.throw", player.location);
                    break;
            }

            // Clear Ball item
            removeFromHeldItemStack(player, itemStack, 1);

        } catch (e) {
            return;
        }

        // Start creative fetching
        if (player.getGameMode() === GameMode.Creative) {
            player.fetchingManager?.startCreativeFetching();
        }
    }

}

class OctGuidebook {
    static initialize(event) {
        event.itemComponentRegistry.registerCustomComponent("oct_dogs:guidebook", new this());
    }
    onUse(e) { forms.openGuidebookMenu(e.source) };
}

// Register objects
system.beforeEvents.startup.subscribe(event => {
    OctThrowableToy.initialize(event);
    OctGuidebook.initialize(event);
});