/*
 *  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.gui.overlays;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraftforge.client.gui.overlay.ForgeGui;
import net.minecraftforge.client.gui.overlay.IGuiOverlay;
import org.jetbrains.annotations.Nullable;
import top.r3944realms.eroticdungeongame.config.EDGConfig;
import top.r3944realms.eroticdungeongame.content.block.blockentity.BaseSeatBlockEntity;
import top.r3944realms.eroticdungeongame.content.util.FurnitureHelper;

public enum DeviceInfoOverlay implements IGuiOverlay {
    INSTANCE;

    private float alpha = 0f;
    private long lastUpdateTime = System.currentTimeMillis();  // 修复1：初始化为当前时间
    private boolean isShowing = false;
    private boolean lastShouldShow = false;  // 新增：记录上一帧的状态
    private int stableCounter = 0;  // 新增：稳定计数器，防止抖动
    private static final int STABLE_THRESHOLD = 3;  // 需要连续稳定3帧才切换

    private static final Minecraft mc = Minecraft.getInstance();

    private float easeInOutCubic(float t) {
        return t < 0.5f ? 4 * t * t * t : 1 - (float) Math.pow(-2 * t + 2, 3) / 2;
    }

    public static boolean shouldNotShowOverlay() {
        return mc.level == null || mc.player == null || mc.player.isSpectator() || !EDGConfig.COMMON.SHOW_LOCK_OVERLAY.get();
    }

    @Override
    public void render(ForgeGui gui, GuiGraphics guiGraphics, float partialTick, int screenWidth, int screenHeight) {
        if (shouldNotShowOverlay()) {
            // 确保离开时完全淡出
            if (isShowing) {
                isShowing = false;
                stableCounter = 0;
            }
            updateAlpha();
            if (alpha > 0.01f) {
                renderLockText(guiGraphics, screenWidth, screenHeight, easeInOutCubic(alpha));
            }
            return;
        }

        // 检测当前是否应该显示
        boolean currentShouldShow = checkShouldShow();

        // 防抖处理：只有连续多帧状态一致才切换
        if (currentShouldShow == lastShouldShow) {
            stableCounter = Math.min(stableCounter + 1, STABLE_THRESHOLD + 1);
        } else {
            stableCounter = 0;
        }

        lastShouldShow = currentShouldShow;

        // 只有稳定后才切换显示状态
        boolean targetShowing = stableCounter >= STABLE_THRESHOLD && currentShouldShow;

        if (targetShowing != isShowing) {
            isShowing = targetShowing;
        }

        // 更新透明度
        updateAlpha();

        // 渲染
        if (alpha > 0.01f) {
            renderLockText(guiGraphics, screenWidth, screenHeight, easeInOutCubic(alpha));
        }
    }

    private boolean checkShouldShow() {
        if (shouldNotShowOverlay()) return false;

        BlockPos lookingAtBlock = getLookingAtBlock();
        if (lookingAtBlock == null) return false;

        assert mc.level != null;
        BaseSeatBlockEntity seatBlockEntity = FurnitureHelper.getSeatBlockEntity(mc.level, lookingAtBlock);
        return seatBlockEntity != null && seatBlockEntity.hasLockCode();
    }

    private void updateAlpha() {
        long currentTime = System.currentTimeMillis();
        float deltaTime = (currentTime - lastUpdateTime) / 1000f;

        // 限制最大delta，避免跳跃太大
        deltaTime = Math.min(0.05f, deltaTime);
        lastUpdateTime = currentTime;

        float fadeDuration = 0.2f;  // 缩短淡入淡出时间，响应更快
        float targetAlpha = isShowing ? 1f : 0f;

        if (Math.abs(alpha - targetAlpha) < 0.005f) {
            alpha = targetAlpha;
        } else {
            float step = deltaTime / fadeDuration;
            if (isShowing) {
                alpha = Math.min(1f, alpha + step);
            } else {
                alpha = Math.max(0f, alpha - step);
            }
        }
    }

    private void renderLockText(GuiGraphics guiGraphics, int screenWidth, int screenHeight, float alpha) {
        String message = Component.translatable("eroticdungeongame.overlay.info.device.locked").getString();

        Player player = mc.player;
        BlockPos lookingAtBlock = getLookingAtBlock();
        if (player != null && lookingAtBlock != null) {
            assert mc.level != null;
            BaseSeatBlockEntity seatBlockEntity = FurnitureHelper.getSeatBlockEntity(mc.level, lookingAtBlock);
            if (seatBlockEntity != null) {
                double distance = Math.sqrt(player.distanceToSqr(seatBlockEntity.getBlockPos().getCenter()));
                double maxDistance = 5.0;
                double minDistance = 2.0;

                float scale;
                if (distance >= maxDistance) {
                    scale = 0.8f;
                } else if (distance <= minDistance) {
                    scale = 1.5f;
                } else {
                    double t = (distance - minDistance) / (maxDistance - minDistance);
                    scale = (float) (1.5 - t * 0.7);
                }

                // 颜色随距离变化，更直观
                int color = (int)(alpha * 255) << 24;
                if (distance > 4.0) {
                    color |= 0xFF6666;  // 远距离淡红色
                } else if (distance > 3.0) {
                    color |= 0xFF8888;
                } else {
                    color |= 0xFF5555;  // 近距离鲜红色
                }

                int textWidth = mc.font.width(message);
                int scaledTextWidth = (int)(textWidth * scale);
                int x = (screenWidth - scaledTextWidth) / 2;
                int y = screenHeight - 80;

                guiGraphics.pose().pushPose();
                guiGraphics.pose().translate(x, y, 0);
                guiGraphics.pose().scale(scale, scale, scale);
                guiGraphics.drawString(mc.font, message, 0, 0, color, false);  // 添加阴影更清晰
                guiGraphics.pose().popPose();
            }
        }
    }

    private @Nullable BlockPos getLookingAtBlock() {
        if (mc.player == null) return null;

        HitResult hit = mc.player.pick(5.0D, 1.0F, false);

        if (hit.getType() == HitResult.Type.BLOCK) {
            return ((BlockHitResult) hit).getBlockPos();
        }
        return null;
    }
}