package com.tiedup.remake.events.lifecycle;

import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityDamsel;
import com.tiedup.remake.entities.EntityKidnapper;
import com.tiedup.remake.entities.EntityKidnapperArcher;
import com.tiedup.remake.entities.EntityKidnapperElite;
import com.tiedup.remake.entities.EntityKidnapperMerchant;
import com.tiedup.remake.entities.EntityMaster;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraftforge.event.entity.living.MobSpawnEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

/**
 * Event handler for controlling entity spawning via gamerules.
 *
 * Controls both on/off spawning and spawn rates:
 * - damselsSpawn + damselSpawnRate: Controls EntityDamsel
 * - kidnappersSpawn + variant rates: Controls EntityKidnapper variants
 * - masterSpawnRate: Controls EntityMaster
 *
 * Spawn rates are 0-100 percentage. For example, 50 = 50% chance to allow spawn.
 * Note: Command spawns (/tiedup npc spawn) are not affected.
 */
@Mod.EventBusSubscriber(
    modid = TiedUpMod.MOD_ID,
    bus = Mod.EventBusSubscriber.Bus.FORGE
)
public class EntitySpawnHandler {

    /**
     * Check if entity spawn should be allowed based on gamerules.
     *
     * @param event The spawn check event
     */
    @SubscribeEvent
    public static void onCheckSpawn(MobSpawnEvent.FinalizeSpawn event) {
        LivingEntity entity = event.getEntity();
        Level level = entity.level();
        GameRules gameRules = level.getGameRules();
        RandomSource random = level.getRandom();

        // Check Master spawn (separate entity, not related to Damsel)
        if (entity instanceof EntityMaster) {
            int spawnRate = SettingsAccessor.getMasterSpawnRate(gameRules);
            if (!checkSpawnRate(random, spawnRate)) {
                event.setSpawnCancelled(true);
                return;
            }
        }
        // Check Kidnapper spawn (includes Elite, Archer, Merchant)
        else if (entity instanceof EntityKidnapper kidnapper) {
            if (!SettingsAccessor.doKidnappersSpawn(gameRules)) {
                event.setSpawnCancelled(true);
                return;
            }

            // Check variant-specific spawn rate
            int spawnRate = getKidnapperVariantSpawnRate(kidnapper, gameRules);
            if (!checkSpawnRate(random, spawnRate)) {
                event.setSpawnCancelled(true);
                return;
            }
        }
        // Check Damsel spawn
        else if (entity instanceof EntityDamsel) {
            if (!SettingsAccessor.doDamselsSpawn(gameRules)) {
                event.setSpawnCancelled(true);
                return;
            }

            // Check damsel spawn rate
            int spawnRate = SettingsAccessor.getDamselSpawnRate(gameRules);
            if (!checkSpawnRate(random, spawnRate)) {
                event.setSpawnCancelled(true);
                return;
            }
        }
    }

    /**
     * Check if spawn should be allowed based on rate (0-100).
     *
     * @param random Random source
     * @param rate Spawn rate percentage (0-100)
     * @return true if spawn should be allowed
     */
    private static boolean checkSpawnRate(RandomSource random, int rate) {
        if (rate <= 0) return false;
        if (rate >= 100) return true;
        return random.nextInt(100) < rate;
    }

    /**
     * Get spawn rate for a specific kidnapper variant.
     */
    private static int getKidnapperVariantSpawnRate(
        EntityKidnapper kidnapper,
        GameRules gameRules
    ) {
        // Check class type to determine spawn rate
        if (kidnapper instanceof EntityKidnapperArcher) {
            return SettingsAccessor.getKidnapperArcherSpawnRate(gameRules);
        } else if (kidnapper instanceof EntityKidnapperElite) {
            return SettingsAccessor.getKidnapperEliteSpawnRate(gameRules);
        } else if (kidnapper instanceof EntityKidnapperMerchant) {
            return SettingsAccessor.getKidnapperMerchantSpawnRate(gameRules);
        } else {
            // Base kidnapper
            return SettingsAccessor.getKidnapperSpawnRate(gameRules);
        }
    }
}
