import { Direction, system } from "@minecraft/server";
import { reflectVec } from "../util/mthUtils";
import { getItemInHand, pushEntity, shrinkIfInSurvival } from "../util/miscUtils";
import { flipDir, getADirection, isSameAxis, offsetPos } from "../util/dirUtils";
import { SuppStates } from "../reg/suppStates";
import { SuppTags } from "../reg/suppTags";
import { McStates } from "../reg/mcStates";
import { isReplaceable } from "../util/blockProperties";
const getNormalVector = (block) => {
    const slanted = block.permutation.getState(SuppStates.Tilted);
    if (!slanted) {
        return { x: 0, y: 1, z: 0 };
    }
    const dir = getADirection(block);
    switch (dir) {
        case Direction.North:
            return { x: 0, y: 0.924, z: -0.383 };
        case Direction.South:
            return { x: 0, y: 0.924, z: 0.383 };
        case Direction.East:
            return { x: 0.383, y: 0.924, z: 0 };
        case Direction.West:
            return { x: -0.383, y: 0.924, z: 0 };
    }
};
export const AwningFallComponent = {
    onEntityFallOn(event) {
        const block = event.block;
        const entity = event.entity;
        if (!entity || entity.isSneaking)
            return;
        if (event.fallDistance > 2) {
            //this is called after entity speed is reset..
            let speed = entity.getVelocity();
            speed = { x: 0, y: -Math.sqrt(0.08 * 2 * event.fallDistance), z: 0 };
            const reflected = reflectVec(speed, getNormalVector(block));
            event.dimension.playSound("razz_sup.awning.bounce", block.center());
            //check if entity instance of player because they didnt implement the clean below for player and those are better...
            pushEntity(entity, reflected);
        }
    },
    //maybe move to event so we can place blocks normally against ita
    onPlayerInteract(event) {
        if (!event.player)
            return;
        const item = getItemInHand(event.player);
        if (!item) {
            let block = event.block;
            let isTilted = block.permutation.getState(SuppStates.Tilted);
            block.setPermutation(block.permutation.withState(SuppStates.Tilted, !isTilted));
            event.dimension.playSound("dig.cloth", block.center(), { pitch: isTilted ? 1.4 : 1.2, volume: 0.8 });
        }
    },
    beforeOnPlayerPlace(event) {
        const block = event.block;
        const dir = event.face;
        const behindDir = flipDir(dir);
        const behindBlock = offsetPos(block, behindDir);
        if (behindBlock && behindBlock.hasTag(SuppTags.Awnings)) {
            const tilted = behindBlock.permutation.getState(SuppStates.Tilted);
            if (!tilted)
                return;
            const behindDir = getADirection(behindBlock);
            const verticalHalf = behindBlock.permutation.getState(McStates.VerticalHalf);
            if (isSameAxis(behindDir, dir)) {
                if (verticalHalf == "top") {
                    event.permutationToPlace = event.permutationToPlace
                        .withState(SuppStates.Tilted, tilted)
                        .withState(McStates.VerticalHalf, "bottom");
                }
                else if (verticalHalf == "bottom") {
                    const below = block.below();
                    if (below && isReplaceable(below)) {
                        event.cancel = true;
                        system.run(() => {
                            below.setPermutation(event.permutationToPlace
                                .withState(SuppStates.Tilted, tilted)
                                .withState(McStates.VerticalHalf, "top"));
                            shrinkIfInSurvival(event.player, getItemInHand(event.player));
                        });
                    }
                }
            }
        }
    }
};
