package com.tiedup.remake.client.gui.screens;

import com.tiedup.remake.client.gui.util.GuiColors;
import com.tiedup.remake.client.gui.util.GuiLayoutConstants;
import com.tiedup.remake.client.gui.widgets.SlaveEntryWidget;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.network.ModNetwork;
import com.tiedup.remake.network.slave.PacketSlaveAction;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.state.PlayerCaptorManager;
import com.tiedup.remake.util.KidnappedHelper;
import com.tiedup.remake.v2.BodyRegionV2;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

/**
 * Dashboard screen for masters to manage all their slaves.
 * Refactored to use standard ContainerObjectSelectionList.
 */
@OnlyIn(Dist.CLIENT)
public class SlaveManagementScreen extends BaseScreen {

    private SlaveList slaveList;
    private Button closeButton;

    public SlaveManagementScreen() {
        super(Component.translatable("gui.tiedup.slave_management"));
    }

    @Override
    protected int getPreferredWidth() {
        return GuiLayoutConstants.getResponsiveWidth(
            this.width,
            0.7f,
            350,
            500
        );
    }

    @Override
    protected int getPreferredHeight() {
        return GuiLayoutConstants.getResponsiveHeight(
            this.height,
            0.8f,
            250,
            400
        );
    }

    @Override
    protected void init() {
        super.init();

        int listLeft = this.leftPos + 10;
        int listWidth = this.imageWidth - 20;
        int listTop = this.topPos + GuiLayoutConstants.TITLE_HEIGHT + 20; // Title + count
        int listBottom =
            this.topPos +
            this.imageHeight -
            GuiLayoutConstants.BUTTON_HEIGHT -
            10;

        // Initialize the list with proper bounds
        slaveList = new SlaveList(
            minecraft,
            listWidth,
            listTop,
            listBottom,
            listLeft
        );

        refreshSlaveList();
        this.addRenderableWidget(slaveList);

        // Close button
        int btnWidth = GuiLayoutConstants.BUTTON_WIDTH_XL;
        closeButton = Button.builder(
            Component.translatable("gui.tiedup.close"),
            b -> onClose()
        )
            .bounds(
                this.leftPos + (this.imageWidth - btnWidth) / 2,
                this.topPos +
                    this.imageHeight -
                    GuiLayoutConstants.BUTTON_HEIGHT -
                    6,
                btnWidth,
                GuiLayoutConstants.BUTTON_HEIGHT
            )
            .build();
        this.addRenderableWidget(closeButton);
    }

    public static boolean shouldShow() {
        Minecraft mc = Minecraft.getInstance();
        return mc.player != null;
    }

    private void refreshSlaveList() {
        slaveList.clearEntriesPublic();

        if (this.minecraft == null || this.minecraft.player == null) return;

        Player player = this.minecraft.player;
        Set<UUID> addedUUIDs = new HashSet<>();

        // 1. Add captives from PlayerCaptorManager
        PlayerBindState state = PlayerBindState.getInstance(player);
        if (state != null) {
            PlayerCaptorManager manager = state.getCaptorManager();
            if (manager != null) {
                for (IBondageState captive : manager.getCaptives()) {
                    addSlaveEntry(captive);
                    LivingEntity entity = captive.asLivingEntity();
                    if (entity != null) {
                        addedUUIDs.add(entity.getUUID());
                    }
                }
            }
        }

        // 2. Add nearby collar-linked entities (50-block radius matches server validation)
        AABB searchBox = player.getBoundingBox().inflate(50);
        for (LivingEntity entity : player
            .level()
            .getEntitiesOfClass(LivingEntity.class, searchBox)) {
            if (entity == player) continue;
            if (addedUUIDs.contains(entity.getUUID())) continue;

            IBondageState kidnapped = KidnappedHelper.getKidnappedState(entity);
            if (kidnapped != null && kidnapped.hasCollar()) {
                ItemStack collarStack = kidnapped.getEquipment(
                    BodyRegionV2.NECK
                );
                if (CollarHelper.isCollar(collarStack)) {
                    if (CollarHelper.isOwner(collarStack, player)) {
                        addSlaveEntry(kidnapped);
                        addedUUIDs.add(entity.getUUID());
                    }
                }
            }
        }
    }

