import { system } from '@minecraft/server';
export default class EntityStatus {
    constructor(entity) {
        this.entity = entity;
        this.status = {
            infection: {
                until: 0,
                level: 1,
            }
        };
        this.refresh();
    }
    /**
     * Pull the most recent details about this entity's statuses.
     */
    refresh() {
        const infectedUntil = this.entity.getDynamicProperty('twb_wisu:infected_until');
        const infectionLevel = this.entity.getDynamicProperty('twb_wisu:infection_level');
        this.status.infection = {
            until: infectedUntil || 0,
            level: infectionLevel || 1,
        };
    }
    /**
     * Get the time at which the entity stops being infected.
     * @returns The world tick until which the entity is infected. Returns 0 if the entity is not
     * currently infected. Returns -1 if the entity is permanently infected.
     */
    getInfectionEndTime() {
        const endTime = this.status.infection.until;
        if (endTime < 0)
            return -1;
        if (endTime < system.currentTick)
            return 0;
        return endTime;
    }
    /**
     * Get whether the entity is currently infected or not.
     * @returns `true` if the entity is currently infected, otherwise `false`
     */
    isInfected() {
        return this.getInfectionEndTime() !== 0;
    }
    /**
     * Get the time that remains until this entity is no longer infected.
     * @returns The time in ticks the entity will remain infected for. Returns 0 if the entity is not
     * currently infected. Returns -1 if the entity is permanently infected.
     */
    getRemainingInfectionTime() {
        const endTime = this.getInfectionEndTime();
        return endTime > 0
            ? endTime - system.currentTick
            : endTime;
    }
    /**
     * Set the time this entity should be infected for.
     * @param duration The time in ticks the entity should be infected for, `-1` for infinite
     * @param overwrite Whether to overwrite the existing effect even if it reduces infection time
     * @returns Whether the time was overwritten. False if `overwrite` is false and `duration` is less
     * than the existing duration.
     */
    setRemainingInfectionTime(duration, overwrite) {
        if (!overwrite) {
            const timeRemaining = this.getRemainingInfectionTime();
            // If entity is already permanently infected, do nothing
            if (timeRemaining < 0)
                return false;
            // If entity already has a longer lasting infection, do nothing
            if (duration !== 1 && timeRemaining > duration)
                return false;
        }
        const newEndTime = duration >= 0 ? (system.currentTick + duration) : -1;
        this.entity.setDynamicProperty('twb_wisu:infected_until', newEndTime);
        this.status.infection.until = newEndTime;
        return true;
    }
    /**
     * Get the infection level of the entity.
     * @returns The infection level of the entity, or `0` if the entity is not infected.
     */
    getInfectionLevel() {
        if (!this.isInfected())
            return 0;
        return this.status.infection.level;
    }
    /**
     * Set the infection level of this entity.
     * @param level The infection level the entity should get, clamped between 1 and
     * MAX_INFECTION_LEVEL
     * @param overwrite Whether to overwrite the existing effect even if it results in a lower level
     * @returns Whether the level was overwritten. False if `overwrite` is false and `level` is less
     * than the existing duration, true otherwise.
     */
    setInfectionLevel(level, overwrite) {
        // 1 <= newLevel <= MAX_INFECTION_LEVEL
        const newLevel = Math.min(Math.max(1, level), EntityStatus.MAX_INFECTION_LEVEL);
        // If entity already has a higher level infection, do nothing
        if (!overwrite && newLevel <= this.status.infection.level)
            return;
        this.entity.setDynamicProperty('twb_wisu:infection_level', newLevel);
        this.status.infection.level = newLevel;
    }
    correctForOfflineTime(lastSeen) {
        if (this.status.infection.until <= -1)
            return;
        const newRemainingTime = this.status.infection.until - lastSeen;
        this.setRemainingInfectionTime(newRemainingTime);
    }
}
EntityStatus.MAX_INFECTION_LEVEL = 100;
