package moe.hazu.tinkeringabnormally;

import com.mojang.logging.LogUtils;
import com.teamabnormals.caverns_and_chasms.core.CavernsAndChasms;
import com.teamabnormals.caverns_and_chasms.core.other.CCTiers;
import moe.hazu.tinkeringabnormally.data.*;
import moe.hazu.tinkeringabnormally.data.material.MaterialRecipeProvider;
import moe.hazu.tinkeringabnormally.data.material.MaterialRenderInfoProvider;
import moe.hazu.tinkeringabnormally.data.sprite.TinkerMaterialSpriteProvider;
import moe.hazu.tinkeringabnormally.data.tags.FluidTagProvider;
import net.minecraft.client.Minecraft;
import net.minecraft.data.DataGenerator;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.item.*;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.pathfinder.BlockPathTypes;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.SoundActions;
import net.minecraftforge.common.TierSortingRegistry;
import net.minecraftforge.common.data.ExistingFileHelper;
import net.minecraftforge.data.event.GatherDataEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fluids.FluidType;
import net.minecraftforge.fluids.ForgeFlowingFluid;
import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import net.minecraftforge.event.server.ServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import org.slf4j.Logger;
import slimeknights.mantle.registration.deferred.FluidDeferredRegister;
import slimeknights.mantle.registration.object.FlowingFluidObject;
import slimeknights.tconstruct.TConstruct;
import slimeknights.tconstruct.fluids.data.FluidBlockstateModelProvider;
import slimeknights.tconstruct.fluids.data.FluidBucketModelProvider;
import slimeknights.tconstruct.library.client.data.material.AbstractMaterialSpriteProvider;
import slimeknights.tconstruct.library.client.data.material.MaterialPaletteDebugGenerator;
import slimeknights.tconstruct.library.client.data.material.MaterialPartTextureGenerator;
import slimeknights.tconstruct.library.modifiers.ModifierId;
import slimeknights.tconstruct.tools.data.sprite.TinkerPartSpriteProvider;

import java.util.List;

import static slimeknights.tconstruct.fluids.block.BurningLiquidBlock.createBurning;

@Mod(TinkeringAbnormally.MODID)
public class TinkeringAbnormally {

    public static final String MODID = "tinkering_abnormally";
    public static final Logger LOGGER = LogUtils.getLogger();
    protected static final FluidDeferredRegister FLUIDS = new FluidDeferredRegister(MODID);

    public static final FlowingFluidObject<ForgeFlowingFluid> moltenSpinel  = FLUIDS.register("molten_spinel").type(hot("molten_spinel").temperature(1450).lightLevel(10)).block(createBurning(10, 10, 6f)).bucket().flowing();
    public static final FlowingFluidObject<ForgeFlowingFluid> moltenNecromium   = FLUIDS.register("molten_necromium").type(hot("molten_necromium").temperature(1600).lightLevel(14)).block(createBurning(14, 10, 10f)).bucket().flowing();
    // just for the fucking record i have NO CLUE what's going on here
    public static final Tier NECROMIUM = TierSortingRegistry.registerTier(CCTiers.CCItemTiers.NECROMIUM, new ResourceLocation(CavernsAndChasms.MOD_ID, "necromium"), List.of(Tiers.DIAMOND), List.of());


    public TinkeringAbnormally() {
        IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();

        modEventBus.addListener(this::commonSetup);
        modEventBus.addListener(this::gatherData);

        FLUIDS.register(modEventBus);

        MinecraftForge.EVENT_BUS.register(this);
    }

    // taken from slimeknights.tconstruct.fluids.TinkerFluids
    private static FluidType.Properties hot(String name) {
        return FluidType.Properties.create().density(2000).viscosity(10000).temperature(1000)
                .descriptionId(TConstruct.makeDescriptionId("fluid", name))
                .sound(SoundActions.BUCKET_FILL, SoundEvents.BUCKET_FILL_LAVA)
                .sound(SoundActions.BUCKET_EMPTY, SoundEvents.BUCKET_EMPTY_LAVA)
                // from forge lava type
                .motionScale(0.0023333333333333335D)
                .canSwim(false).canDrown(false)
                .pathType(BlockPathTypes.LAVA).adjacentPathType(null);
    }

    private void commonSetup(final FMLCommonSetupEvent event) {
        LOGGER.info("HELLO FROM COMMON SETUP");
        LOGGER.info("DIRT BLOCK >> {}", ForgeRegistries.BLOCKS.getKey(Blocks.DIRT));
    }

    public static ResourceLocation getResource(String name) {
        return new ResourceLocation(MODID, name);
    }

    @SubscribeEvent
    void gatherData(final GatherDataEvent event) {
        boolean server = event.includeServer();
        boolean client = event.includeClient();
        DataGenerator datagenerator = event.getGenerator();
        ExistingFileHelper existingFileHelper = event.getExistingFileHelper();

        datagenerator.addProvider(server, new ModifierProvider(datagenerator));
        datagenerator.addProvider(server, new ModifierRecipeProvider(datagenerator));
        datagenerator.addProvider(server, new MaterialRecipeProvider(datagenerator));
        datagenerator.addProvider(server, new SmelteryRecipeProvider(datagenerator));
        datagenerator.addProvider(server, new FluidTagProvider(datagenerator, existingFileHelper));
        TinkerMaterialSpriteProvider materialSprites = new TinkerMaterialSpriteProvider();
        datagenerator.addProvider(client, new MaterialRenderInfoProvider(datagenerator, materialSprites, existingFileHelper));
        datagenerator.addProvider(client, new MaterialPartTextureGenerator(datagenerator, existingFileHelper, new TinkerPartSpriteProvider(), materialSprites));
        datagenerator.addProvider(client, new FluidTextureProvider(datagenerator));
        datagenerator.addProvider(client, new FluidBucketModelProvider(datagenerator, MODID));
        datagenerator.addProvider(client, new FluidBlockstateModelProvider(datagenerator, MODID));
    }
}