    private void addSlaveEntry(IBondageState slave) {
        slaveList.addEntryPublic(
            new SlaveEntryWidget(
                slave,
                this::onAdjustClicked,
                this::onShockClicked,
                this::onLocateClicked,
                this::onFreeClicked
            )
        );
    }

    // ==================== ACTIONS ====================

    private void onAdjustClicked(IBondageState slave) {
        LivingEntity entity = slave.asLivingEntity();
        if (entity != null) {
            this.minecraft.setScreen(
                new RemoteAdjustmentScreen(slave, entity.getUUID())
            );
        }
    }

    private void onShockClicked(IBondageState slave) {
        LivingEntity entity = slave.asLivingEntity();
        if (entity != null) {
            ModNetwork.sendToServer(
                new PacketSlaveAction(
                    entity.getUUID(),
                    PacketSlaveAction.Action.SHOCK
                )
            );
        }
    }

    private void onLocateClicked(IBondageState slave) {
        LivingEntity entity = slave.asLivingEntity();
        if (entity != null) {
            ModNetwork.sendToServer(
                new PacketSlaveAction(
                    entity.getUUID(),
                    PacketSlaveAction.Action.LOCATE
                )
            );
        }
    }

    private void onFreeClicked(IBondageState slave) {
        LivingEntity entity = slave.asLivingEntity();
        if (entity != null) {
            ModNetwork.sendToServer(
                new PacketSlaveAction(
                    entity.getUUID(),
                    PacketSlaveAction.Action.FREE
                )
            );
            // Refresh list after a short delay or immediately (server sync latency might require delay)
            // For now, immediate refresh to remove from UI
            refreshSlaveList();
        }
    }

    // ==================== RENDERING ====================

    @Override
    public void render(
        GuiGraphics graphics,
        int mouseX,
        int mouseY,
        float partialTick
    ) {
        super.render(graphics, mouseX, mouseY, partialTick);

        // Slave count text
        String countText =
            slaveList.children().size() +
            " slave" +
            (slaveList.children().size() != 1 ? "s" : "");
        graphics.drawString(
            this.font,
            countText,
            this.leftPos + GuiLayoutConstants.MARGIN_M,
            this.topPos + GuiLayoutConstants.TITLE_HEIGHT + 2,
            GuiColors.TEXT_GRAY
        );

        // Empty state
        if (slaveList.children().isEmpty()) {
            graphics.drawCenteredString(
                this.font,
                Component.translatable("gui.tiedup.slave_management.no_slaves"),
                this.leftPos + this.imageWidth / 2,
                this.topPos + this.imageHeight / 2,
                GuiColors.TEXT_DISABLED
            );
        }
    }

    // ==================== INNER CLASS: LIST ====================

    class SlaveList extends ContainerObjectSelectionList<SlaveEntryWidget> {

        private final int listLeft;
        private final int listWidth;

        public SlaveList(
            Minecraft mc,
            int width,
            int top,
            int bottom,
            int left
        ) {
            super(
                mc,
                width,
                bottom - top,
                top,
                bottom,
                GuiLayoutConstants.ENTRY_HEIGHT
            );
            this.listLeft = left;
            this.listWidth = width;
            this.centerListVertically = false;
            this.setRenderBackground(false);
            this.setRenderTopAndBottom(false);

            // Set horizontal bounds directly (x0/x1 are protected in AbstractSelectionList)
            this.x0 = left;
            this.x1 = left + width;
        }

        public void addEntryPublic(SlaveEntryWidget entry) {
            this.addEntry(entry);
        }

        public void clearEntriesPublic() {
            this.clearEntries();
        }

        @Override
        public int getRowWidth() {
            return this.listWidth - 12; // Leave space for scrollbar
        }

        @Override
        protected int getScrollbarPosition() {
            return this.listLeft + this.listWidth - 6;
        }

        @Override
        public int getRowLeft() {
            return this.listLeft;
        }
    }

    public static boolean canOpen() {
        Minecraft mc = Minecraft.getInstance();
        if (mc.player == null) return false;
        PlayerBindState state = PlayerBindState.getInstance(mc.player);
        return (
            state != null &&
            state.getCaptorManager() != null &&
            state.getCaptorManager().hasCaptives()
        );
    }
}
