/*
 *  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;

import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.multiplayer.PlayerInfo;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.*;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.eroticdungeongame.EroticDungeon;
import top.r3944realms.eroticdungeongame.content.entity.npc.INPCPlayer;
import top.r3944realms.eroticdungeongame.util.IEDGClientPacketListener;
import top.r3944realms.superleadrope.util.riding.RidingFinder;

import java.util.*;

@SuppressWarnings("ConstantValue")
public class ClientNPCManager {

    // 缓存待处理的 NPC 玩家包
    private static final Set<ClientboundAddPlayerPacket> pendingNPCs = new HashSet<>();

    // 缓存待处理的实体包（坐骑、宠物等）
//    private static final Set<ClientboundAddEntityPacket> pendingEntities = new HashSet<>();

    // 缓存待处理的实体数据包
    private static final Set<ClientboundSetEntityDataPacket> pendingEntityData = new HashSet<>();

    // 缓存待处理的属性包
    private static final Set<ClientboundUpdateAttributesPacket> pendingAttributes = new HashSet<>();

    // 缓存待处理的装备包
    private static final Set<ClientboundSetEquipmentPacket> pendingEquipment = new HashSet<>();

    // 缓存待处理的乘客包
    private static final Set<ClientboundSetPassengersPacket> pendingPassengers = new HashSet<>();

    // 缓存待处理的链接包（拴绳）
    private static final Set<ClientboundSetEntityLinkPacket> pendingLinks = new HashSet<>();

    // 缓存待处理的头部旋转包
    private static final Set<ClientboundRotateHeadPacket> pendingHeadRotations = new HashSet<>();

    // 缓存待处理的移动包
    private static final Set<Packet<?>> pendingMovements = new HashSet<>();

    // 缓存待处理的运动包
    private static final Set<ClientboundSetEntityMotionPacket> pendingMotions = new HashSet<>();

    public static void reset() {
        pendingNPCs.clear();
//        pendingEntities.clear();
        pendingEntityData.clear();
        pendingAttributes.clear();
        pendingEquipment.clear();
        pendingPassengers.clear();
        pendingLinks.clear();
        pendingHeadRotations.clear();
        pendingMovements.clear();
        pendingMotions.clear();
        EroticDungeon.LOGGER.debug("ClientNPCManager reset");
    }

    // ========== 缓存方法 ==========

    /**
     * 缓存 NPC 玩家包
     */
    public static void cacheNPCIfNeeded(ClientboundAddPlayerPacket packet) {
        ClientPacketListener connection = Minecraft.getInstance().getConnection();
        if (connection instanceof IEDGClientPacketListener iedgListener) {
            UUID playerId = packet.getPlayerId();
            PlayerInfo info = iedgListener.getNPCPlayerInfoMap().get(playerId);
            if (info == null && !iedgListener.getNPCPlayerInfoMap().containsKey(playerId)) {
                pendingNPCs.add(packet);
                EroticDungeon.LOGGER.debug("Cached AddPlayer packet for NPC: {} (entityId: {})",
                        playerId, packet.getEntityId());
            }
        }
    }

