import { EntityComponentTypes, GameMode, Player, system, world } from "@minecraft/server";
import { BrutalPlayerMethods, initWeather } from "./helper/BrutalPlayerMethods";
import { FoodSpoilageMethods, SPOIL_UPDATE_INTERVAL } from "./helper/FoodSpoilage";
import { initBreakBlockDamage, Limb, LimbDamageMethods, MAX_LIMB_HEALTH } from "./helper/LimbDamage";
import { initTalismans } from "./helper/Talismans";
import { initThirst, initWaterFlask } from "./helper/Thirst";
import "./helper/EatenFoodHandler";
import "./forms";
import { initOnJoin } from "./helper/onJoin";
import { initMedkit } from "./helper/medkit";
// DEBUG
// world.afterEvents.itemUse.subscribe(result => {
//     if (result.itemStack.typeId === "minecraft:stick") {
//         const player = result.source;
//         // (player as BrutalPlayer).setThirst(0);
//         // (player as BrutalPlayer).damageSpecificLimb(Limb.LeftArm, 99);
//         player.damageSpecificLimb(Limb.RightArm, MAX_LIMB_HEALTH / 8);
//         // (player as BrutalPlayer).damageSpecificLimb(Limb.Head, 99);
//         // (player as BrutalPlayer).damageSpecificLimb(Limb.Body, MAX_LIMB_HEALTH / 8);
//         // (player as BrutalPlayer).damageSpecificLimb(Limb.Legs, 99);
//         // (player as Player).setDynamicProperty(`oct_db:is_not_new_player`, undefined);
//     }
// });
system.afterEvents.scriptEventReceive.subscribe(result => {
    if (result.id === "oct_db:thirst") {
        const setAmount = Number(result.message);
        if (isNaN(setAmount))
            return;
        result.sourceEntity.setThirst(setAmount);
    }
});
// Medkit
initMedkit();
// Limb damage
world.afterEvents.entityHurt.subscribe(result => {
    if (result.hurtEntity.typeId !== "minecraft:player")
        return;
    const player = result.hurtEntity;
    player.damageLimb(result.damage, result.damageSource.cause);
});
world.afterEvents.itemUse.subscribe(result => {
    if (result.itemStack.typeId === "oct_db:bandage") {
        const player = result.source;
        player.useBandage();
    }
    else if (result.itemStack.typeId === "oct_db:enhanced_bandage") {
        const player = result.source;
        player.useBandage(true);
    }
});
// Reset limbs when player respawns/dies
world.afterEvents.playerSpawn.subscribe(result => {
    if (result.initialSpawn)
        return;
    result.player.resetLimbHealth();
    result.player.resetThirst();
    result.player.resetTemperature();
});
// On join
initOnJoin();
// Weather
initWeather();
// Thirst
initThirst();
// Talismans
initTalismans();
// Water Flask
initWaterFlask();
// Break block damage
initBreakBlockDamage();
system.runInterval(() => {
    const players = world.getPlayers();
    for (const player of players) {
        // Things that should apply to all players
        if (system.currentTick % SPOIL_UPDATE_INTERVAL === 0) {
            player.updateFoodSpoilage(player.getComponent(EntityComponentTypes.Inventory));
            // If player is riding an entity, update the entity inventory as well
            const ridingComp = player.getComponent(EntityComponentTypes.Riding);
            if (ridingComp) {
                const entityRidingOnInventoryComp = ridingComp.entityRidingOn?.getComponent(EntityComponentTypes.Inventory);
                if (entityRidingOnInventoryComp)
                    player.updateFoodSpoilage(entityRidingOnInventoryComp);
            }
        }
        if (system.currentTick % 20 === 0) {
            player.refreshLimbHealth(); // Reset animations
            player.checkActionbarStats();
            player.updateHealthMenuItem();
        }
        // Things that should only apply to survival/adventure mode players
        const playerGamemode = player.getGameMode();
        if (playerGamemode === GameMode.creative || playerGamemode === GameMode.spectator) {
            // Set temp to normal to avoid temperature being static
            player.setTemperature(0.2);
            continue;
        }
        if (system.currentTick % 5 === 0)
            player.checkInsulatedFeet();
        if (system.currentTick % 4 === 0)
            player.deteriorateThirst();
        player.checkFog();
        if (system.currentTick % 20 === 0) {
            player.checkThirst();
        }
        if (system.currentTick % 10 === 0) {
            player.checkNotifications();
            player.checkSoundEffects();
        }
        if (system.currentTick % 60 === 0) {
            player.checkParticleWarning();
        }
        if (system.currentTick % 10 === 0) {
            player.setTemperatureFromEnvironment();
        }
        if (system.currentTick % 20 === 0)
            player.applyExtremeWeatherDetriments();
        if (system.currentTick % 20 === 0)
            player.checkLimbHealth();
        if (system.currentTick % 20 === 0)
            player.checkShouldTickDamage();
    }
});
// On world reload
world.afterEvents.playerJoin.subscribe(result => {
    const interval = system.runInterval(() => {
        const player = world.getPlayers().find(p => p.name === result.playerName);
        if (!player || !player.isValid())
            return;
        player.refreshLimbHealth();
        system.clearRun(interval);
    });
});
world.afterEvents.worldInitialize.subscribe(() => {
    const interval = system.runInterval(() => {
        const player = world.getPlayers()[0];
        if (!player || !player.isValid())
            return;
        player.refreshLimbHealth();
        system.clearRun(interval);
    });
});
// Set methods to player
Object.assign(Player.prototype, BrutalPlayerMethods);
Object.assign(Player.prototype, LimbDamageMethods);
Object.assign(Player.prototype, FoodSpoilageMethods);
