package net.mcreator.customoregen;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.biome.Biome;
import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.common.EventBusSubscriber;

import java.util.*;

@EventBusSubscriber(modid = CustomOreGenMod.MODID, bus = EventBusSubscriber.Bus.GAME)
public class OresCommand {

	// Tags personnalisés du mod
	private static final TagKey<Biome> COLD_BIOMES_TAG = TagKey.create(Registries.BIOME,
			ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "cold_biomes"));
	private static final TagKey<Biome> HOT_BIOMES_TAG = TagKey.create(Registries.BIOME,
			ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "hot_biomes"));
	private static final TagKey<Biome> MOUNTAIN_BIOMES_TAG = TagKey.create(Registries.BIOME,
			ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "mountain_biomes"));
	private static final TagKey<Biome> TEMPERED_BIOMES_TAG = TagKey.create(Registries.BIOME,
			ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "tempered_biomes"));
	private static final TagKey<Biome> RARE_BIOMES_TAG = TagKey.create(Registries.BIOME,
			ResourceLocation.fromNamespaceAndPath("custom_ore_gen", "rare_biomes"));

	// Minerais par catégorie (mappé avec les biome modifiers)
	private static final List<String> COLD_ORES = Arrays.asList(
			"Lapis (stone) [Y: 0 à 32]",
			"Lapis (deepslate) [Y: -64 à 0]",
			"Diamant (deepslate) [Y: -64 à 0]");

	private static final List<String> HOT_ORES = Arrays.asList(
			"Or Pur (stone) [Y: 0 à 256]",
			"Or Pur (deepslate) [Y: -64 à 0]",
			"Redstone (stone) [Y: -10 à 20]",
			"Redstone (deepslate) [Y: -80 à -30]",
			"Cuivre (haut) [Y: 15 à 256]",
			"Cuivre (bas) [Y: -64 à 0]");

	private static final List<String> MOUNTAIN_ORES = Arrays.asList(
			"Emeraude (haute altitude) [Y: 0 à 64]");

	private static final List<String> TEMPERED_ORES = Arrays.asList(
			"Charbon Concentre [Y: 0 à 70]",
			"Fer (stone) [Y: 0 à 100]",
			"Fer (deepslate) [Y: -64 à 0]");

	private static final List<String> RARE_ORES = Arrays.asList(
			"Emeraude (basse altitude) [Y: -64 à 0]");

	private static final List<String> EVERYWHERE_ORES = Arrays.asList(
			"Diamant Shard (deepslate) [Y: -64 à -40]",
			"Bloc Diamant Shard [Y: 0 à 15]");

	@SubscribeEvent
	public static void onRegisterCommands(RegisterCommandsEvent event) {
		CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher();

		// Niveau de permission 2 = OP (Admin level)
		dispatcher.register(Commands.literal("ores")
				.requires(source -> source.hasPermission(2))
				.executes(OresCommand::executeOres));

		dispatcher.register(Commands.literal("ore")
				.requires(source -> source.hasPermission(2))
				.executes(OresCommand::executeOres));
	}

	private static int executeOres(CommandContext<CommandSourceStack> context) {
		if (!(context.getSource().getEntity() instanceof net.minecraft.world.entity.player.Player)) {
			context.getSource()
					.sendFailure(Component.literal("Cette commande ne peut etre utilisee que par un joueur"));
			return 0;
		}

		net.minecraft.world.entity.player.Player player = (net.minecraft.world.entity.player.Player) context.getSource()
				.getEntity();
		net.minecraft.world.level.Level level = player.level();
		net.minecraft.core.BlockPos pos = player.blockPosition();

		var biomeHolder = level.getBiome(pos);
		ResourceKey<Biome> biomeKey = biomeHolder.unwrapKey()
				.orElse(ResourceKey.create(Registries.BIOME, ResourceLocation.fromNamespaceAndPath("minecraft", "plains")));
		ResourceLocation biomeId = biomeKey.location();
		String biomeName = biomeId.getPath();

		context.getSource().sendSuccess(() -> Component.literal("=== Minerais dans: " + biomeName + " ==="), true);
		context.getSource().sendSuccess(() -> Component.literal("Biome ID: " + biomeId), true);

		// Vérifier les tags personnalisés du mod
		Set<String> foundTags = new HashSet<>();
		List<String> foundOres = new ArrayList<>();

		// Vérifier chaque tag de biome et ajouter les minerais correspondants
		if (isBiomeInTag(level, pos, COLD_BIOMES_TAG)) {
			foundTags.add("cold_biomes");
			foundOres.addAll(COLD_ORES);
		}
		if (isBiomeInTag(level, pos, HOT_BIOMES_TAG)) {
			foundTags.add("hot_biomes");
			foundOres.addAll(HOT_ORES);
		}
		if (isBiomeInTag(level, pos, MOUNTAIN_BIOMES_TAG)) {
			foundTags.add("mountain_biomes");
			foundOres.addAll(MOUNTAIN_ORES);
		}
		if (isBiomeInTag(level, pos, TEMPERED_BIOMES_TAG)) {
			foundTags.add("tempered_biomes");
			foundOres.addAll(TEMPERED_ORES);
		}
		if (isBiomeInTag(level, pos, RARE_BIOMES_TAG)) {
			foundTags.add("rare_biomes");
			foundOres.addAll(RARE_ORES);
		}

		// Ajouter les minerais présents partout
		foundOres.addAll(EVERYWHERE_ORES);

		// Afficher les tags trouvés
		if (!foundTags.isEmpty()) {
			context.getSource().sendSuccess(() -> Component.literal("Tags du mod: " + String.join(", ", foundTags)),
					true);
		} else {
			context.getSource().sendSuccess(() -> Component.literal("Tags du mod: aucun"), true);
		}

		// Afficher les minerais (sans doublons)
		if (!foundOres.isEmpty()) {
			Set<String> uniqueOres = new LinkedHashSet<>(foundOres);
			context.getSource().sendSuccess(() -> Component.literal("Minerais trouvables:"), true);
			for (String ore : uniqueOres) {
				context.getSource().sendSuccess(() -> Component.literal("  * " + ore), true);
			}
		} else {
			context.getSource().sendSuccess(() -> Component.literal("Aucun minerai specifique"), true);
		}

		return 1;
	}

	private static boolean isBiomeInTag(net.minecraft.world.level.Level level, net.minecraft.core.BlockPos pos,
			TagKey<Biome> tag) {
		return level.getBiome(pos).is(tag);
	}
}
