package net.mcreator.customoregen;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

import net.neoforged.fml.ModContainer;
import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.fml.util.thread.SidedThreadGroups;
import net.neoforged.fml.common.Mod;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.event.tick.ServerTickEvent;
import net.neoforged.neoforge.common.NeoForge;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.core.registries.Registries;

import net.mcreator.customoregen.init.CustomOreGenModTabs;
import net.mcreator.customoregen.init.CustomOreGenModItems;
import net.mcreator.customoregen.init.CustomOreGenModBlocks;
import net.mcreator.customoregen.item.ShardDiamondArmorMaterial;
import net.mcreator.customoregen.config.ModConfigs;
import net.neoforged.fml.config.ModConfig;


import net.neoforged.neoforge.common.loot.IGlobalLootModifier;
import com.mojang.serialization.MapCodec;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import net.mcreator.customoregen.loot.CustomOreLootModifier;
import net.mcreator.customoregen.worldgen.WorldGenRegistration;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.List;
import java.util.Collection;
import java.util.ArrayList;
import java.util.AbstractMap;

@Mod(CustomOreGenMod.MODID)
public class CustomOreGenMod {
	public static final Logger LOGGER = LogManager.getLogger(CustomOreGenMod.class);
	public static final String MODID = "custom_ore_gen";
	public static final DeferredRegister<MapCodec<? extends IGlobalLootModifier>> LOOT_MODIFIERS = DeferredRegister.create(NeoForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, MODID);

	public CustomOreGenMod(IEventBus modEventBus, ModContainer container) {
		// Start of user code block mod constructor
		container.registerConfig(ModConfig.Type.COMMON, ModConfigs.SPEC);
		LOOT_MODIFIERS.register("custom_ore_drops", () -> CustomOreLootModifier.CODEC);
		// End of user code block mod constructor

		NeoForge.EVENT_BUS.register(this);

		CustomOreGenModBlocks.REGISTRY.register(modEventBus);
		CustomOreGenModItems.REGISTRY.register(modEventBus);
		ShardDiamondArmorMaterial.REGISTRY.register(modEventBus);

		CustomOreGenModTabs.REGISTRY.register(modEventBus);
		LOOT_MODIFIERS.register(modEventBus);

		// Start of user code block mod init
		WorldGenRegistration.BIOME_SOURCES.register(modEventBus);
		WorldGenRegistration.BIOME_MODIFIER_SERIALIZERS.register(modEventBus);
		// End of user code block mod init
	}

	// Start of user code block mod methods
	// End of user code block mod methods
	private static final Collection<AbstractMap.SimpleEntry<Runnable, Integer>> workQueue = new ConcurrentLinkedQueue<>();

	public static void queueServerWork(int tick, Runnable action) {
		if (Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER)
			workQueue.add(new AbstractMap.SimpleEntry<>(action, tick));
	}

	@SubscribeEvent
	public void tick(ServerTickEvent.Post event) {
		List<AbstractMap.SimpleEntry<Runnable, Integer>> actions = new ArrayList<>();
		workQueue.forEach(work -> {
			work.setValue(work.getValue() - 1);
			if (work.getValue() == 0)
				actions.add(work);
		});
		actions.forEach(e -> e.getKey().run());
		workQueue.removeAll(actions);
	}
}
