package com.tiedup.remake.network.trader;

import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.network.base.AbstractClientPacket;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

/**
 * Packet to open the SlaveTrader trading screen on the client.
 *
 * Server -> Client
 */
public class PacketOpenTraderScreen extends AbstractClientPacket {

    private final int traderEntityId;
    private final String traderName;
    private final List<CaptiveOfferData> offers;

    /**
     * Network-serializable captive offer data.
     */
    public static class CaptiveOfferData {

        public final UUID captiveId;
        public final String captiveName;
        public final String priceDescription;
        public final int priceAmount;
        public final String priceItemId;

        public CaptiveOfferData(
            UUID captiveId,
            String captiveName,
            String priceDescription,
            int priceAmount,
            String priceItemId
        ) {
            this.captiveId = captiveId;
            this.captiveName = captiveName;
            this.priceDescription = priceDescription;
            this.priceAmount = priceAmount;
            this.priceItemId = priceItemId;
        }
    }

    public PacketOpenTraderScreen(
        int traderEntityId,
        String traderName,
        List<CaptiveOfferData> offers
    ) {
        this.traderEntityId = traderEntityId;
        this.traderName = traderName;
        this.offers = offers != null ? offers : new ArrayList<>();
    }

    public void encode(FriendlyByteBuf buf) {
        buf.writeInt(traderEntityId);
        buf.writeUtf(traderName, 64);
        buf.writeInt(offers.size());

        for (CaptiveOfferData offer : offers) {
            buf.writeUUID(offer.captiveId);
            buf.writeUtf(offer.captiveName, 64);
            buf.writeUtf(offer.priceDescription, 128);
            buf.writeInt(offer.priceAmount);
            buf.writeUtf(offer.priceItemId, 128);
        }
    }

    public static PacketOpenTraderScreen decode(FriendlyByteBuf buf) {
        int traderEntityId = buf.readInt();
        String traderName = buf.readUtf(64);
        int offerCount = buf.readInt();

        List<CaptiveOfferData> offers = new ArrayList<>();
        for (int i = 0; i < offerCount; i++) {
            UUID captiveId = buf.readUUID();
            String captiveName = buf.readUtf(64);
            String priceDescription = buf.readUtf(128);
            int priceAmount = buf.readInt();
            String priceItemId = buf.readUtf(128);

            offers.add(
                new CaptiveOfferData(
                    captiveId,
                    captiveName,
                    priceDescription,
                    priceAmount,
                    priceItemId
                )
            );
        }

        return new PacketOpenTraderScreen(traderEntityId, traderName, offers);
    }

    @Override
    @OnlyIn(Dist.CLIENT)
    protected void handleClientImpl() {
        ClientHandler.handle(this);
    }

    @OnlyIn(Dist.CLIENT)
    private static class ClientHandler {

        private static void handle(PacketOpenTraderScreen pkt) {
            net.minecraft.client.Minecraft mc =
                net.minecraft.client.Minecraft.getInstance();
            if (mc.player == null) return;

            // Convert network data to screen data
            List<
                com.tiedup.remake.client.gui.screens.SlaveTraderScreen.CaptiveOffer
            > screenOffers = new ArrayList<>();
            for (CaptiveOfferData data : pkt.offers) {
                screenOffers.add(
                    new com.tiedup.remake.client.gui.screens.SlaveTraderScreen.CaptiveOffer(
                        data.captiveId,
                        data.captiveName,
                        data.priceDescription,
                        data.priceAmount,
                        data.priceItemId
                    )
                );
            }

            TiedUpMod.LOGGER.info(
                "[PacketOpenTraderScreen] Opening trader screen with {} offers",
                screenOffers.size()
            );

            mc.setScreen(
                new com.tiedup.remake.client.gui.screens.SlaveTraderScreen(
                    pkt.traderEntityId,
                    pkt.traderName,
                    screenOffers
                )
            );
        }
    }
}
