import { Direction, EntityInitializationCause, TicksPerSecond, system, world } from "@minecraft/server";
import EntityManager from "../EntityManager";
import FSEntityHelper from "../fs/FSEntityHelper";
import FSMemoryProperty from "../fs/libs/FSMemoryProperty";
import { FSCompassDirection } from "../fs/FSCompassDirection";
import { RAYCAST_MAX_DISTANCE } from "../fs/FSConstants";
import PlayerHelper from "../PlayerHelper";
import FSLocalizedString from "../fs/FSLocalizedString";
import FSDynamicProperty from "../fs/libs/FSDynamicProperty";
import FSUtil from "../fs/FSUtil";
import FSMath from "../fs/FSMath";
import SecretEntranceBlockData from "./SecretEntranceBlockData";
import FSInventoryManager from "../fs/libs/FSInventoryManager";
import FSPlayer from "../fs/FSPlayer";
export default class SecretEntrance {
    static init(entity, spawnCause) {
        SecretEntrance.initSpawnedEntity(entity, spawnCause);
    }
    static initSpawnedEntity(entity, spawnCause) {
        const block_variant_location = `block_variant_${Math.round(entity.location.x)}_${Math.round(entity.location.y)}_${Math.round(entity.location.z)}`;
        const compass_direction_location = `compass_direction_${Math.round(entity.location.x)}_${Math.round(entity.location.y)}_${Math.round(entity.location.z)}`;
        if (spawnCause !== EntityInitializationCause.Transformed && !entity.hasComponent("minecraft:is_charged")) {
            FSEntityHelper.snapRotation(entity);
            const block_variant = entity.getProperty("property:fs_sbunk_block_variant");
            FSMemoryProperty.setNumber(world, block_variant_location, block_variant);
            const compass_direction = FSEntityHelper.getCompassDirection(entity);
            let event = "fs:facing_south";
            switch (compass_direction) {
                case FSCompassDirection.South:
                    entity.setProperty("property:fs_sbunk_compass_direction", 0);
                    FSMemoryProperty.setNumber(world, compass_direction_location, 0);
                    event = "fs:set_facing_south";
                    break;
                case FSCompassDirection.West:
                    entity.setProperty("property:fs_sbunk_compass_direction", 1);
                    FSMemoryProperty.setNumber(world, compass_direction_location, 1);
                    event = "fs:set_facing_west";
                    break;
                case FSCompassDirection.North:
                    entity.setProperty("property:fs_sbunk_compass_direction", 2);
                    FSMemoryProperty.setNumber(world, compass_direction_location, 2);
                    event = "fs:set_facing_north";
                    break;
                case FSCompassDirection.East:
                    entity.setProperty("property:fs_sbunk_compass_direction", 3);
                    FSMemoryProperty.setNumber(world, compass_direction_location, 3);
                    event = "fs:set_facing_east";
                    break;
                default:
                    break;
            }
            entity.addTag("fs_sbunk:secret_entrance_transformed");
            entity.triggerEvent(event);
        }
        else {
            const block_variant = FSMemoryProperty.getNumber(world, block_variant_location);
            entity.setProperty("property:fs_sbunk_block_variant", block_variant);
            FSMemoryProperty.clearProperty(world, block_variant_location);
            const compass_direction = FSMemoryProperty.getNumber(world, compass_direction_location);
            entity.setProperty("property:fs_sbunk_compass_direction", compass_direction);
            FSMemoryProperty.clearProperty(world, compass_direction_location);
            system.runTimeout(() => {
                if (entity.isValid()) {
                    if (SecretEntrance.validateSurroundingBlocks(entity, -1)) {
                        SecretEntrance.onOpen(entity);
                    }
                    else {
                        SecretEntrance.popToItem(entity);
                    }
                }
            }, 1);
        }
    }
    static popToItem(entity) {
        entity.triggerEvent("fs:pop_to_item");
        SecretEntrance.sendInvalidPlacementMessage(entity);
        system.runTimeout(() => {
            entity.addTag("fs_sbunk:secret_entrance_transformed");
            entity.remove();
        }, 1);
    }
    static sendInvalidPlacementMessage(entity) {
        world.playSound("random.pop", entity.location);
        world.playSound("fs.sbunk.chat_ping", entity.location);
        const message = {
            rawtext: [
                { text: "§l§c" },
                {
                    translate: FSLocalizedString.localize("bunker.secret_entrance.invalid_placement.title", "Invalid Placement!", "Invalid placement title.")
                },
                { text: "§r " },
                {
                    translate: FSLocalizedString.localize("bunker.secret_entrance.invalid_placement.message", "Make sure all blocks match the type of entrance you want!", "Tip/instructions for placing secret doors.")
                }
            ]
        };
        world.sendMessage(message);
    }
    static onInteract(entity) {
        if (FSDynamicProperty.getBoolean(entity, "is_open")) {
            SecretEntrance.onClose(entity);
        }
        else {
            SecretEntrance.onOpen(entity);
        }
    }
    static getCloseAnimationTime(entity) {
        let close_animation_time = 0.1;
        if (entity.typeId === "57d_sbunk:secret_wall") {
            close_animation_time = 0.25;
        }
        else if (entity.typeId === "57d_sbunk:secret_floor") {
            close_animation_time = 0.25;
        }
        else if (entity.typeId === "57d_sbunk:secret_door") {
            close_animation_time = 0.1;
        }
        else if (entity.typeId === "57d_sbunk:secret_trapdoor") {
            close_animation_time = 0.1;
        }
        else if (entity.typeId === "57d_sbunk:secret_stairs") {
            close_animation_time = 0.25;
        }
        return close_animation_time;
    }
    static getFillAreaFrom(entity) {
        if (entity.typeId.indexOf("57d_sbunk:secret_wall") !== -1) {
            return { x: -1, y: 0, z: 0 };
        }
        else if (entity.typeId.indexOf("57d_sbunk:secret_floor") !== -1) {
            return { x: -1, y: 0, z: -1 };
        }
        else if (entity.typeId.indexOf("57d_sbunk:secret_door") !== -1) {
            return { x: 0, y: 0, z: 0 };
        }
        else if (entity.typeId.indexOf("57d_sbunk:secret_trapdoor") !== -1) {
            return { x: 0, y: 0, z: 0 };
        }
        return { x: 0, y: 0, z: 0 };
    }
    static getFillAreaTo(entity) {
        if (entity.typeId.indexOf("57d_sbunk:secret_wall") !== -1) {
            return { x: 1, y: 2, z: 0 };
        }
        else if (entity.typeId.indexOf("57d_sbunk:secret_floor") !== -1) {
            return { x: 1, y: 0, z: 1 };
        }
        else if (entity.typeId.indexOf("57d_sbunk:secret_door") !== -1) {
            return { x: 0, y: 1, z: 0 };
        }
        else if (entity.typeId.indexOf("57d_sbunk:secret_trapdoor") !== -1) {
            return { x: 0, y: 0, z: 0 };
        }
        return { x: 0, y: 0, z: 0 };
    }
    static validateSurroundingBlocks(entity, variant = -1, outputDebugMessage = false) {
        let valid = true;
        if (variant === -1) {
            variant = entity.getProperty("property:fs_sbunk_block_variant");
        }
        const blockDataSet = SecretEntranceBlockData.getBlockData();
        let blockData = undefined;
        for (let i = 0; i < blockDataSet.blocks.length; i++) {
            if (blockDataSet.blocks[i].block_variant === variant) {
                blockData = blockDataSet.blocks[i];
                break;
            }
        }
        if (entity.typeId === "57d_sbunk:secret_stairs") {
            if (blockData) {
                const name = blockData.name;
                const location0 = EntityManager.getLocationOffsetByRotation(entity, 0, 0, 0);
                const location1 = EntityManager.getLocationOffsetByRotation(entity, 0, 1, -1);
                const block0 = entity.dimension.getBlock(location0);
                const block1 = entity.dimension.getBlock(location1);
                const blockValid0 = block0 && block0.permutation.matches(name) ? true : false;
                const blockValid1 = block1 && block1.permutation.matches(name) ? true : false;
                valid = blockValid0 && blockValid1;
            }
        }
        else {
            if (blockData) {
                const name = blockData.name;
                const fill_area_from = SecretEntrance.getFillAreaFrom(entity);
                const fill_area_to = SecretEntrance.getFillAreaTo(entity);
                let index = 0;
                for (let x = fill_area_from.x; x <= fill_area_to.x; x++) {
                    for (let y = fill_area_from.y; y <= fill_area_to.y; y++) {
                        for (let z = fill_area_from.z; z <= fill_area_to.z; z++) {
                            index++;
                            const location = EntityManager.getLocationOffsetByRotation(entity, x, y, z);
                            const block = entity.dimension.getBlock(location);
                            if (!block) {
                                valid = false;
                            }
                            else {
                                if (!block.permutation.matches(name)) {
                                    valid = false;
                                }
                            }
                            if (!valid) {
                                break;
                            }
                        }
                        if (!valid) {
                            break;
                        }
                    }
                    if (!valid) {
                        break;
                    }
                }
            }
            else {
                valid = false;
            }
        }
        return valid;
    }
    static getFillArea(entity) {
        const fill_area_from = SecretEntrance.getFillAreaFrom(entity);
        const fill_area_to = SecretEntrance.getFillAreaTo(entity);
        const loc0 = EntityManager.getLocationOffsetByRotation(entity, fill_area_from.x, fill_area_from.y, fill_area_from.z);
        const loc1 = EntityManager.getLocationOffsetByRotation(entity, fill_area_to.x, fill_area_to.y, fill_area_to.z);
        return `${loc0.x} ${loc0.y} ${loc0.z} ${loc1.x} ${loc1.y} ${loc1.z}`;
    }
    static getFillBlocks(entity) {
        let blocks = [];
        const block_variant = entity.getProperty("property:fs_sbunk_block_variant");
        const blockDataSet = SecretEntranceBlockData.getBlockData();
        let blockData = undefined;
        for (let i = 0; i < blockDataSet.blocks.length; i++) {
            if (blockDataSet.blocks[i].block_variant === block_variant) {
                blockData = blockDataSet.blocks[i];
                break;
            }
        }
        if (blockData && blockData.fillBlocks) {
            blocks = blocks.concat(blockData.fillBlocks);
        }
        blocks.push("minecraft:barrier");
        return blocks;
    }
    static fillClosed(entity, wasKilled = false) {
        FSEntityHelper.snapRotation(entity);
        const fill_blocks = SecretEntrance.getFillBlocks(entity);
        let fill_block = fill_blocks.length > 0 ? fill_blocks[0] : undefined;
        if (entity.typeId === "57d_sbunk:secret_stairs") {
            const location0 = EntityManager.getLocationOffsetByRotation(entity, 0, 0, 0);
            const location1 = EntityManager.getLocationOffsetByRotation(entity, 0, 1, -1);
            const fill_area_0 = `${location0.x} ${location0.y} ${location0.z} ${location0.x} ${location0.y} ${location0.z}`;
            const fill_area_1 = `${location1.x} ${location1.y} ${location1.z} ${location1.x} ${location1.y} ${location1.z}`;
            const compass_direction = FSEntityHelper.getCompassDirection(entity);
            let weirdo_direction = 0;
            switch (compass_direction) {
                case FSCompassDirection.South: {
                    weirdo_direction = 3;
                    break;
                }
                case FSCompassDirection.West: {
                    weirdo_direction = 0;
                    break;
                }
                case FSCompassDirection.North: {
                    weirdo_direction = 2;
                    break;
                }
                case FSCompassDirection.East: {
                    weirdo_direction = 1;
                    break;
                }
            }
            if (fill_block) {
                fill_block = fill_block.replace("[]", "");
                const command0 = `/fill ${fill_area_0} ${fill_block} ["weirdo_direction":${weirdo_direction}]`;
                const command1 = `/fill ${fill_area_1} ${fill_block} ["weirdo_direction":${weirdo_direction}]`;
                if (!wasKilled) {
                    entity.runCommand(command0);
                    entity.runCommand(command1);
                    system.runTimeout(() => {
                        if (!FSDynamicProperty.getBoolean(entity, "is_open")) {
                            const block = FSEntityHelper.getBlockAtEntity(entity);
                            if (!block || !block.permutation.matches("minecraft:air")) {
                                entity.triggerEvent("fs:set_scale_0");
                            }
                        }
                    }, 1);
                }
                else {
                    const dimension = entity.dimension;
                    system.run(() => {
                        dimension.runCommand(command0);
                        dimension.runCommand(command1);
                    });
                }
            }
        }
        else {
            const fill_area = SecretEntrance.getFillArea(entity);
            if (fill_block) {
                const command = `/fill ${fill_area} ${fill_block}`;
                if (!wasKilled) {
                    entity.runCommand(command);
                    system.runTimeout(() => {
                        if (!FSDynamicProperty.getBoolean(entity, "is_open")) {
                            const block = FSEntityHelper.getBlockAtEntity(entity);
                            if (!block || !block.permutation.matches("minecraft:air")) {
                                entity.triggerEvent("fs:set_scale_0");
                            }
                        }
                    }, 1);
                }
                else {
                    const dimension = entity.dimension;
                    system.run(() => {
                        dimension.runCommand(command);
                    });
                }
            }
        }
    }
    static fillOpened(entity, wasKilled = false) {
        FSEntityHelper.snapRotation(entity);
        const fill_blocks = SecretEntrance.getFillBlocks(entity);
        if (entity.typeId === "57d_sbunk:secret_stairs") {
            const location0 = EntityManager.getLocationOffsetByRotation(entity, 0, 0, 0);
            const location1 = EntityManager.getLocationOffsetByRotation(entity, 0, 1, -1);
            const fill_area_0 = `${location0.x} ${location0.y} ${location0.z} ${location0.x} ${location0.y} ${location0.z}`;
            const fill_area_1 = `${location1.x} ${location1.y} ${location1.z} ${location1.x} ${location1.y} ${location1.z}`;
            fill_blocks.forEach(fill_block => {
                if (!wasKilled) {
                    const command0 = `/fill ${fill_area_0} air [] replace ${fill_block}`;
                    const command1 = `/fill ${fill_area_1} air [] replace ${fill_block}`;
                    entity.runCommand(command0);
                    entity.runCommand(command1);
                }
                else {
                    const command0 = `/fill ${fill_area_0} air [] destroy`;
                    const command1 = `/fill ${fill_area_1} air [] destroy`;
                    const dimension = entity.dimension;
                    system.run(() => {
                        dimension.runCommand(command0);
                        dimension.runCommand(command1);
                    });
                }
            });
        }
        else {
            const fill_area = SecretEntrance.getFillArea(entity);
            fill_blocks.forEach(fill_block => {
                if (!wasKilled) {
                    const command = `/fill ${fill_area} air [] replace ${fill_block}`;
                    entity.runCommand(command);
                }
                else {
                    const command = `/fill ${fill_area} air [] destroy`;
                    const dimension = entity.dimension;
                    system.run(() => {
                        dimension.runCommand(command);
                    });
                }
            });
        }
    }
    static onOpen(entity) {
        if (FSDynamicProperty.getBoolean(entity, "is_open")) {
            return;
        }
        FSDynamicProperty.setBoolean(entity, "is_open", true);
        entity.setProperty("property:fs_sbunk_entrance_state", "opened");
        world.playSound("open.wooden_door", entity.location);
        entity.triggerEvent("fs:set_scale_100");
        SecretEntrance.fillOpened(entity);
        const showSecretEntranceOutline = FSDynamicProperty.has(world, "show_secret_entrance_outline") ? FSDynamicProperty.getBoolean(world, "show_secret_entrance_outline") : true;
        if (showSecretEntranceOutline) {
            const entityTypeId = `${entity.typeId}_guide`;
            const location = entity.location;
            const rotation = entity.getRotation();
            const command = `summon ${entityTypeId} ${location.x} ${location.y} ${location.z} ${rotation.y} 0`;
            entity.runCommand(command);
        }
    }
    static onClose(entity) {
        FSEntityHelper.snapRotation(entity);
        if (!FSDynamicProperty.getBoolean(entity, "is_open")) {
            return;
        }
        FSDynamicProperty.setBoolean(entity, "is_open", false);
        world.playSound("close.wooden_door", entity.location);
        entity.setProperty("property:fs_sbunk_entrance_state", "closed");
        system.runTimeout(() => {
            SecretEntrance.fillClosed(entity);
        }, TicksPerSecond * SecretEntrance.getCloseAnimationTime(entity));
        const eqo = {
            type: `${entity.typeId}_guide`,
            location: entity.location,
            maxDistance: 1,
            closest: 1
        };
        const entities = entity.dimension.getEntities(eqo);
        if (entities.length > 0) {
            entities[0].remove();
        }
    }
    static onDeny(entity) {
        EntityManager.playAnimation(entity, "deny");
        SecretEntrance.fillClosed(entity);
    }
    static onKilled(entity) {
        if (!entity.hasTag("fs_sbunk:secret_entrance_transformed")) {
            SecretEntrance.fillClosed(entity, true);
            SecretEntrance.fillOpened(entity, true);
            const location = entity.location;
            const dimension = entity.dimension;
            const type = `${entity.typeId}_guide`;
            system.run(() => {
                const eqo = {
                    type: type,
                    location: location,
                    maxDistance: 0.5,
                    closest: 1
                };
                const entities = dimension.getEntities(eqo);
                if (entities.length > 0) {
                    entities[0].remove();
                }
            });
        }
    }
    static getRaycastHit(player) {
        let options = {
            includeLiquidBlocks: false,
            includePassableBlocks: false,
            maxDistance: RAYCAST_MAX_DISTANCE
        };
        try {
            const dimension = player.dimension;
            return dimension.getBlockFromRay(player.getHeadLocation(), player.getViewDirection(), options);
        }
        catch (error) {
            return undefined;
        }
    }
    static getSpawnRotationForPlayer(player) {
        const compassDirection = PlayerHelper.getCompassDirection(player);
        let rotation = 0;
        switch (compassDirection) {
            case FSCompassDirection.North: {
                rotation = 0;
                break;
            }
            case FSCompassDirection.East: {
                rotation = 90;
                break;
            }
            case FSCompassDirection.South: {
                rotation = 180;
                break;
            }
            case FSCompassDirection.West: {
                rotation = 270;
                break;
            }
        }
        return rotation;
    }
    static playerInteractWithSecretEntranceItem(player, item) {
        if (!SecretEntrance.raycastTestForSecretEntranceItem(player, item)) {
            SecretEntrance.sendInvalidPlacementMessage(player);
            return;
        }
        const raycastHit = SecretEntrance.getRaycastHit(player);
        if (!raycastHit) {
            return;
        }
        const block = raycastHit.block;
        const blockData = SecretEntranceBlockData.getSecretEntranceBlockData(block, item);
        if (!blockData) {
            return;
        }
        const event = blockData.event;
        if (event.length > 0) {
            try {
                let location = block.bottomCenter();
                if (item === "57d_sbunk:secret_wall") {
                    const blockBelow = block.below(1);
                    if (blockBelow) {
                        location = blockBelow.bottomCenter();
                    }
                }
                const rotation = SecretEntrance.getSpawnRotationForPlayer(player);
                const command = `summon ${item} ${location.x} ${location.y} ${location.z} ${rotation} 0 ${event}`;
                const result = player.runCommand(command);
                if (result.successCount > 0 && !FSPlayer.isCreative(player)) {
                    FSInventoryManager.removeItem(player, item, 1);
                }
            }
            catch (error) { }
        }
    }
    static removeSecretEntranceGuide(player, item) {
        const guideId = FSDynamicProperty.getString(player, `${item}_guide_id`);
        let guideEntity = undefined;
        if (guideId.length) {
            guideEntity = world.getEntity(guideId);
        }
        if (guideEntity) {
            guideEntity.remove();
        }
        FSDynamicProperty.clear(player, guideId);
    }
    static getSecretEntranceGuide(player, item) {
        const guideId = FSDynamicProperty.getString(player, `${item}_guide_id`);
        let guideEntity = undefined;
        if (guideId.length > 0) {
            guideEntity = world.getEntity(guideId);
        }
        return guideEntity;
    }
    static raycastTestForSecretEntranceItem(player, item) {
        let valid_placement = false;
        let options = {
            includeLiquidBlocks: false,
            includePassableBlocks: false,
            maxDistance: RAYCAST_MAX_DISTANCE
        };
        const raycastHit = player.dimension.getBlockFromRay(player.getHeadLocation(), player.getViewDirection(), options);
        if (!raycastHit) {
            SecretEntrance.removeSecretEntranceGuide(player, item);
            return valid_placement;
        }
        const block = raycastHit.block;
        if (!block) {
            SecretEntrance.removeSecretEntranceGuide(player, item);
            return valid_placement;
        }
        const blockData = SecretEntranceBlockData.getSecretEntranceBlockData(block, item);
        if (!blockData) {
            SecretEntrance.removeSecretEntranceGuide(player, item);
            return valid_placement;
        }
        if (blockData) {
            let blockLocation = block.bottomCenter();
            let guideEntity = SecretEntrance.getSecretEntranceGuide(player, item);
            if (!guideEntity) {
                const dimension = player.dimension;
                guideEntity = dimension.spawnEntity(`${item}_guide`, blockLocation);
                FSDynamicProperty.setString(player, `${item}_guide_id`, guideEntity.id);
                FSDynamicProperty.setString(guideEntity, "player_id", player.id);
            }
            let locationOffset = { x: 0, y: 0, z: 0 };
            let rotation = 0;
            if (item === "57d_sbunk:secret_wall") {
                locationOffset.y = -1;
            }
            if (item === "57d_sbunk:secret_wall") {
                if (raycastHit.face === Direction.East || raycastHit.face === Direction.West) {
                    rotation = 90;
                }
            }
            if (item === "57d_sbunk:secret_stairs") {
                if (raycastHit.face === Direction.South) {
                    rotation = 0;
                }
                if (raycastHit.face === Direction.West) {
                    rotation = 90;
                }
                if (raycastHit.face === Direction.North) {
                    rotation = 180;
                }
                if (raycastHit.face === Direction.East) {
                    rotation = 270;
                }
            }
            valid_placement = SecretEntrance.validateSurroundingBlocks(guideEntity, blockData.block_variant);
            if (valid_placement) {
                guideEntity.triggerEvent("fs:set_valid");
                guideEntity.addTag(FSUtil.namespacedStringCr("is_valid"));
            }
            else {
                guideEntity.triggerEvent("fs:set_invalid");
                guideEntity.removeTag(FSUtil.namespacedStringCr("is_valid"));
            }
            blockLocation = FSMath.add(blockLocation, locationOffset);
            guideEntity.teleport(blockLocation);
            guideEntity.setRotation({ x: 0, y: rotation });
            system.runTimeout(() => {
                if (guideEntity.isValid()) {
                    guideEntity.teleport(blockLocation);
                    guideEntity.setRotation({ x: 0, y: rotation });
                }
            }, 1);
        }
        return valid_placement;
    }
}

//# sourceMappingURL=../../../../_SBUNK_BPDebug/fs_sbunk/entity/SecretEntrance.js.map
