package top.r3944realms.lib39.client.gui.component;

import com.mojang.blaze3d.platform.Window;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.network.chat.Component;
import org.joml.Matrix4f;
import org.joml.Vector2f;
import top.r3944realms.lib39.client.shader.Lib39Shaders;
import top.r3944realms.lib39.util.MathUtil;
import top.r3944realms.lib39.util.lang.FourConsumer;
import top.r3944realms.lib39.util.lang.Pair;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * The type Wheel widget.
 *
 * @author QiuShui1012
 */
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class WheelWidget extends AbstractWidget {
    /**
     * The constant IGNORE_CURSOR_MOVE_LENGTH.
     */
    public static final int IGNORE_CURSOR_MOVE_LENGTH = 15;
    private static final Vector2f ROTATION_START = new Vector2f(0, 1);
    private static final int SELECTION_EFFECT_COLOR = 0xddFFFF00;
    private static final int SELECTION_EFFECT_RADIUS = 20;

    private final Minecraft minecraft = Minecraft.getInstance();
    private final Vector2f centerPos;
    private final float ringInnerRadius;
    private final float ringOuterRadius;
    private final int delay;
    private final int animationMs;
    private final int closingAnimationMs; //ms
    private final int ringColor;
    private final int selectionEffectColor;
    private final int selectionEffectRadius;
    private final float selectionAnimationSpeedFactor;
    private final int textColor;
    private final float textScale;
    private final List<WheelSection> sections = new ArrayList<>();

    private long displayTime = System.currentTimeMillis();
    private float currentAngle = 0;

    /**
     * Gets current section index.
     *
     * @return the current section index
     */
    public int getCurrentSectionIndex() {
        return currentSectionIndex;
    }

    /**
     * Is closing animation started boolean.
     *
     * @return the boolean
     */
    public boolean isClosingAnimationStarted() {
        return closingAnimationStarted;
    }

    private int currentSectionIndex = -1;
    private Vector2f selectionEffectPos;
    private boolean animationStarted = false;

    /**
     * Sets closing animation started.
     *
     * @param closingAnimationStarted the closing animation started
     */
    public void setClosingAnimationStarted(boolean closingAnimationStarted) {
        this.closingAnimationStarted = closingAnimationStarted;
    }

    private boolean closingAnimationStarted = false;

    /**
     * Instantiates a new Wheel widget.
     *
     * @param x               the x
     * @param y               the y
     * @param width           the width
     * @param height          the height
     * @param ringInnerRadius the ring inner radius
     * @param ringOuterRadius the ring outer radius
     * @param textScale       the text scale
     * @param sections        the sections
     */
    public WheelWidget(
            int x, int y, int width, int height,
            float ringInnerRadius, float ringOuterRadius, float textScale,
            List<Pair<Component, FourConsumer<GuiGraphics, PoseStack, Integer, Integer>>> sections
    ) {
        this(x, y, width, height, Component.empty(), ringInnerRadius, ringOuterRadius, textScale, sections);
    }

    /**
     * Instantiates a new Wheel widget.
     *
     * @param x                 the x
     * @param y                 the y
     * @param width             the width
     * @param height            the height
     * @param ringInnerRadius   the ring inner radius
     * @param ringOuterRadius   the ring outer radius
     * @param textScale         the text scale
     * @param degreeOffsetAngle the degree offset angle
     * @param sections          the sections
     */
    public WheelWidget(
            int x, int y, int width, int height,
            float ringInnerRadius, float ringOuterRadius, float textScale, float degreeOffsetAngle,
            List<Pair<Component, FourConsumer<GuiGraphics, PoseStack, Integer, Integer>>> sections
    ) {
        this(x, y, width, height, Component.empty(), ringInnerRadius, ringOuterRadius, textScale, degreeOffsetAngle, sections);
    }

    /**
     * Instantiates a new Wheel widget.
     *
     * @param x               the x
     * @param y               the y
     * @param width           the width
     * @param height          the height
     * @param ringInnerRadius the ring inner radius
     * @param ringOuterRadius the ring outer radius
     * @param sections        the sections
     */
    public WheelWidget(
            int x, int y, int width, int height,
            float ringInnerRadius, float ringOuterRadius,
            List<Pair<Component, FourConsumer<GuiGraphics, PoseStack, Integer, Integer>>> sections
    ) {
        this(x, y, width, height, Component.empty(), ringInnerRadius, ringOuterRadius, sections);
    }

    /**
     * Instantiates a new Wheel widget.
     *
     * @param x                 the x
     * @param y                 the y
     * @param width             the width
     * @param height            the height
     * @param message           the message
     * @param ringInnerRadius   the ring inner radius
     * @param ringOuterRadius   the ring outer radius
     * @param textScale         the text scale
     * @param degreeOffsetAngle the degree offset angle
     * @param sections          the sections
     */
    public WheelWidget(
            int x, int y, int width, int height, Component message,
            float ringInnerRadius, float ringOuterRadius, float textScale, float degreeOffsetAngle,
            List<Pair<Component, FourConsumer<GuiGraphics, PoseStack, Integer, Integer>>> sections
    ) {
        this(
                x, y, width, height, message,
                ringInnerRadius, ringOuterRadius,
                150, 300, 150,
                0x00000000,
                0xddffff00, 20, 5f,
                0xfdfdfd, textScale, degreeOffsetAngle,
                sections
        );
    }

    /**
     * Instantiates a new Wheel widget.
     *
     * @param x               the x
     * @param y               the y
     * @param width           the width
     * @param height          the height
     * @param message         the message
     * @param ringInnerRadius the ring inner radius
     * @param ringOuterRadius the ring outer radius
     * @param sections        the sections
     */
    public WheelWidget(
            int x, int y, int width, int height, Component message,
            float ringInnerRadius, float ringOuterRadius,
            List<Pair<Component, FourConsumer<GuiGraphics, PoseStack, Integer, Integer>>> sections
    ) {
        this(
                x, y, width, height, message,
                ringInnerRadius, ringOuterRadius,
                150, 300, 150,
                0x00000000,
                0xddffff00, 20, 5f,
                0xfdfdfd, 1f, 0f,
                sections
        );
    }

    /**
     * Instantiates a new Wheel widget.
     *
     * @param x                 the x
     * @param y                 the y
     * @param width             the width
     * @param height            the height
     * @param message           the message
     * @param ringInnerRadius   the ring inner radius
     * @param ringOuterRadius   the ring outer radius
     * @param degreeOffsetAngle the degree offset angle
     * @param sections          the sections
     */
    public WheelWidget(
            int x, int y, int width, int height, Component message,
            float ringInnerRadius, float ringOuterRadius, float degreeOffsetAngle,
            List<Pair<Component, FourConsumer<GuiGraphics, PoseStack, Integer, Integer>>> sections
    ) {
        this(
                x, y, width, height, message,
                ringInnerRadius, ringOuterRadius,
                150, 300, 150,
                0x00000000,
                0xddffff00, 20, 5f,
                0xfdfdfd, 1f, degreeOffsetAngle,
                sections
        );
    }

    /**
     * Instantiates a new Wheel widget.
     *
     * @param x                             the x
     * @param y                             the y
     * @param width                         the width
     * @param height                        the height
     * @param ringInnerRadius               the ring inner radius
     * @param ringOuterRadius               the ring outer radius
     * @param delay                         the delay
     * @param animationMs                   the animation ms
     * @param closingAnimationMs            the closing animation ms
     * @param ringColor                     the ring color
     * @param selectionEffectColor          the selection effect color
     * @param selectionEffectRadius         the selection effect radius
     * @param selectionAnimationSpeedFactor the selection animation speed factor
     * @param textColor                     the text color
     * @param textScale                     the text scale
     * @param sections                      the sections
     */
    public WheelWidget(
            int x, int y, int width, int height,
            float ringInnerRadius, float ringOuterRadius,
            int delay, int animationMs, int closingAnimationMs,
            int ringColor,
            int selectionEffectColor, int selectionEffectRadius, float selectionAnimationSpeedFactor,
            int textColor, float textScale,
            List<Pair<Component, FourConsumer<GuiGraphics, PoseStack, Integer, Integer>>> sections
    ) {
        this(
                x, y, width, height, Component.empty(),
                ringInnerRadius, ringOuterRadius,
                delay, animationMs, closingAnimationMs,
                ringColor,
                selectionEffectColor, selectionEffectRadius, selectionAnimationSpeedFactor,
                textColor, textScale, 0f,
                sections
        );
    }

    /**
     * Instantiates a new Wheel widget.
     *
     * @param x                             the x
     * @param y                             the y
     * @param width                         the width
     * @param height                        the height
     * @param message                       the message
     * @param ringInnerRadius               the ring inner radius
     * @param ringOuterRadius               the ring outer radius
     * @param delay                         the delay
     * @param animationMs                   the animation ms
     * @param closingAnimationMs            the closing animation ms
     * @param ringColor                     the ring color
     * @param selectionEffectColor          the selection effect color
     * @param selectionEffectRadius         the selection effect radius
     * @param selectionAnimationSpeedFactor the selection animation speed factor
     * @param textColor                     the text color
     * @param textScale                     the text scale
     * @param degreeOffsetAngle             the degree offset angle
     * @param sections                      the sections
     */
    public WheelWidget(
            int x, int y, int width, int height, Component message,
            float ringInnerRadius, float ringOuterRadius,
            int delay, int animationMs, int closingAnimationMs,
            int ringColor,
            int selectionEffectColor, int selectionEffectRadius, float selectionAnimationSpeedFactor,
            int textColor, float textScale, float degreeOffsetAngle,
            List<Pair<Component, FourConsumer<GuiGraphics, PoseStack, Integer, Integer>>> sections
    ) {
        super(x, y, width, height, message);
        this.centerPos = new Vector2f(this.getX() + this.getWidth() / 2f, this.getY() + this.getHeight() / 2f);
        this.ringInnerRadius = Math.max(ringInnerRadius, IGNORE_CURSOR_MOVE_LENGTH);
        this.ringOuterRadius = ringOuterRadius;
        this.delay = delay;
        this.animationMs = animationMs;
        this.closingAnimationMs = closingAnimationMs;
        this.ringColor = ringColor;
        this.selectionEffectColor = selectionEffectColor;
        this.selectionEffectRadius = selectionEffectRadius;
        this.selectionAnimationSpeedFactor = selectionAnimationSpeedFactor;
        this.textColor = textColor;
        this.textScale = textScale;
        float degreeEachRotation = 360f / sections.size();
        for (int i = 0; i < sections.size(); i++) {
            Pair<Component, FourConsumer<GuiGraphics, PoseStack, Integer, Integer>> section = sections.get(i);
            float rotation = MathUtil.clampWithProportion((degreeEachRotation * i + degreeOffsetAngle) % 360, 0, 360);
            Vector2f rotated = MathUtil.rotationDegrees(ROTATION_START, rotation)
                    .mul(1, -1)
                    .mul(this.getSectionCircleDiameter())
                    .add(this.centerPos);
            float detectionStart = (float) (Math.toRadians(rotation - degreeEachRotation / 2f) + Math.PI * 2);
            float detectionEnd = (float) (Math.toRadians(rotation + degreeEachRotation / 2f) + Math.PI * 2);
            detectionStart = detectionStart % (float) (Math.PI * 2);
            detectionEnd = detectionEnd % (float) (Math.PI * 2);
            this.sections.add(new WheelSection(
                    rotated,
                    (float) (Math.toRadians(rotation) % (Math.PI * 2)),
                    detectionStart,
                    detectionEnd,
                    section.first,
                    section.second
            ));
        }
        this.selectionEffectPos = MathUtil.rotate(
                MathUtil.copy(ROTATION_START)
                        .mul(this.getSectionCircleDiameter()),
                this.currentAngle
        );
    }

    /**
     * Gets section circle diameter.
     *
     * @return the section circle diameter
     */
// 滚轮选择器中每个扇形的圆形直径
    public float getSectionCircleDiameter() {
        return this.ringOuterRadius + this.ringInnerRadius;
    }

    /**
     * Sets current index.
     *
     * @param index the index
     * @return the current index
     */
    public WheelWidget setCurrentIndex(int index) {
        this.currentSectionIndex = index;
        this.currentAngle = this.sections.get(index).angle;
        this.selectionEffectPos = MathUtil.rotate(
                MathUtil.copy(ROTATION_START)
                        .mul(this.getSectionCircleDiameter()),
                this.currentAngle
        );
        return this;
    }

    /**
     * Gets section size.
     *
     * @return the section size
     */
    public int getSectionSize() {
        return this.sections.size();
    }


    @Override
    public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
        if (delta > 0) {
            if (this.currentSectionIndex == this.getSectionSize() - 1) {
                this.currentSectionIndex = 0;
            } else {
                this.currentSectionIndex++;
            }
        } else if (delta < 0) {
            if (this.currentSectionIndex == 0) {
                this.currentSectionIndex = this.getSectionSize() - 1;
            } else {
                this.currentSectionIndex--;
            }
        }
        for (WheelSection section : this.sections) {
            if (this.sections.indexOf(section) == this.currentSectionIndex) {
                this.currentAngle = section.angle;
                return true;
            }
        }
        return true;
    }

    /**
     * Check mouse pos.
     *
     * @param mouseX the mouse x
     * @param mouseY the mouse y
     */
    public void checkMousePos(double mouseX, double mouseY) {
        if (this.closingAnimationStarted) return;
        float centerX = this.centerPos.x;
        float centerY = this.centerPos.y;
        // 鼠标距离屏幕中心的位置向量
        Vector2f cursorPos = new Vector2f((float) mouseX - centerX, (float) mouseY - centerY);

        if (cursorPos.length() < IGNORE_CURSOR_MOVE_LENGTH) return;

        Vector2f rotationStart = new Vector2f(0, 1);
        cursorPos.normalize();
        // 计算夹角弧度
        double rot = Math.acos(rotationStart.dot(cursorPos) / (rotationStart.length() * cursorPos.length()));
        double rotation = cursorPos.x < 0 ? Math.PI - rot : Math.PI + rot;
        for (WheelSection section : this.sections) {
            if (section.angleStart > section.angleEnd && rotation >= section.angleStart
                    || rotation >= section.angleStart && rotation <= section.angleEnd
            ) {
                this.currentAngle = section.angle;
                this.currentSectionIndex = this.sections.indexOf(section);
                break;
            }
        }
    }

    /**
     * Should render boolean.
     *
     * @return the boolean
     */
    public boolean shouldRender() {
        if (this.animationStarted) return true;
        return (this.displayTime + this.delay) <= System.currentTimeMillis();
    }

    @Override
    public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
        this.checkMousePos(mouseX, mouseY);
        this.renderWidget(guiGraphics, mouseX, mouseY, partialTick);
    }

    @Override
    protected void renderWidget(GuiGraphics guiGraphics, int i, int i1, float v) {
        RenderSystem.enableDepthTest();
        RenderSystem.enableBlend();
        this.renderClosingAnimation(guiGraphics);
        if (!this.shouldRender()) {
            return;
        }
        if (this.closingAnimationStarted) return;
        if (!this.animationStarted) {
            this.animationStarted = true;
            this.displayTime = System.currentTimeMillis();
        }
        PoseStack poseStack = guiGraphics.pose();
        float delta = this.displayTime + this.animationMs - System.currentTimeMillis();
        if (delta > 0) {
            float progress = 1 - (delta / this.animationMs);
            progress = (float) (-Math.pow(progress, 2) + 2 * progress);
            if (progress == 0) return;
            this.renderProgressAnimation(guiGraphics, progress);
            return;
        }
        renderRing(
                guiGraphics,
                this.centerPos.x,
                this.centerPos.y,
                this.ringColor,
                this.ringInnerRadius * 2,
                this.ringOuterRadius * 2
        );
        this.renderSelection(guiGraphics);
        for (WheelSection value : this.sections) {
            float x = value.center.x;
            float y = value.center.y;
            poseStack.pushPose();
            poseStack.translate(x - 10, y - 10, 100);
            value.renderer.accept(guiGraphics, poseStack, 20, 20);
            poseStack.popPose();
            poseStack.pushPose();
            float coordinateScale = 0.7f;
            float offsetX = 0.1f * this.width;
            float offsetY = 0.1f * this.height;
            float adjustedX = (x - offsetX) / coordinateScale;
            float adjustedY = (y - offsetY - 20 * this.textScale) / coordinateScale;

            poseStack.translate(offsetX, offsetY, 0);
            poseStack.scale(coordinateScale, coordinateScale, coordinateScale);
            poseStack.translate(adjustedX, adjustedY, 0);
            poseStack.scale(this.textScale / coordinateScale, this.textScale / coordinateScale, this.textScale / coordinateScale);
            guiGraphics.drawCenteredString(
                    minecraft.font,
                    value.subTitle,
                    0,
                    0,
                    (0xff << 24) | this.textColor
            );
            poseStack.popPose();
        }
        RenderSystem.disableDepthTest();
        RenderSystem.disableBlend();
    }

    /**
     * Render closing animation.
     *
     * @param guiGraphics the gui graphics
     */
    public void renderClosingAnimation(GuiGraphics guiGraphics) {
        if (!this.closingAnimationStarted) return;
        float delta = this.displayTime + this.closingAnimationMs - System.currentTimeMillis();
        float progress = delta / this.closingAnimationMs;
        if(progress >= 1 || progress <= 0) {
            this.minecraft.setScreen(null);
        }
        this.renderProgressAnimation(guiGraphics, progress);
    }
    private void renderProgressAnimation(GuiGraphics guiGraphics, float progress) {
        progress =  (float) (-Math.pow(progress, 2) + 2 * progress);
        if (progress == 0) return;
        PoseStack poseStack = guiGraphics.pose();
        poseStack.pushPose();
        renderRing(
                guiGraphics,
                this.centerPos.x,
                this.centerPos.y,
                this.ringColor,
                this.ringInnerRadius * 2 * progress,
                this.ringOuterRadius * 2 * progress
        );
        poseStack.popPose();
        if(this.currentSectionIndex != -1) {
            WheelSection section = this.sections.get(this.currentSectionIndex);
            Vector2f center = new Vector2f(
                    (section.center.x - this.centerPos.x) / this.getSectionCircleDiameter(),
                    (section.center.y - this.centerPos.y) / this.getSectionCircleDiameter()
            ).mul(this.getSectionCircleDiameter() * progress).add(this.centerPos.x, this.centerPos.y);
            renderSelectionEffect(
                    guiGraphics,
                    center.x,
                    center.y,
                    this.selectionEffectColor,
                    this.selectionEffectRadius
            );
        }
        for (WheelSection value : this.sections) {
            if (sections.get(0) != value) continue;
            Vector2f center = new Vector2f(
                    (value.center.x - this.centerPos.x) / this.getSectionCircleDiameter(),
                    (value.center.y - this.centerPos.y) / this.getSectionCircleDiameter()
            ).mul(this.getSectionCircleDiameter() * progress).add(this.centerPos.x, this.centerPos.y);
            float x = center.x;
            float y = center.y;
            poseStack.pushPose();
            poseStack.translate(x - 10, y - 10, 100);
            value.renderer.accept(guiGraphics, poseStack, 20, 20);
            poseStack.pushPose();
        }
    }

    /**
     * Render ring.
     *
     * @param guiGraphics the gui graphics
     * @param centerX     the center x
     * @param centerY     the center y
     * @param color       the color
     * @param innerRadius the inner radius
     * @param outerRadius the outer radius
     */
    public static void renderRing(
            GuiGraphics guiGraphics,
            float centerX,
            float centerY,
            int color,
            float innerRadius,  // 改为半径
            float outerRadius   // 改为半径
    ) {
        PoseStack poseStack = guiGraphics.pose();
        poseStack.pushPose();

        Tesselator tesselator = Tesselator.getInstance();
        BufferBuilder buffer = tesselator.getBuilder();

        // 计算足够大的绘制区域来覆盖整个环形（基于外半径）
        float margin = outerRadius + 100f; // 使用半径计算边距
        float x1 = centerX - margin;
        float y1 = centerY - margin;
        float x2 = centerX + margin;
        float y2 = centerY + margin;

        buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);

        Matrix4f matrix = poseStack.last().pose();
        buffer.vertex(matrix, x1, y1, -300).color(color).endVertex();
        buffer.vertex(matrix, x1, y2, -300).color(color).endVertex();
        buffer.vertex(matrix, x2, y2, -300).color(color).endVertex();
        buffer.vertex(matrix, x2, y1, -300).color(color).endVertex();

        setupRingShader(centerX, centerY, innerRadius, outerRadius);

        BufferUploader.drawWithShader(buffer.end());
        poseStack.popPose();
    }

    private static void setupRingShader(float centerX, float centerY, float innerRadius, float outerRadius) {
        Window window = Minecraft.getInstance().getWindow();
        float guiScale = (float) window.getGuiScale();

        RenderSystem.setShader(Lib39Shaders::getRingShader);

        // 转换到像素坐标（考虑GUI缩放）
        float pixelCenterX = centerX * guiScale;
        float pixelCenterY = window.getHeight() - (centerY * guiScale); // 翻转Y坐标

        // 半径考虑GUI缩放
        float pixelInnerRadius = innerRadius * guiScale;
        float pixelOuterRadius = outerRadius * guiScale;
        float pixelAntiAliasing = 2.0f * guiScale; // 抗锯齿范围

        System.out.println("Shader Params - Center: (" + pixelCenterX + ", " + pixelCenterY +
                "), InnerRadius: " + pixelInnerRadius + ", OuterRadius: " + pixelOuterRadius);

        ShaderInstance shader = Lib39Shaders.getRingShader();
        shader.safeGetUniform("Center").set(pixelCenterX, pixelCenterY);
        shader.safeGetUniform("InnerRadius").set(pixelInnerRadius);
        shader.safeGetUniform("OuterRadius").set(pixelOuterRadius);
        shader.safeGetUniform("AntiAliasing").set(pixelAntiAliasing);
        shader.safeGetUniform("ColorModulator").set(1.0f, 1.0f, 1.0f, .5f);
    }

    private void renderSelection(GuiGraphics guiGraphics) {
        float selectionEffectAngle = MathUtil.angle(
                MathUtil.copy(ROTATION_START),
                this.selectionEffectPos
        );

        float diffAngle = this.currentAngle - selectionEffectAngle;

        if (diffAngle > Math.PI) {
            diffAngle -= (float) (Math.PI * 2);
        } else if (diffAngle < -Math.PI) {
            diffAngle += (float) (Math.PI * 2);
        }

        this.selectionEffectPos = MathUtil.rotate(
                this.selectionEffectPos,
                diffAngle / this.selectionAnimationSpeedFactor
        );

        Vector2f pos = MathUtil.copy(this.selectionEffectPos)
                .mul(1, -1)
                .add(this.centerPos);

        // 调用时使用半径
        renderSelectionEffect(
                guiGraphics,
                pos.x,
                pos.y,
                SELECTION_EFFECT_COLOR,
                SELECTION_EFFECT_RADIUS  // 确保这是半径值
        );
    }

    /**
     * Render selection effect.
     *
     * @param guiGraphics the gui graphics
     * @param centerX     the center x
     * @param centerY     the center y
     * @param color       the color
     * @param radius      the radius
     */
    public static void renderSelectionEffect(
            GuiGraphics guiGraphics,
            float centerX,
            float centerY,
            int color,
            float radius
    ) {
        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();
        RenderSystem.disableDepthTest();
        PoseStack poseStack = guiGraphics.pose();
        Matrix4f matrix4f = poseStack.last().pose();
        Tesselator tesselator = Tesselator.getInstance();
        BufferBuilder buffer = tesselator.getBuilder();
        buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);

        float x1 = centerX - radius - 5;
        float y1 = centerY - radius - 5;
        float x2 = centerX + radius + 5;
        float y2 = centerY + radius + 5;
        buffer.vertex(matrix4f, x1, y1, -200).color(color).endVertex();
        buffer.vertex(matrix4f, x1, y2, -200).color(color).endVertex();
        buffer.vertex(matrix4f, x2, y2, -200).color(color).endVertex();
        buffer.vertex(matrix4f, x2, y1, -200).color(color).endVertex();

        Window window = Minecraft.getInstance().getWindow();
        float guiScale =  (float) window.getGuiScale();
        RenderSystem.setShader(Lib39Shaders::getSelectionShader);
        System.out.println("Selection Effect Params:");
        System.out.println("  Center: " + centerX + ", " + centerY);
        System.out.println("  Radius: " + radius);
        System.out.println("  GUI Scale: " + guiScale);
        System.out.println("  Framebuffer: " + window.getWidth() + "x" + window.getHeight());
        Lib39Shaders.getSelectionShader()
                .safeGetUniform("Center")
                .set(centerX * guiScale, centerY * guiScale);
        Lib39Shaders.getSelectionShader()
                .safeGetUniform("FramebufferSize")
                .set((float) window.getWidth(), (float) window.getHeight());
        Lib39Shaders.getSelectionShader()
                .safeGetUniform("Radius")
                .set(radius * guiScale);
        Lib39Shaders.getSelectionShader()
                .safeGetUniform("AntiAliasingRadius")
                .set(guiScale); // 根据需要调整
        RenderSystem.setShaderColor(1, 1, 1, 1);
        BufferUploader.drawWithShader(Objects.requireNonNull(buffer.end()));
        RenderSystem.enableDepthTest();
    }

    /**
     * On closing.
     */
    public void onClosing() {
        if (this.shouldRender() && !this.closingAnimationStarted) {
            this.displayTime = System.currentTimeMillis();
            this.closingAnimationStarted = true;
        } else {
            this.minecraft.setScreen(null);
        }
    }

    @Override
    protected void updateWidgetNarration(NarrationElementOutput narrationElementOutput) {
    }

    /**
     * The type Wheel section.
     */
    public record WheelSection(
            Vector2f center,
            float angle,
            float angleStart,
            float angleEnd,
            Component subTitle,
            FourConsumer<GuiGraphics, PoseStack, Integer, Integer> renderer
    ) {
    }
}
