package net.Chipperfluff.chipi.entity;

import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.SpawnRestriction;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.Heightmap;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.biome.Biome;

public final class SpawnLogic {

    private static final int MAX_MEPS = 60;
    private static final int SPAWN_RADIUS = 150;

    private static final RegistryKey<Biome> VOID_BIOME =
        RegistryKey.of(RegistryKeys.BIOME, new Identifier("chipi", "void"));

    private SpawnLogic() {}

    public static void register() {

        BiomeModifications.addSpawn(
            BiomeSelectors.includeByKey(VOID_BIOME),
            SpawnGroup.MONSTER,
            ModEntities.MEP,
            1,
            1,
            4
        );

        SpawnRestriction.register(
            ModEntities.MEP,
            SpawnRestriction.Location.ON_GROUND,
            Heightmap.Type.MOTION_BLOCKING_NO_LEAVES,
            SpawnLogic::canSpawn
        );
    }

    private static boolean canSpawn(
        EntityType<? extends MobEntity> type,
        ServerWorldAccess world,
        SpawnReason reason,
        BlockPos pos,
        Random random
    ) {
        // --- HEIGHT & Z RULES ---
        int y = pos.getY();
        if (y < 87 || y > 90) return false;
        if (pos.getZ() < 18) return false;

        // --- BLOCK CHECK ---
        BlockState below = world.getBlockState(pos.down());
        if (!below.isOf(Blocks.POLISHED_BLACKSTONE_BRICKS)) return false;

        // --- GLOBAL CAP (DENY SPAWN, DO NOT DESPAWN) ---
        int mepCount = world.getEntitiesByClass(
            MepEntity.class,
            new Box(
                pos.getX() - 512, pos.getY() - 512, pos.getZ() - 512,
                pos.getX() + 512, pos.getY() + 512, pos.getZ() + 512
            ),
            e -> true
        ).size();

        if (mepCount >= MAX_MEPS) return false;

        // --- PLAYER PROXIMITY ---
        double maxSq = SPAWN_RADIUS * SPAWN_RADIUS;

        for (PlayerEntity player : world.getPlayers()) {
            if (player.squaredDistanceTo(
                pos.getX() + 0.5,
                pos.getY(),
                pos.getZ() + 0.5
            ) <= maxSq) {
                return true; // ✔ valid spawn
            }
        }

        // No nearby player → no spawn
        return false;
    }
}
