package de.winniepat.citrus.cosmetics.hat;

import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.PlayerEntityModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.RotationAxis;
import software.bernie.geckolib.renderer.GeoObjectRenderer;

import java.util.WeakHashMap;

public class HatFeatureRenderer extends FeatureRenderer<AbstractClientPlayerEntity, PlayerEntityModel<AbstractClientPlayerEntity>> {
    private final GeoObjectRenderer<CosmeticHat> hatRenderer;
    private static final WeakHashMap<PlayerEntity, CosmeticHat> HAT_CACHE = new WeakHashMap<>();

    public HatFeatureRenderer(FeatureRendererContext<AbstractClientPlayerEntity, PlayerEntityModel<AbstractClientPlayerEntity>> context) {
        super(context);
        this.hatRenderer = new GeoObjectRenderer<>(new HatModel());
    }

    @Override
    public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, AbstractClientPlayerEntity player, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {

        CosmeticHat hat = HAT_CACHE.computeIfAbsent(player, CosmeticHat::new);
        boolean shouldRender = hat.shouldRender();
        HatType type = hat.getHatType();
        if (!shouldRender) return;

        Identifier texture = this.hatRenderer.getGeoModel().getTextureResource(hat);
        if (texture == null) return;

        matrices.push();

        matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(headYaw * 0.3f));
        matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(headPitch * 0.3f));

        matrices.translate(0, -1.6, 0);

        matrices.translate(type.getPosX(), type.getPosY(), type.getPosZ());

        float scale = type.getScale();
        matrices.scale(scale, scale, scale);

        matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180f));

        try {
            this.hatRenderer.render(
                    matrices, hat, vertexConsumers,
                    RenderLayer.getEntityTranslucent(texture),
                    vertexConsumers.getBuffer(RenderLayer.getEntityTranslucent(texture)),
                    0xF000F0,
                    tickDelta
            );
        } catch (Exception e) {
            System.err.println("Failed to render hat: " + e.getMessage());
        } finally {
            matrices.pop();
        }
    }

    public static void invalidateHatCache(PlayerEntity player) {
        HAT_CACHE.remove(player);
    }
}