package de.winniepat.citrus.cosmetics.wings;

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 WingsFeatureRenderer extends FeatureRenderer<AbstractClientPlayerEntity, PlayerEntityModel<AbstractClientPlayerEntity>> {
    private final GeoObjectRenderer<CosmeticWings> wingRenderer;
    private static final WeakHashMap<PlayerEntity, CosmeticWings> WING_CACHE = new WeakHashMap<>();

    public WingsFeatureRenderer(FeatureRendererContext<AbstractClientPlayerEntity, PlayerEntityModel<AbstractClientPlayerEntity>> context) {
        super(context);
        this.wingRenderer = new GeoObjectRenderer<>(new WingsModel());
    }

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

        CosmeticWings wings = WING_CACHE.computeIfAbsent(player, CosmeticWings::new);
        if (!wings.shouldRender()) return;

        WingType type = wings.getWingType();
        if (type == WingType.NONE) return;

        Identifier texture = this.wingRenderer.getGeoModel().getTextureResource(wings);
        if (texture == null) {
            System.err.println("Wing texture is null for type: " + type.getId());
            return;
        }

        matrices.push();

        this.getContextModel().body.rotate(matrices);

        matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180f));
        matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180f));

        matrices.translate(-0.7, -2.8, 0.5);

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

        matrices.scale(type.getScale(), type.getScale(), -1.0f);

        try {
            this.wingRenderer.render(
                    matrices, wings, vertexConsumers,
                    RenderLayer.getEntityCutoutNoCull(texture),
                    vertexConsumers.getBuffer(RenderLayer.getEntityCutoutNoCull(texture)),
                    light, tickDelta
            );
        } catch (Exception e) {
            System.err.println("Failed to render wings: " + e.getMessage());
            e.printStackTrace();
        } finally {
            matrices.pop();
        }
    }

    public static void invalidateWingCache(PlayerEntity player) {
        WING_CACHE.remove(player);
    }
}