package net.halbear.aotg.utility;

import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.ColorTargetState;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.serialization.MapCodec;
import net.halbear.aotg.AgeoftheGods;
import net.halbear.aotg.registries.ModBlocks;
import net.halbear.aotg.rendering.skybox.SkyBoxRendering;
import net.minecraft.client.color.block.BlockTintSource;
import net.minecraft.client.color.item.GrassColorSource;
import net.minecraft.client.color.item.ItemTintSource;
import net.minecraft.client.color.item.ItemTintSources;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.client.renderer.RenderPipelines;
import net.minecraft.client.renderer.block.BlockAndTintGetter;
import net.minecraft.client.renderer.rendertype.RenderType;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.Identifier;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GrassColor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.EventBus;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent;
import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent.BlockTintSources;
import net.neoforged.neoforge.client.event.RegisterRenderPipelinesEvent;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nullable;
import java.util.List;

import static net.minecraft.client.renderer.RenderPipelines.MATRICES_PROJECTION_SNIPPET;

@EventBusSubscriber(modid = AgeoftheGods.MODID, value = Dist.CLIENT)
public class ModEventHandler {

    @SubscribeEvent
    public static void onRegisterPipelines(RegisterRenderPipelinesEvent event) {
        SkyBoxRendering.CUSTOM_SKYBOX_PIPELINE = RenderPipeline.builder(new RenderPipeline.Snippet[]{MATRICES_PROJECTION_SNIPPET})
                .withLocation(Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "pipeline/custom_skybox"))
                .withVertexShader(Identifier.withDefaultNamespace("core/position_tex"))
                .withFragmentShader(Identifier.withDefaultNamespace("core/position_tex"))
                .withSampler("Sampler0")
                .withCull(false)
                .withColorTargetState(new ColorTargetState(BlendFunction.TRANSLUCENT)).withVertexFormat(DefaultVertexFormat.POSITION_TEX, VertexFormat.Mode.QUADS).build();

        event.registerPipeline(SkyBoxRendering.CUSTOM_SKYBOX_PIPELINE);
        System.out.println("Age of the Gods pipeline Registered");
    }

    public static void BlockTint(RegisterColorHandlersEvent.BlockTintSources event, Block block) {
        event.register(
                List.of(new BlockTintSource() {
                    @Override
                    public int color(BlockState state) {
                        return 0xFFFFFFFF;
                    }

                    @Override
                    public int colorInWorld(BlockState state, BlockAndTintGetter level, BlockPos pos) {
                        return BiomeColors.getAverageGrassColor(level, pos);
                    }
                }),
                block
        );
    }

    public static void BlockFoliageTint(RegisterColorHandlersEvent.BlockTintSources event, Block block) {
        event.register(
                List.of(new BlockTintSource() {
                    @Override
                    public int color(BlockState state) {
                        return 0xFFFFFFFF;
                    }

                    @Override
                    public int colorInWorld(BlockState state, BlockAndTintGetter level, BlockPos pos) {
                        return BiomeColors.getAverageFoliageColor(level, pos);
                    }
                }),
                block
        );
    }

    @SubscribeEvent
    public static void registerBlockTint(RegisterColorHandlersEvent.BlockTintSources event) {
        BlockTint(event, ModBlocks.LIMESTONE_GRASS_BLOCK.get());
        BlockTint(event, ModBlocks.SHALE_GRASS_BLOCK.get());
        BlockFoliageTint(event, ModBlocks.OLIVE_LEAVES.get());
    }

    @SubscribeEvent
    public static void registerItemTint(RegisterColorHandlersEvent.ItemTintSources event) {
        event.register( ModBlocks.LIMESTONE_GRASS_BLOCK.getId(),
                (new CustomItemGrassTint().type()) );
        event.register( ModBlocks.SHALE_GRASS_BLOCK.getId(),
                (new CustomItemGrassTint().type()) );
        event.register( ModBlocks.OLIVE_LEAVES.getId(),
                (new CustomItemGrassTint().type()) );
    }

    private static class CustomItemGrassTint implements ItemTintSource {
        @Override
        public int calculate(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity) {
            return GrassColor.get(0.5D, 1.0D);
        }

        @Override
        public @NotNull MapCodec<? extends ItemTintSource> type() {
            return MapCodec.unit(this);
        }
    }
}