package top.r3944realms.lib39.client.renderer.block;

import com.mojang.authlib.GameProfile;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.DefaultPlayerSkin;
import net.minecraft.client.resources.PlayerSkin;
import net.minecraft.client.resources.SkinManager;
import net.minecraft.core.Direction;
import net.minecraft.resources.Identifier;
import net.minecraft.world.item.component.ResolvableProfile;
import net.minecraft.world.level.block.SkullBlock;
import net.minecraft.world.level.block.WallSkullBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.RotationSegment;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import top.r3944realms.lib39.client.model.DollModel;
import top.r3944realms.lib39.content.block.AbstractDollBlock;
import top.r3944realms.lib39.content.block.WallDollBlock;
import top.r3944realms.lib39.content.block.blockentity.DollBlockEntity;
import top.r3944realms.lib39.util.lang.Pair;

import java.util.Optional;

/**
 * The type Doll block entity renderer.
 */
public class DollBlockEntityRenderer implements BlockEntityRenderer<DollBlockEntity> {
    private final DollModel dollModel;

    /**
     * Instantiates a new Doll block entity renderer.
     *
     * @param context the context
     */
    public DollBlockEntityRenderer(BlockEntityRendererProvider.@NotNull Context context) {
        this.dollModel = new DollModel(context.bakeLayer(DollModel.LAYER_LOCATION));
    }

    @Override
    public void render(@NotNull DollBlockEntity dollBlockEntity, float partialTick, @NotNull PoseStack poseStack, @NotNull MultiBufferSource buffer, int packedLight, int packedOverlay) {
        BlockState blockState = dollBlockEntity.getBlockState();
        if (blockState.getBlock() instanceof AbstractDollBlock dollBlock) {
            boolean isWall = dollBlock instanceof WallDollBlock;
            Direction direction = isWall ? blockState.getValue(WallSkullBlock.FACING) : null;
            float rotation = isWall ? direction.toYRot() : RotationSegment.convertToDegrees(blockState.getValue(SkullBlock.ROTATION));
            Pair<PlayerSkin.Model, RenderType> modelAndRenderTypePair = getModelAndRenderTypePair(dollBlockEntity.getOwnerProfile());
            poseStack.pushPose();
            poseStack.translate(0.5, 1.5, 0.5);
            poseStack.scale(1.0F, -1.0F, -1.0F);
            poseStack.mulPose(Axis.YP.rotationDegrees(rotation));
            VertexConsumer vertexConsumer = buffer.getBuffer(modelAndRenderTypePair.second);
            this.dollModel.slim = modelAndRenderTypePair.first == PlayerSkin.Model.SLIM;
            this.dollModel.renderToBuffer(poseStack, vertexConsumer, packedLight, OverlayTexture.NO_OVERLAY,-1);
            poseStack.popPose();
        }
    }
    public static @NotNull Pair<PlayerSkin.Model, RenderType> getModelAndRenderTypePair(@Nullable ResolvableProfile profile) {
        SkinManager skinmanager = Minecraft.getInstance().getSkinManager();

        if (profile == null) {
            return Pair.of(PlayerSkin.Model.SLIM,
                    RenderType.entityTranslucent(DefaultPlayerSkin.getDefaultTexture()));
        }

        GameProfile gameProfile = profile.gameProfile();

        // 如果当前 Profile 没有纹理数据，尝试从 DollBlockEntity 缓存获取
        if (gameProfile != null && gameProfile.getProperties().isEmpty()
                && gameProfile.getName() != null && !gameProfile.getName().isEmpty()) {
            Optional<GameProfile> cached = DollBlockEntity.fetchGameProfile(gameProfile.getName())
                    .getNow(Optional.empty());
            if (cached.isPresent() && !cached.get().getProperties().isEmpty()) {
                gameProfile = cached.get();
            }
        }

        if (gameProfile != null && !gameProfile.getProperties().isEmpty()) {
            PlayerSkin skin = skinmanager.getInsecureSkin(gameProfile);
            return Pair.of(skin.model(), RenderType.entityTranslucent(skin.texture()));
        }

        return Pair.of(PlayerSkin.Model.SLIM,
                RenderType.entityTranslucent(DefaultPlayerSkin.getDefaultTexture()));
    }
}
