import { system, world } from "@minecraft/server";
import { OreLootCollection } from "./definitions";
import { calculateEuclideanDistance, HexEncoder } from "nps_mot/utils/my_API";
import { Codex } from "nps_mot/nps_mot/codex";
import { PlayerDynamicProperty } from "nps_mot/utils/customPlayer";
import { getBlockTags, getOreCategory } from "./newToolSystem";
import { OrePlacementCollection } from "./regionUtils";
world.beforeEvents.itemUse.subscribe(event => {
    handleMagnifyingGlassUse(event);
});
function handleMagnifyingGlassUse(event) {
    const itemStack = event.itemStack;
    if (!isMagnifyingGlass(itemStack))
        return;
    const player = event.source;
    const blockFromView = player.getBlockFromViewDirection();
    if (!blockFromView)
        return;
    const { block, playerLocation } = getBlockAndPlayerLocation(player, blockFromView);
    if (isTooFarFromBlock(playerLocation, block)) {
        system.run(() => {
            player.onScreenDisplay.setActionBar([{ translate: 'nps_mot:magnifying_glass.too_far' }]);
        });
        return;
    }
    //oreLoot
    const oreLootIndex = OreLootCollection.findOreIndexByOreId(block.typeId);
    const vanillaOreLootIndex = OreLootCollection.findVanillaOreIndexByOreId(block.typeId);
    if (oreLootIndex == -1 && vanillaOreLootIndex == -1)
        return;
    if (vanillaOreLootIndex != -1) {
        //vanilla ores
        const vanillaOreLoot = OreLootCollection.vanillaOres[vanillaOreLootIndex];
        const oreRawtext = vanillaOreLoot.getOreTranslateText();
        const oreDropRawtext = vanillaOreLoot.getOreDropTranslateText();
        const fortuneBoostEnabled = OreLootCollection.vanillaOres[vanillaOreLootIndex].fortuneBoostEnabled;
        const fortuneEnabledRawtext = fortuneBoostEnabled ? 'nps_mot:magnifying_glass.yes' : 'nps_mot:magnifying_glass.no';
        const blockTags = getBlockTags(block);
        const oreCategory = getOreCategory(blockTags);
        //
        system.run(() => {
            player.onScreenDisplay.setActionBar([
                { translate: `nps_mot:magnifying_glass.name` }, { translate: oreRawtext }, { text: "\n" },
                { translate: `nps_mot:magnifying_glass.loot` }, { translate: oreDropRawtext }, { text: "\n" },
                { translate: `nps_mot:magnifying_glass.fortuneBoostEnabled` }, { translate: fortuneEnabledRawtext }, { text: "\n" },
                { translate: `nps_mot:magnifying_glass.oreCategory` }, { text: oreCategory.toString() }
            ]);
        });
        return;
    }
    if (oreLootIndex != -1) {
        //mot ores/blocks
        const oreLoot = OreLootCollection.ores[oreLootIndex];
        const fortuneBoostEnabled = oreLoot.fortuneBoostEnabled;
        const fortuneEnabledRawtext = fortuneBoostEnabled ? 'nps_mot:magnifying_glass.yes' : 'nps_mot:magnifying_glass.no';
        const oreDropRawtext = oreLoot.getOreDropTranslateText();
        const blockTags = getBlockTags(block);
        const oreCategory = getOreCategory(blockTags);
        //orePlacement
        let oreId = block.typeId;
        const isDeepslateOre = oreId.includes('deepslate_');
        if (isDeepslateOre) {
            if (oreId != 'nps_mot:deepslate_osmium_ore') {
                oreId = 'nps_mot:'.concat(block.typeId.split('nps_mot:deepslate_')[1]);
            }
        }
        const orePlacementIndex = OrePlacementCollection.findIndexByOreId(oreId);
        if (orePlacementIndex === -1) {
            //display block information
            system.run(() => {
                player.onScreenDisplay.setActionBar([
                    { translate: `nps_mot:magnifying_glass.name` }, { translate: `tile.${block.typeId}.name` }, { text: "\n" },
                    { translate: `nps_mot:magnifying_glass.oreCategory` }, { text: oreCategory.toString() }
                ]);
            });
        }
        else {
            const orePlacement = OrePlacementCollection.ores[orePlacementIndex];
            const optimumMiningLayer = orePlacement.density.getOptimalY();
            let optimalMiningLayerText = undefined;
            if (optimumMiningLayer.length == 0) {
                optimalMiningLayerText = { translate: "nps_mot:ore_codex_entry.noOptimalY" };
            }
            else {
                optimalMiningLayerText = { text: orePlacement.density.getOptimalY().join(', ') };
            }
            //display block information
            system.run(() => {
                player.onScreenDisplay.setActionBar([
                    { translate: `nps_mot:magnifying_glass.name` }, { translate: `tile.${block.typeId}.name` }, { text: "\n" },
                    { translate: `nps_mot:magnifying_glass.loot` }, { translate: oreDropRawtext }, { text: "\n" },
                    { translate: `nps_mot:magnifying_glass.fortuneBoostEnabled` }, { translate: fortuneEnabledRawtext }, { text: "\n" },
                    { translate: `nps_mot:magnifying_glass.oreCategory` }, { text: oreCategory.toString() }, { text: "\n" },
                    { translate: `nps_mot:magnifying_glass.optimumMiningLayer` }, { text: " " }, optimalMiningLayerText
                ]);
            });
        }
        //scan block in codex
        const encodingPosition = Codex.getEncodingPosition(oreLoot.oreDrop.typeId);
        if (encodingPosition === undefined) {
            return;
        }
        const CODE1 = player.getDynamicProperty(PlayerDynamicProperty.CODE1);
        const discovered = HexEncoder.getBit(CODE1, encodingPosition);
        if (discovered == false) {
            const newCode1 = HexEncoder.setBit(CODE1, encodingPosition);
            player.setDynamicProperty(PlayerDynamicProperty.CODE1, newCode1);
            const countSetBits = HexEncoder.countSetBits(CODE1);
            if (countSetBits === Codex.oreCodex.length - 1) {
                Codex.onCompleteOreCodexDiscovery(player);
            }
            else {
                Codex.onOreDiscovery(player);
            }
        }
    }
}
;
function isMagnifyingGlass(itemStack) {
    return itemStack.typeId === "nps_mot:magnifying_glass";
}
function getBlockAndPlayerLocation(player, blockFromView) {
    const block = blockFromView.block;
    const playerLocation = { ...player.location }; // Clone player location
    playerLocation.y++;
    return { block, playerLocation };
}
function isTooFarFromBlock(playerLocation, block) {
    const distanceFromBlock = calculateEuclideanDistance(playerLocation, block.center());
    return distanceFromBlock > 2.5;
}
