import { DimensionTypes, GameMode, system, world } from '@minecraft/server';
import ScriptingModule from '../scriptingModule';
import Witherboss from './witherboss';
import { BOSS_ID } from './witherbossSettings';
import TargetRegistry from './targets/targetRegistry';
import SoulFetcherAttack from './attacks/soulFetcherAttack';
export default class WitherbossModule extends ScriptingModule {
    constructor() {
        super('WitherModule');
    }
    onInitialize() {
        TargetRegistry.setup();
        TargetRegistry.register('twb_wisu:witherboss', {
            scanInterval: 1.0,
            sightRange: 25,
            followRange: 30,
            maxNumTargets: 4,
            filterFunc: (entity) => {
                if (entity.typeId === 'minecraft:player') {
                    const gameMode = entity.getGameMode();
                    return gameMode !== GameMode.creative && gameMode !== GameMode.spectator;
                }
                return entity.typeId === 'minecraft:villager_v2';
            },
        });
        TargetRegistry.register('twb_wisu:soul_fetcher', {
            scanInterval: 1.0,
            sightRange: 20,
            followRange: 22,
            filterFunc: (entity) => {
                if (entity.typeId === 'minecraft:player') {
                    const gameMode = entity.getGameMode();
                    return gameMode !== GameMode.creative && gameMode !== GameMode.spectator;
                }
                return entity.typeId === 'minecraft:villager_v2';
            },
        });
        world.afterEvents.entityHurt.subscribe((e) => {
            const hitbox = e.hurtEntity;
            const oId = hitbox.getDynamicProperty('owner');
            const owner = WitherbossModule.WITHER_BOSSES.find((boss) => boss.getEntity()?.id === oId);
            if (owner) {
                const numPlayers = owner.getNumNearbyPlayers();
                let damageMultiplier = 1.0;
                if (numPlayers <= 1) {
                    damageMultiplier = 2.0;
                }
                else if (numPlayers === 2) {
                    damageMultiplier = 1.5;
                }
                // Transfer damage from hitbox to boss
                owner.damage(e.damage * damageMultiplier, e.damageSource);
            }
        }, { entityTypes: ['twb_wisu:witherboss_hitbox'] });
        world.afterEvents.entityHurt.subscribe((e) => SoulFetcherAttack.onHurt(e.hurtEntity), { entityTypes: ['twb_wisu:soul_fetcher'] });
        system.afterEvents.scriptEventReceive.subscribe((e) => {
            const { sourceEntity } = e;
            if (e.id === 'twb_wisu:summon_wither' && sourceEntity) {
                WitherbossModule.summonNewWitherboss(sourceEntity.dimension, sourceEntity.location);
            }
        });
    }
    onTick() {
        // Delete wither bosses that are no longer valid
        WitherbossModule.WITHER_BOSSES = WitherbossModule.WITHER_BOSSES
            .filter((witherboss) => witherboss.tick());
        const validWitherbossBodies = new Set(WitherbossModule.WITHER_BOSSES
            .map((boss) => boss.getEntity()));
        // Load wither bosses that are not yet loaded
        for (const dimensionType of DimensionTypes.getAll()) {
            world.getDimension(dimensionType.typeId).getEntities().forEach((entity) => {
                if (entity.typeId === BOSS_ID && !validWitherbossBodies.has(entity)) {
                    WitherbossModule.WITHER_BOSSES.push(new Witherboss(entity, false));
                }
            });
        }
        SoulFetcherAttack.onTick();
    }
    on3Seconds() {
        WitherbossModule.WITHER_BOSSES.forEach((boss) => {
            if (!boss.isSummoning() && !boss.isDying())
                boss.spawnHitboxes();
        });
    }
    static summonNewWitherboss(dimension, location) {
        const witherEntity = dimension.spawnEntity(BOSS_ID, location);
        witherEntity.runCommand('tp @s ~ ~ ~ facing @p');
        const witherBoss = new Witherboss(witherEntity, true);
        WitherbossModule.WITHER_BOSSES.push(witherBoss);
    }
}
WitherbossModule.WITHER_BOSSES = [];
