package com.tiedup.remake.network.conversation;

import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.IDialogueSpeaker;
import com.tiedup.remake.dialogue.conversation.ConversationManager;
import com.tiedup.remake.dialogue.conversation.ConversationTopic;
import com.tiedup.remake.entities.EntityDamsel;
import com.tiedup.remake.network.PacketRateLimiter;
import java.util.function.Supplier;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraftforge.network.NetworkEvent;

/**
 * Packet sent from client to server when player selects a conversation topic.
 *
 */
public class PacketSelectTopic {

    /** Maximum distance for conversation */
    private static final double MAX_DISTANCE = 5.0;

    private final int entityId;
    private final String topicName;

    public PacketSelectTopic(int entityId, ConversationTopic topic) {
        this.entityId = entityId;
        this.topicName = topic.name();
    }

    private PacketSelectTopic(int entityId, String topicName) {
        this.entityId = entityId;
        this.topicName = topicName;
    }

    public void encode(FriendlyByteBuf buf) {
        buf.writeInt(entityId);
        buf.writeUtf(topicName, 64);
    }

    public static PacketSelectTopic decode(FriendlyByteBuf buf) {
        int entityId = buf.readInt();
        String topicName = buf.readUtf(64);
        return new PacketSelectTopic(entityId, topicName);
    }

    public void handle(Supplier<NetworkEvent.Context> ctx) {
        ctx
            .get()
            .enqueueWork(() -> {
                ServerPlayer sender = ctx.get().getSender();
                if (sender == null) return;

                handleServer(sender);
            });
        ctx.get().setPacketHandled(true);
    }

    private void handleServer(ServerPlayer sender) {
        if (!PacketRateLimiter.allowPacket(sender, "action")) return;

        // Find the target entity
        Entity entity = sender.level().getEntity(entityId);
        if (entity == null) {
            TiedUpMod.LOGGER.warn(
                "[PacketSelectTopic] Entity {} not found",
                entityId
            );
            return;
        }

        // Check if entity is a dialogue speaker
        if (!(entity instanceof IDialogueSpeaker speaker)) {
            TiedUpMod.LOGGER.warn(
                "[PacketSelectTopic] Entity {} is not a dialogue speaker",
                entityId
            );
            return;
        }

        // Validate distance
        double distance = sender.distanceTo(entity);
        if (distance > MAX_DISTANCE) {
            TiedUpMod.LOGGER.warn(
                "[PacketSelectTopic] Player {} too far from entity {} ({})",
                sender.getName().getString(),
                entityId,
                distance
            );
            return;
        }

        // Parse topic
        ConversationTopic topic;
        try {
            topic = ConversationTopic.valueOf(topicName);
        } catch (IllegalArgumentException e) {
            TiedUpMod.LOGGER.warn(
                "[PacketSelectTopic] Unknown topic: {}",
                topicName
            );
            return;
        }

        TiedUpMod.LOGGER.info(
            "[PacketSelectTopic] {} selected topic {} for {}",
            sender.getName().getString(),
            topic.name(),
            speaker.getDialogueName()
        );

        // Handle the topic selection - this sends the response dialogue
        ConversationManager.handleTopicSelection(speaker, sender, topic);
    }

    public int getEntityId() {
        return entityId;
    }

    public String getTopicName() {
        return topicName;
    }
}
