package net.minecraft.world.entity.ai.village;

import javax.annotation.Nullable;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.phys.Vec3;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.SpawnGroupData;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.monster.Zombie;
import net.minecraft.world.entity.player.Player;
import java.util.Iterator;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.ServerLevel;

public class VillageSiege {
    private boolean hasSetupSiege;
    private State siegeState;
    private int zombiesToSpawn;
    private int nextSpawnTime;
    private int spawnX;
    private int spawnY;
    private int spawnZ;
    
    public VillageSiege() {
        this.siegeState = State.SIEGE_DONE;
    }
    
    public int tick(final ServerLevel xd, final boolean boolean2, final boolean boolean3) {
        if (xd.isDay() || !boolean2) {
            this.siegeState = State.SIEGE_DONE;
            this.hasSetupSiege = false;
            return 0;
        }
        final float float5 = xd.getTimeOfDay(0.0f);
        if (float5 == 0.5) {
            this.siegeState = ((xd.random.nextInt(10) == 0) ? State.SIEGE_TONIGHT : State.SIEGE_DONE);
        }
        if (this.siegeState == State.SIEGE_DONE) {
            return 0;
        }
        if (!this.hasSetupSiege) {
            if (!this.tryToSetupSiege(xd)) {
                return 0;
            }
            this.hasSetupSiege = true;
        }
        if (this.nextSpawnTime > 0) {
            --this.nextSpawnTime;
            return 0;
        }
        this.nextSpawnTime = 2;
        if (this.zombiesToSpawn > 0) {
            this.trySpawn(xd);
            --this.zombiesToSpawn;
        }
        else {
            this.siegeState = State.SIEGE_DONE;
        }
        return 1;
    }
    
    private boolean tryToSetupSiege(final ServerLevel xd) {
        for (final Player ayj4 : xd.players()) {
            if (!ayj4.isSpectator()) {
                final BlockPos fk5 = ayj4.getCommandSenderBlockPosition();
                if (!xd.isVillage(fk5)) {
                    continue;
                }
                if (xd.getBiome(fk5).getBiomeCategory() == Biome.BiomeCategory.MUSHROOM) {
                    continue;
                }
                for (int integer6 = 0; integer6 < 10; ++integer6) {
                    final float float7 = xd.random.nextFloat() * 6.2831855f;
                    this.spawnX = fk5.getX() + Mth.floor(Mth.cos(float7) * 32.0f);
                    this.spawnY = fk5.getY();
                    this.spawnZ = fk5.getZ() + Mth.floor(Mth.sin(float7) * 32.0f);
                    if (this.findRandomSpawnPos(xd, new BlockPos(this.spawnX, this.spawnY, this.spawnZ)) != null) {
                        this.nextSpawnTime = 0;
                        this.zombiesToSpawn = 20;
                        break;
                    }
                }
                return true;
            }
        }
        return false;
    }
    
    private void trySpawn(final ServerLevel xd) {
        final Vec3 cvl3 = this.findRandomSpawnPos(xd, new BlockPos(this.spawnX, this.spawnY, this.spawnZ));
        if (cvl3 == null) {
            return;
        }
        Zombie axp4;
        try {
            axp4 = new Zombie(xd);
            axp4.finalizeSpawn(xd, xd.getCurrentDifficultyAt(new BlockPos(axp4)), MobSpawnType.EVENT, null, null);
        }
        catch (Exception exception5) {
            exception5.printStackTrace();
            return;
        }
        axp4.moveTo(cvl3.x, cvl3.y, cvl3.z, xd.random.nextFloat() * 360.0f, 0.0f);
        xd.addFreshEntity(axp4);
    }
    
    @Nullable
    private Vec3 findRandomSpawnPos(final ServerLevel xd, final BlockPos fk) {
        for (int integer4 = 0; integer4 < 10; ++integer4) {
            final int integer5 = fk.getX() + xd.random.nextInt(16) - 8;
            final int integer6 = fk.getZ() + xd.random.nextInt(16) - 8;
            final int integer7 = xd.getHeight(Heightmap.Types.WORLD_SURFACE, integer5, integer6);
            final BlockPos fk2 = new BlockPos(integer5, integer7, integer6);
            if (xd.isVillage(fk2)) {
                if (Monster.checkMonsterSpawnRules(EntityType.ZOMBIE, xd, MobSpawnType.EVENT, fk2, xd.random)) {
                    return new Vec3(fk2.getX() + 0.5, fk2.getY(), fk2.getZ() + 0.5);
                }
            }
        }
        return null;
    }
    
    enum State {
        SIEGE_CAN_ACTIVATE, 
        SIEGE_TONIGHT, 
        SIEGE_DONE;
    }
}
