/*
 *  Copyright 2025-2026 R3944Realms
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package top.r3944realms.eroticdungeongame.client.renderer.armor;

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.gui.Font;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.util.FastColor;
import net.minecraft.util.FormattedCharSequence;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.entity.SignText;
import net.minecraft.world.level.block.state.properties.WoodType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.cache.object.GeoBone;
import software.bernie.geckolib.renderer.GeoArmorRenderer;
import top.r3944realms.eroticdungeongame.client.model.item.SignArmorModel;
import top.r3944realms.eroticdungeongame.content.item.SignArmorItem;

import java.util.List;
import java.util.Optional;

public class SignArmorRenderer extends GeoArmorRenderer<SignArmorItem> {
    private static final float TEXT_SCALE = 0.015625F * 0.9f;
    private static final float TEXT_Y_OFFSET = 51;
    private static final float TEXT_Z_OFFSET = -14.1f;
    private static final float LINE_HEIGHT = 9.5F;
    private float crouchingYOffset = 0;
    private boolean isCrouching;
    private boolean init;
    public SignArmorRenderer(WoodType woodType) {
        super(new SignArmorModel(woodType));
    }

    @Override
    public void preRender(PoseStack poseStack, SignArmorItem animatable, BakedGeoModel model,
                          @Nullable MultiBufferSource bufferSource, @Nullable VertexConsumer buffer,
                          boolean isReRender, float partialTick, int packedLight, int packedOverlay,
                          float red, float green, float blue, float alpha) {
        super.preRender(poseStack, animatable, model, bufferSource, buffer,
                isReRender, partialTick, packedLight, packedOverlay, red, green, blue, alpha);
        if (currentEntity != null && currentEntity.isCrouching()) {
            crouchingYOffset = -4.5f;
            isCrouching = true;
            Optional<GeoBone> bipedBody = this.model.getBone("bipedBody");
            bipedBody.ifPresent(geoBone -> geoBone.setPosY(crouchingYOffset));
        } else {
            crouchingYOffset = 0;
            isCrouching = false;
        }
    }

    @Override
    public void actuallyRender(PoseStack poseStack, SignArmorItem animatable, BakedGeoModel model, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
        super.actuallyRender(poseStack, animatable, model, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, red, green, blue, alpha);
        // 后渲染文字
        renderSignText(animatable, poseStack, bufferSource, packedLight, animatable.getTextLineHeight(), animatable.getMaxTextLineWidth());
    }

    private void renderSignText(@NotNull SignArmorItem armorItem, PoseStack poseStack,
                                MultiBufferSource bufferSource, int packedLight, int lineHeight, int maxWidth) {
        SignText signText = armorItem.getSignText(currentStack);
        if (signText == null) {
            return;
        }

        // 检查是否有任何文字
        boolean hasText = false;
        for (int i = 0; i < 4; i++) {
            if (!signText.getMessage(i, false).getString().isEmpty()) {
                hasText = true;
                break;
            }
        }
        if (!hasText) return;

        Minecraft mc = Minecraft.getInstance();
        Font font = mc.font;

        poseStack.pushPose();
        poseStack.scale(TEXT_SCALE, TEXT_SCALE, TEXT_SCALE);
        poseStack.mulPose(Axis.XP.rotationDegrees(-7.5f));
        poseStack.translate(0, TEXT_Y_OFFSET, TEXT_Z_OFFSET);
        if(isCrouching) {
            poseStack.translate(0,  - (crouchingYOffset*4.5), 3.2);
        }

        // 发光文字使用高亮度
        int light = signText.hasGlowingText() ? 15728880 : packedLight;

        for (int i = 0; i < 4; i++) {
            if (!signText.getMessage(i, false).getString().isEmpty()) {
                break;
            }
        }


        // 获取文字颜色（原版使用 getDarkColor）
        int darkColor = getDarkColor(signText);

        // 获取渲染用的文字行（原版使用 getRenderMessages）
        FormattedCharSequence[] renderMessages = signText.getRenderMessages(Minecraft.getInstance().isTextFilteringEnabled(), (split) -> {
            List<FormattedCharSequence> list = font.split(split, maxWidth);
            return list.isEmpty() ? FormattedCharSequence.EMPTY : list.get(0);
        });

        // 确定是否使用发光文字
        boolean hasGlowingText = signText.hasGlowingText();
        int glowLight = hasGlowingText ? 15728880 : packedLight;
        int textColor = hasGlowingText ? signText.getColor().getTextColor() : darkColor;

        // 渲染4行文字（原版循环）
        for (int line = 0; line < 4; line++) {
            FormattedCharSequence formattedText = renderMessages[line];
            if (formattedText != null) {
                // 计算X轴偏移（居中）
                float xOffset = (float)(-font.width(formattedText) / 2);
                // 计算Y轴偏移（原版公式）
                float yOffset = line * LINE_HEIGHT - 4 * LINE_HEIGHT / 2;

                if (hasGlowingText) {
                    // 发光文字
                    font.drawInBatch8xOutline(
                            formattedText,
                            xOffset, yOffset,
                            textColor,      // 内部颜色
                            darkColor,   // 轮廓颜色
                            poseStack.last().pose(),
                            bufferSource,
                            glowLight
                    );
                } else {
                    // 普通文字
                    font.drawInBatch(
                            formattedText,
                            xOffset, yOffset,
                            textColor,
                            false,
                            poseStack.last().pose(),
                            bufferSource,
                            Font.DisplayMode.POLYGON_OFFSET,
                            0,
                            packedLight
                    );
                }
            }
        }

        poseStack.popPose();
    }

    static int getDarkColor(@NotNull SignText signText) {
        int i = signText.getColor().getTextColor();
        if (i == DyeColor.BLACK.getTextColor() && signText.hasGlowingText()) {
            return -988212;
        } else {
            double d0 = 0.4;
            int j = (int)((double) FastColor.ARGB32.red(i) * 0.4);
            int k = (int)((double) FastColor.ARGB32.green(i) * 0.4);
            int l = (int)((double) FastColor.ARGB32.blue(i) * 0.4);
            return FastColor.ARGB32.color(0, j, k, l);
        }
    }
}