//    /**
//     * 缓存实体包
//     */
//    public static void cacheEntityIfNeeded(@NotNull ClientboundAddEntityPacket packet) {
//        pendingEntities.add(packet);
//        EroticDungeon.LOGGER.debug("Cached AddEntity packet {}", packet);
//    }

    /**
     * 缓存实体数据包
     */
    public static void cacheEntityDataIfNeeded(@NotNull ClientboundSetEntityDataPacket packet) {
         pendingEntityData.add(packet);
         EroticDungeon.LOGGER.debug("Cached SetEntityData packet {}, ID: {}", packet, packet.id());
    }

    /**
     * 缓存属性包
     */
    public static void cacheAttributesIfNeeded(@NotNull ClientboundUpdateAttributesPacket packet) {
        pendingAttributes.add(packet);
        EroticDungeon.LOGGER.debug("Cached UpdateAttributes packet {}, ID: {}", packet, packet.getEntityId());
    }

    /**
     * 缓存装备包
     */
    public static void cacheEquipmentIfNeeded(@NotNull ClientboundSetEquipmentPacket packet) {
        pendingEquipment.add(packet);
        EroticDungeon.LOGGER.debug("Cached SetEquipment packet{}, ID: {}", packet, packet.getEntity());
    }

    /**
     * 缓存乘客包
     */
    public static void cachePassengersIfNeeded(@NotNull ClientboundSetPassengersPacket packet) {
        pendingPassengers.add(packet);
        EroticDungeon.LOGGER.debug("Cached SetPassengers packet {}, (as vehicle) ID: {}", packet, packet.getVehicle());
    }

    /**
     * 缓存链接包（拴绳）
     */
    public static void cacheLinkIfNeeded(@NotNull ClientboundSetEntityLinkPacket packet) {
        pendingLinks.add(packet);
        EroticDungeon.LOGGER.debug("Cached SetEntityLink packet {}, (as source) ID: {}", packet, packet.getSourceId());
    }

    /**
     * 缓存头部旋转包
     */
    public static void cacheHeadRotationIfNeeded(ClientboundRotateHeadPacket packet) {
        pendingHeadRotations.add(packet);
        EroticDungeon.LOGGER.debug("Cached RotateHead packet {}", packet);
    }

    /**
     * 缓存移动包
     */
    public static void cacheMoveEntityIfNeeded(ClientboundMoveEntityPacket packet) {
        pendingMovements.add(packet);
        EroticDungeon.LOGGER.debug("Cached MoveEntity packet {}", packet);
    }

    /**
     * 缓存传送包
     */
    public static void cacheTeleportEntityIfNeeded(ClientboundTeleportEntityPacket packet) {
        EroticDungeon.LOGGER.debug("Cached TeleportEntity packet {}", packet);
        pendingMovements.add(packet);
    }

    /**
     * 缓存运动包
     */
    public static void cacheMotionIfNeeded(ClientboundSetEntityMotionPacket packet) {
        pendingMotions.add(packet);
        EroticDungeon.LOGGER.debug("Cached SetEntityMotion packet {}, ID: {}", packet, packet.getId());
    }

    // ========== 处理方法 ==========

    /**
     * 处理缓存的 NPC 包（当 NPCInfo 到达时调用）
     */
    public static void processPendingNPCs(@NotNull PlayerInfo npcInfo) {
        UUID uuid = npcInfo.getProfile().getId();
        ClientPacketListener connection = Minecraft.getInstance().getConnection();

        if (!(connection instanceof IEDGClientPacketListener iedgListener)) {
            return;
        }

        // 处理缓存的 AddPlayer 包
        Iterator<ClientboundAddPlayerPacket> playerIterator = pendingNPCs.iterator();
        while (playerIterator.hasNext()) {
            ClientboundAddPlayerPacket packet = playerIterator.next();
            if (packet.getPlayerId().equals(uuid)) {
                PlayerInfo npcPlayerInfo = iedgListener.getNPCPlayerInfo(uuid);
                if (npcPlayerInfo != null) {
                    // 创建 NPC 玩家实体
                    iedgListener.edg$createNPCPlayer(packet, npcPlayerInfo);
                    playerIterator.remove();
                    EroticDungeon.LOGGER.debug("Processed AddPlayer packet for NPC: {}", uuid);

                    // 处理所有缓存的包
                    processAllCachedPackets(iedgListener);
                    break;
                } else {
                    EroticDungeon.LOGGER.warn("NPC Player {} not found", uuid);
                }
            }
        }
    }

    /**
     * 处理所有缓存的包
     */
    private static void processAllCachedPackets(IEDGClientPacketListener iedgListener) {
        Level level = Minecraft.getInstance().level;
        if (level == null) return;

//        // 处理实体包
//        Iterator<ClientboundAddEntityPacket> entityIterator = pendingEntities.iterator();
//        while (entityIterator.hasNext()) {
//            ClientboundAddEntityPacket packet = entityIterator.next();
//            Entity entity = level.getEntity(packet.getId());
//            if (entity != null) {
//                iedgListener.edg$createEntity(packet);
//                entityIterator.remove();
//                EroticDungeon.LOGGER.debug("Processed AddEntity packet: {}", entity.getUUID());
//            }
//
//        }

        // 处理实体数据包
        Iterator<ClientboundSetEntityDataPacket> dataIterator = pendingEntityData.iterator();
        while (dataIterator.hasNext()) {
            ClientboundSetEntityDataPacket packet = dataIterator.next();
            Entity entity = level.getEntity(packet.id());
            if (entity != null) {
                iedgListener.edg$setEntityData(packet);
                dataIterator.remove();
                EroticDungeon.LOGGER.debug("Processed SetEntityData packet: {}", entity.getUUID());
            }
        }

        // 处理属性包
        Iterator<ClientboundUpdateAttributesPacket> attrIterator = pendingAttributes.iterator();
        while (attrIterator.hasNext()) {
            ClientboundUpdateAttributesPacket packet = attrIterator.next();
            Entity entity = level.getEntity(packet.getEntityId());
            if (entity != null) {
                iedgListener.edg$updateAttributes(packet);
                attrIterator.remove();
                EroticDungeon.LOGGER.debug("Processed UpdateAttributes packet: {}", entity.getUUID());
            }
        }

        // 处理装备包
        Iterator<ClientboundSetEquipmentPacket> equipIterator = pendingEquipment.iterator();
        while (equipIterator.hasNext()) {
            ClientboundSetEquipmentPacket packet = equipIterator.next();
            Entity entity = level.getEntity(packet.getEntity());
            if (entity != null) {
                iedgListener.edg$setEquipment(packet);
                equipIterator.remove();
                EroticDungeon.LOGGER.debug("Processed SetEquipment packet for: {}", entity.getUUID());
            }
        }

        // 处理乘客包
        Iterator<ClientboundSetPassengersPacket> passengerIterator = pendingPassengers.iterator();
        while (passengerIterator.hasNext()) {
            ClientboundSetPassengersPacket packet = passengerIterator.next();
            Entity vehicle = level.getEntity(packet.getVehicle());
            if (vehicle != null) {
                boolean flag = true;
                for (int passengerId : packet.getPassengers()) {
                    Entity passenger = level.getEntity(passengerId);
                    if (passenger == null) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    iedgListener.edg$setPassengers(packet);
                    passengerIterator.remove();
                    EroticDungeon.LOGGER.debug("Processed SetPassengers packet: {}", vehicle.getUUID());
                }
            }
        }

        // 处理链接包
        Iterator<ClientboundSetEntityLinkPacket> linkIterator = pendingLinks.iterator();
        while (linkIterator.hasNext()) {
            ClientboundSetEntityLinkPacket packet = linkIterator.next();
            Entity source = level.getEntity(packet.getSourceId());
            Entity dest = level.getEntity(packet.getDestId());
            if (source != null && dest != null) {
                iedgListener.edg$setEntityLink(packet);
                linkIterator.remove();
                EroticDungeon.LOGGER.debug("Processed SetEntityLink packet: {}", source.getUUID());
            }
        }

        // 处理头部旋转包
        Iterator<ClientboundRotateHeadPacket> headIterator = pendingHeadRotations.iterator();
        while (headIterator.hasNext()) {
            ClientboundRotateHeadPacket packet = headIterator.next();
            Entity entity = packet.getEntity(level);
            if (entity != null){
                iedgListener.edg$rotateHead(packet);
                headIterator.remove();
            }
            EroticDungeon.LOGGER.debug("Processed RotateHead packet for NPC: {}", entity.getUUID());
        }

        // 处理移动包
        Iterator<Packet<?>> moveIterator = pendingMovements.iterator();
        while (moveIterator.hasNext()) {
            Packet<?> packet = moveIterator.next();
            Entity entity = null;

            if (packet instanceof ClientboundMoveEntityPacket movePacket) {
                entity = movePacket.getEntity(level);
            } else if (packet instanceof ClientboundTeleportEntityPacket teleportPacket) {
                entity = level.getEntity(teleportPacket.getId());
            }

            if (entity != null) {
                if (packet instanceof ClientboundMoveEntityPacket movePacket) {
                    iedgListener.edg$moveEntity(movePacket);
                } else if (packet instanceof ClientboundTeleportEntityPacket teleportPacket) {
                    iedgListener.edg$teleportEntity(teleportPacket);
                }

                moveIterator.remove();
                EroticDungeon.LOGGER.debug("Processed movement packet for NPC: {}", entity.getUUID());
            }
        }

        // 处理运动包
        Iterator<ClientboundSetEntityMotionPacket> motionIterator = pendingMotions.iterator();
        while (motionIterator.hasNext()) {
            ClientboundSetEntityMotionPacket packet = motionIterator.next();
            Entity entity = level.getEntity(packet.getId());
            if (entity != null) {
                iedgListener.edg$setEntityMotion(packet);
                motionIterator.remove();
                EroticDungeon.LOGGER.debug("Processed SetEntityMotion packet for NPC: {}", entity.getUUID());
            }
        }
    }
}