package net.mcreator.customoregen.procedures;

import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.core.Holder;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.item.Items;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.ExperienceOrb;

import net.mcreator.customoregen.config.ModConfigs;
import net.mcreator.customoregen.init.CustomOreGenModItems;

import java.util.Random;

public class ConfigurableOreDropsProcedure {

	public static void execute(LevelAccessor world, double x, double y, double z, Entity entity, String oreType) {
		if (world.isClientSide())
			return;

		Random random = new Random();
		int fortuneLevel = 0;
		boolean silkTouch = false;

		// Get fortune and silk touch from the tool if mining by player
		if (entity instanceof Player) {
			Player player = (Player) entity;
			ItemStack mainHandItem = player.getMainHandItem();
			// 1.21: Enchantment API changed - use getAllEnchantments with registry lookup
			var enchantmentRegistry = world.registryAccess().lookupOrThrow(Registries.ENCHANTMENT);
			for (Holder<Enchantment> enchantment : mainHandItem.getAllEnchantments(enchantmentRegistry).keySet()) {
				if (enchantment.is(Enchantments.FORTUNE)) {
					fortuneLevel = mainHandItem.getAllEnchantments(enchantmentRegistry).getLevel(enchantment);
				}
				if (enchantment.is(Enchantments.SILK_TOUCH)) {
					silkTouch = mainHandItem.getAllEnchantments(enchantmentRegistry).getLevel(enchantment) > 0;
				}
			}
		}

		// If silk touch, drop the block itself and return
		if (silkTouch) {
			return; // Let vanilla handle silk touch
		}

		int minDrops = 1;
		int maxDrops = 2;
		boolean enableFortune = true;
		ItemStack dropItem = ItemStack.EMPTY;

		// Configure drops based on ore type
		switch (oreType) {
			case "shard_diamond":
				minDrops = ModConfigs.DROPS.shardDiamondOreMinDrops.get();
				maxDrops = ModConfigs.DROPS.shardDiamondOreMaxDrops.get();
				enableFortune = ModConfigs.DROPS.shardDiamondOreEnableFortune.get();
				dropItem = new ItemStack(CustomOreGenModItems.DIAMONDSHARD.get());
				break;

			case "concentrated_diamond":
				minDrops = ModConfigs.DROPS.concentratedDiamondOreMinDrops.get();
				maxDrops = ModConfigs.DROPS.concentratedDiamondOreMaxDrops.get();
				enableFortune = ModConfigs.DROPS.concentratedDiamondOreEnableFortune.get();
				dropItem = new ItemStack(Items.DIAMOND);
				break;

			case "concentrated_coal":
				minDrops = ModConfigs.DROPS.concentratedCoalOreMinDrops.get();
				maxDrops = ModConfigs.DROPS.concentratedCoalOreMaxDrops.get();
				enableFortune = ModConfigs.DROPS.concentratedCoalOreEnableFortune.get();
				dropItem = new ItemStack(Items.COAL);
				break;

			case "pure_golden":
				minDrops = ModConfigs.DROPS.pureGoldenOreMinDrops.get();
				maxDrops = ModConfigs.DROPS.pureGoldenOreMaxDrops.get();
				enableFortune = ModConfigs.DROPS.pureGoldenOreEnableFortune.get();
				dropItem = new ItemStack(Items.RAW_GOLD);
				break;

			case "impure_iron":
				minDrops = ModConfigs.DROPS.impureIronOreMinDrops.get();
				maxDrops = ModConfigs.DROPS.impureIronOreMaxDrops.get();
				enableFortune = ModConfigs.DROPS.impureIronOreEnableFortune.get();
				dropItem = new ItemStack(Items.RAW_IRON);
				break;

			case "impure_gold":
				minDrops = ModConfigs.DROPS.impureGoldOreMinDrops.get();
				maxDrops = ModConfigs.DROPS.impureGoldOreMaxDrops.get();
				dropItem = new ItemStack(Items.RAW_GOLD);
				break;

			case "lapis":
				minDrops = ModConfigs.DROPS.lapisOreMinDrops.get();
				maxDrops = ModConfigs.DROPS.lapisOreMaxDrops.get();
				enableFortune = ModConfigs.DROPS.lapisOreEnableFortune.get();
				dropItem = new ItemStack(Items.LAPIS_LAZULI);
				break;

			case "redstone":
				minDrops = ModConfigs.DROPS.redstoneOreMinDrops.get();
				maxDrops = ModConfigs.DROPS.redstoneOreMaxDrops.get();
				enableFortune = ModConfigs.DROPS.redstoneOreEnableFortune.get();
				dropItem = new ItemStack(Items.REDSTONE);
				break;

			case "emerald":
				minDrops = ModConfigs.DROPS.emeraldOreMinDrops.get();
				maxDrops = ModConfigs.DROPS.emeraldOreMaxDrops.get();
				dropItem = new ItemStack(Items.EMERALD);
				break;

			case "copper":
				minDrops = ModConfigs.DROPS.copperOreMinDrops.get();
				maxDrops = ModConfigs.DROPS.copperOreMaxDrops.get();
				enableFortune = ModConfigs.DROPS.copperOreEnableFortune.get();
				dropItem = new ItemStack(Items.RAW_COPPER);
				break;

			default:

				return;
		}

		// Calculate base drops
		int dropCount = minDrops + (maxDrops > minDrops ? random.nextInt(maxDrops - minDrops + 1) : 0);

		// Apply fortune if enabled
		if (enableFortune && fortuneLevel > 0) {
			if (oreType.equals("lapis") || oreType.equals("copper") || oreType.equals("redstone")) {
				// Vanilla-like multiplier for multi-drop ores (Lapis, Copper, Redstone)
				// Level 3: 2/5 chance of x1, 1/5 chance of x2, 1/5 chance of x3, 1/5 chance of x4
				int multiplier = random.nextInt(fortuneLevel + 2) - 1;
				if (multiplier < 0) multiplier = 0;
				dropCount *= (multiplier + 1);
			} else {
				// Vanilla-like bonus for discrete ores (Diamond, Coal, Emerald)
				int fortuneBonus = random.nextInt(fortuneLevel + 2) - 1;
				if (fortuneBonus < 0) fortuneBonus = 0;
				dropCount += fortuneBonus;
			}
		}

		/* 
		// ITEM DROPS ARE NOW HANDLED BY CustomLootModifier TO SUPPORT MACHINES (like Mekanism Digital Miner)
		// This avoids duplicate drops for players and ensures machines get drops.
		if (!dropItem.isEmpty() && dropCount > 0) {
			dropItem.setCount(dropCount);
			if (world instanceof ServerLevel) {
				ItemEntity itemEntity = new ItemEntity(
						(ServerLevel) world,
						x + 0.5, y + 0.5, z + 0.5,
						dropItem
				);
				itemEntity.setDefaultPickUpDelay();
				((ServerLevel) world).addFreshEntity(itemEntity);
			}
		}
		*/

		// Drop experience based on ore type (Vanilla 1.21 values)
		int expAmount = 0;
		if (entity instanceof Player) {
			switch (oreType) {
				case "concentrated_coal":
					expAmount = random.nextInt(3); // 0-2
					break;
				case "shard_diamond":
				case "concentrated_diamond":
				case "emerald":
					expAmount = 3 + random.nextInt(5); // 3-7
					break;
				case "lapis":
					expAmount = 2 + random.nextInt(4); // 2-5
					break;
				case "redstone":
					expAmount = 1 + random.nextInt(5); // 1-5
					break;
				// Iron, Gold, Copper ores don't drop XP in Vanilla 1.21 (only after smelting)
			}

			if (expAmount > 0 && world instanceof ServerLevel) {
				ExperienceOrb expOrb = new ExperienceOrb(
						(ServerLevel) world,
						x + 0.5, y + 0.5, z + 0.5,
						expAmount
				);
				((ServerLevel) world).addFreshEntity(expOrb);
			}
		}
	}
}
