var _a;
import * as mc from "@minecraft/server";
import * as utils from "../utils/index";
import * as db from "../utils/database/index";
import { Settings } from "../shared/index";
import { ItemDrops } from "./item_drops";
export class PlayerGrave {
    static registerGrave(block, player, source) {
        const blockId = `${block.dimension.id}_${block.location.x}_${block.location.y}_${block.location.z}`;
        const data = {
            block: blockId,
            name: player.name,
            death_time: Date.now(),
            death_cause: getDeathCause(source),
        };
        const location = new utils.Vector3(block.location);
        location.y = block.dimension.heightRange.min;
        const actor = new PlayerGraveActor(block.dimension.spawnEntity("ldz_250121:player_grave", location));
        actor.addInventory(player);
        this.database.Tables.blocks.setEntry(blockId, { id: actor.id });
        this.database.Tables.data.setEntry(actor.id, data);
    }
}
_a = PlayerGrave;
PlayerGrave.database = new db.DataBase("player_graves", {
    tables: {
        blocks: {
            maxSize: Number.MAX_SAFE_INTEGER,
        },
        data: {
            maxSize: Number.MAX_SAFE_INTEGER,
        }
    }
});
(() => {
    mc.world.beforeEvents.worldInitialize.subscribe(event => {
        const database = _a.database;
        event.blockComponentRegistry.registerCustomComponent("ldz_250121:player_grave", {
            onPlayerInteract(arg) {
                var _b;
                if (!arg.player)
                    return;
                const player = new utils.SafetyCheckedPlayer(arg.player);
                const blockId = `${arg.block.dimension.id}_${arg.block.location.x}_${arg.block.location.y}_${arg.block.location.z}`;
                const blockEntry = database.Tables.blocks.getEntry(blockId);
                if (blockEntry === null || blockEntry === void 0 ? void 0 : blockEntry.id) {
                    const data = database.Tables.data.getEntry(blockEntry.id);
                    const actor = utils.Actor.getActor(blockEntry.id, PlayerGraveActor);
                    if (data) {
                        new utils.MenuBuilder({
                            type: "buttons",
                            title: utils.translate("message.player_grave.title", [data.name]),
                            body: { rawtext: [
                                    utils.translate("message.player_grave.body", ["\n", data.name, data.death_cause, getTimeSince(data.death_time)]),
                                    ...(_b = actor === null || actor === void 0 ? void 0 : actor.getItemLangs()) !== null && _b !== void 0 ? _b : [],
                                ] },
                            contents: [
                                {
                                    text: "Close",
                                    onClick: () => { }
                                }
                            ],
                        }).showMenuToPlayer(player);
                    }
                }
            },
            onPlayerDestroy(arg0) {
                arg0.dimension.getEntities({ type: "minecraft:item", maxDistance: 5, location: arg0.block.location })
                    .map(entity => entity.getComponent("item"))
                    .filter(component => { var _b; return ((_b = component === null || component === void 0 ? void 0 : component.itemStack) === null || _b === void 0 ? void 0 : _b.typeId) === "ldz_250121:player_grave"; })
                    .forEach(component => {
                    try {
                        component === null || component === void 0 ? void 0 : component.entity.remove();
                    }
                    catch (_error) {
                        // Do nothing if removal fails
                    }
                });
            },
        });
    });
    mc.world.afterEvents.entityDie.subscribe(event => {
        const player = new utils.SafetyCheckedEntity(event.deadEntity).getPlayer();
        if (player && Settings.PlayerGravestone) {
            const location = getSurfaceLocation(player.dimension, player.location).up();
            const cardinalDirection = ["north", "east", "south", "west"][Math.round(player.getRotation().y / 90) & 3];
            player.dimension.setBlockPermutation(location, mc.BlockPermutation.resolve("ldz_250121:player_grave", {
                "minecraft:cardinal_direction": cardinalDirection
            }));
            const block = player.dimension.getBlock(location);
            if (block) {
                _a.registerGrave(block, player, event.damageSource);
            }
        }
    });
    mc.world.afterEvents.playerBreakBlock.subscribe(event => {
        const blockId = `${event.block.dimension.id}_${event.block.location.x}_${event.block.location.y}_${event.block.location.z}`;
        const blockEntry = _a.database.Tables.blocks.getEntry(blockId);
        if (blockEntry === null || blockEntry === void 0 ? void 0 : blockEntry.id) {
            const actor = utils.Actor.getActor(blockEntry.id, PlayerGraveActor);
            actor === null || actor === void 0 ? void 0 : actor.dropInventory(event.block.location);
            _a.database.Tables.blocks.deleteEntry(blockId);
            _a.database.Tables.data.deleteEntry(blockEntry.id);
        }
    });
})();
export class PlayerGraveActor extends utils.Actor {
    addInventory(player) {
        const sourceItems = ItemDrops.getDropsAtLocation(mc.system.currentTick, player.location);
        const targetInventory = this.Inventory;
        if (sourceItems.length && targetInventory && !mc.world.gameRules.keepInventory) {
            for (const item of sourceItems) {
                targetInventory.addItem(item.item);
                item.entity.remove();
            }
        }
    }
    dropInventory(location) {
        const inventory = this.Inventory;
        if (inventory) {
            for (let index = 0; index < inventory.size; index++) {
                const item = inventory.getItem(index);
                if (item) {
                    this.dimension.spawnItem(item, location);
                }
            }
        }
        this.remove();
    }
    getItemLangs() {
        const array = [];
        const inventory = this.Inventory;
        if (inventory) {
            for (let index = 0; index < inventory.size; index++) {
                const item = inventory.getItem(index);
                if (item) {
                    array.push(utils.translate("message.player_grave.item", [utils.itemLangKey(item), item.amount.toString()]));
                    array.push({ text: "\n" });
                }
            }
        }
        if (!array.length) {
            array.push(utils.translate("message.player_grave.no_items"));
            array.push({ text: "\n\n" });
        }
        else {
            array.unshift(utils.translate("message.player_grave.item_label"), { text: "\n" });
            array.push({ text: "\n" });
        }
        return array;
    }
}
utils.Actor.makeActors({ type: "ldz_250121:player_grave" }, PlayerGraveActor);
function getSurfaceLocation(dimension, location) {
    var _b;
    const foundLocation = (_b = dimension.getTopmostBlock(location, location.y)) === null || _b === void 0 ? void 0 : _b.location;
    if (foundLocation) {
        return new utils.Vector3(foundLocation);
    }
    else {
        return location;
    }
}
function getTimeSince(time) {
    const elapsedTime = Date.now() - time;
    const date = new Date(elapsedTime);
    const hours = String(date.getUTCHours()).padStart(2, '0');
    const minutes = String(date.getUTCMinutes()).padStart(2, '0');
    const seconds = String(date.getUTCSeconds()).padStart(2, '0');
    return `${hours}:${minutes}:${seconds}`;
}
function getDeathCause(source) {
    var _b, _c, _d;
    if (((_b = source.damagingEntity) === null || _b === void 0 ? void 0 : _b.isValid()) && source.damagingEntity.nameTag !== "") {
        return utils.translate(`message.player_grave.death.${source.cause}`, [source.damagingEntity.nameTag]);
    }
    else {
        const typeId = (_d = (_c = source.damagingEntity) === null || _c === void 0 ? void 0 : _c.typeId) !== null && _d !== void 0 ? _d : "";
        const translate = `entity.${typeId.replace("minecraft:", "")}.name`;
        return utils.translate(`message.player_grave.death.${source.cause}`, [{ translate }]);
    }
}
