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

import com.tiedup.remake.client.gui.util.GuiLayoutConstants;
import com.tiedup.remake.client.gui.util.GuiRenderUtil;
import com.tiedup.remake.client.gui.widgets.*;
import com.tiedup.remake.items.ItemKey;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.network.ModNetwork;
import com.tiedup.remake.network.cell.PacketRequestCellList;
import com.tiedup.remake.network.slave.PacketMasterEquip;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
import com.tiedup.remake.v2.bondage.network.PacketV2SelfEquip;
import java.util.UUID;
import net.minecraft.client.gui.GuiGraphics;
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.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

/**
 * Unified bondage equipment screen replacing BondageInventoryScreen,
 * SlaveItemManagementScreen, and StruggleChoiceScreen.
 */
@OnlyIn(Dist.CLIENT)
public class UnifiedBondageScreen extends BaseScreen {

    // Visual theme colors (vanilla MC style)
    private static final int TITLE_COLOR = 0xFF404040;
    private static final int MODE_SELF_BG = 0xFF8B8B8B;
    private static final int MODE_MASTER_BG = 0xFF707070;

    // Full-body view for all tabs (zoom per-tab was too finicky to get right)
    private static final float[] TAB_SCALES = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
    private static final float[] TAB_OFFSETS = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };

    private final ActionPanel.ScreenMode mode;
    private final LivingEntity targetEntity;
    private final UUID targetEntityUUID;

    // Widgets
    private RegionTabBar tabBar;
    private EntityPreviewWidget preview;
    private RegionSlotWidget[] currentSlots;
    private ActionPanel actionPanel;
    private ItemPickerOverlay pickerOverlay;
    private StatusBarWidget statusBar;

    // State
    private RegionSlotWidget selectedSlot;
    private int refreshCountdown = -1;

    // Key info (for master mode)
    private UUID keyUUID;
    private boolean isMasterKey;

    /**
     * Open in SELF mode.
     */
    public UnifiedBondageScreen() {
        this(ActionPanel.ScreenMode.SELF, null);
    }

    /**
     * Open in MASTER mode targeting a specific entity.
     */
    public UnifiedBondageScreen(LivingEntity target) {
        this(ActionPanel.ScreenMode.MASTER, target);
    }

    private UnifiedBondageScreen(
        ActionPanel.ScreenMode mode,
        LivingEntity target
    ) {
        super(Component.translatable("gui.tiedup.unified_bondage"));
        this.mode = mode;
        this.targetEntity = target;
        this.targetEntityUUID = (target != null) ? target.getUUID() : null;
    }

    private LivingEntity getTarget() {
        return (mode == ActionPanel.ScreenMode.SELF)
            ? minecraft.player
            : targetEntity;
    }

    @Override
    protected int getPreferredWidth() {
        return GuiLayoutConstants.getResponsiveWidth(
            this.width,
            0.65f,
            420,
            600
        );
    }

    @Override
    protected int getPreferredHeight() {
        return GuiLayoutConstants.getResponsiveHeight(
            this.height,
            0.75f,
            350,
            500
        );
    }

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

        // Resolve key info for master mode by iterating player inventory
        if (mode == ActionPanel.ScreenMode.MASTER && minecraft.player != null) {
            ItemStack keyStack = findFirstKey(minecraft.player);
            if (!keyStack.isEmpty()) {
                if (keyStack.getItem() instanceof ItemKey key) {
                    this.keyUUID = key.getKeyUUID(keyStack);
                    this.isMasterKey = false;
                } else if (keyStack.is(ModItems.MASTER_KEY.get())) {
                    this.keyUUID = null;
                    this.isMasterKey = true;
                }
            }
        }

        int contentTop =
            topPos +
            GuiLayoutConstants.TITLE_HEIGHT +
            GuiLayoutConstants.MARGIN_M;

        // === Tab Bar ===
        tabBar = new RegionTabBar(leftPos + 2, contentTop, imageWidth - 4);
        tabBar.setTargetEntity(getTarget());
        tabBar.setOnTabChanged(this::onTabChanged);
        addRenderableWidget(tabBar);

        int belowTabs = contentTop + 30;
        int statusBarHeight = 46;
        int mainContentHeight =
            imageHeight -
            (belowTabs - topPos) -
            statusBarHeight -
            GuiLayoutConstants.MARGIN_S;

        // === Preview (Left, 40%) ===
        int previewWidth = (int) ((imageWidth -
                GuiLayoutConstants.MARGIN_M * 3) *
            0.40f);
        LivingEntity target = getTarget();
        if (target != null) {
            preview = new EntityPreviewWidget(
                leftPos + GuiLayoutConstants.MARGIN_M,
                belowTabs,
                previewWidth,
                mainContentHeight,
                target
            );
            preview.setAutoRotate(true);
            preview.setAutoRotateSpeed(0.3f);
            preview.setZoomTarget(TAB_SCALES[0], TAB_OFFSETS[0]);
            addRenderableWidget(preview);
        }

        // === Right panel area ===
        int rightX =
            leftPos +
            GuiLayoutConstants.MARGIN_M +
            previewWidth +
            GuiLayoutConstants.MARGIN_M;
        int rightWidth =
            imageWidth - (rightX - leftPos) - GuiLayoutConstants.MARGIN_M;

        // Action panel height
        int actionPanelHeight = 84;
        int slotsHeight =
            mainContentHeight - actionPanelHeight - GuiLayoutConstants.MARGIN_S;

        // === Region Slots ===
        buildSlots(rightX, belowTabs, rightWidth, slotsHeight);

        // === Action Panel ===
        actionPanel = new ActionPanel(
            rightX,
            belowTabs + slotsHeight + GuiLayoutConstants.MARGIN_S,
            rightWidth,
            actionPanelHeight
        );
        actionPanel.setMode(mode);
        actionPanel.setTargetEntity(getTarget());
        actionPanel.setKeyInfo(keyUUID, isMasterKey);
        actionPanel.setOnAdjustRequested(region -> {
            if (AdjustmentScreen.canOpen()) minecraft.setScreen(
                new AdjustmentScreen()
            );
        });
        actionPanel.setOnEquipRequested(this::openPicker);
        actionPanel.setOnCellAssignRequested(() -> {
            if (targetEntityUUID != null) ModNetwork.sendToServer(
                new PacketRequestCellList(targetEntityUUID)
            );
        });
        actionPanel.setOnCloseRequested(this::onClose);
        actionPanel.clearContext();
        addRenderableWidget(actionPanel);

        // === Status Bar ===
        int statusY = topPos + imageHeight - statusBarHeight;
        statusBar = new StatusBarWidget(
            leftPos,
            statusY,
            imageWidth,
            statusBarHeight
        );
        statusBar.setMode(mode);
        statusBar.setTargetEntity(getTarget());
        statusBar.setOnCloseClicked(this::onClose);
        addRenderableWidget(statusBar);

        // === Picker Overlay (created but hidden) ===
        pickerOverlay = new ItemPickerOverlay();
        pickerOverlay.setOnItemSelected(this::onPickerItemSelected);
        pickerOverlay.setOnCancelled(() -> {}); // No-op, just close
        addRenderableWidget(pickerOverlay);

        // Auto-select first occupied slot
        autoSelectFirstOccupied();
    }

    /**
     * Find the first key (ItemKey or ItemMasterKey) in the player's inventory.
     * Regular ItemKey is preferred; falls back to master key if none found.
     */
    private static ItemStack findFirstKey(Player player) {
        ItemStack masterKeyStack = ItemStack.EMPTY;
        for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
            ItemStack stack = player.getInventory().getItem(i);
            if (stack.isEmpty()) continue;
            if (stack.getItem() instanceof ItemKey) {
                return stack; // Regular key takes priority
            }
            if (
                masterKeyStack.isEmpty() && stack.is(ModItems.MASTER_KEY.get())
            ) {
                masterKeyStack = stack; // Remember master key as fallback
            }
        }
        return masterKeyStack; // Empty or master key
    }

    private void buildSlots(int x, int y, int width, int totalHeight) {
        RegionTabBar.BodyTab tab = tabBar.getActiveTab();
        BodyRegionV2[] regions = tab.getRegions().toArray(new BodyRegionV2[0]);
        currentSlots = new RegionSlotWidget[regions.length];

        int slotHeight = Math.min(52, (totalHeight - 4) / regions.length);
        LivingEntity target = getTarget();

        for (int i = 0; i < regions.length; i++) {
            BodyRegionV2 region = regions[i];
            int slotY = y + i * slotHeight;

            RegionSlotWidget slot = new RegionSlotWidget(
                x,
                slotY,
                width,
                slotHeight - 2,
                region,
                () ->
                    target != null
                        ? V2EquipmentHelper.getInRegion(target, region)
                        : ItemStack.EMPTY
            );
            slot.setOnClick(this::onSlotClicked);
            slot.setShowEquipButton(true);
            slot.setOnEquipClick(s -> openPicker(s.getRegion()));

            // Adjust button for MOUTH/EYES
            if (region == BodyRegionV2.MOUTH || region == BodyRegionV2.EYES) {
                slot.setShowAdjustButton(true);
            }

            currentSlots[i] = slot;
            addRenderableWidget(slot);
        }
    }

    private void onTabChanged(RegionTabBar.BodyTab tab) {
        // Update preview zoom
        int tabIdx = tab.ordinal();
        if (preview != null) {
            preview.setZoomTarget(TAB_SCALES[tabIdx], TAB_OFFSETS[tabIdx]);
        }

        // Rebuild slots — clear old ones and re-init
        if (currentSlots != null) {
            for (RegionSlotWidget slot : currentSlots) {
                removeWidget(slot);
            }
        }
        selectedSlot = null;
        actionPanel.clearContext();

        // Recalculate layout for slots
        int contentTop =
            topPos +
            GuiLayoutConstants.TITLE_HEIGHT +
            GuiLayoutConstants.MARGIN_M;
        int belowTabs = contentTop + 30;
        int statusBarHeight = 46;
        int mainContentHeight =
            imageHeight -
            (belowTabs - topPos) -
            statusBarHeight -
            GuiLayoutConstants.MARGIN_S;
        int previewWidth = (int) ((imageWidth -
                GuiLayoutConstants.MARGIN_M * 3) *
            0.40f);
        int rightX =
            leftPos +
            GuiLayoutConstants.MARGIN_M +
            previewWidth +
            GuiLayoutConstants.MARGIN_M;
        int rightWidth =
            imageWidth - (rightX - leftPos) - GuiLayoutConstants.MARGIN_M;
        int actionPanelHeight = 84;
        int slotsHeight =
            mainContentHeight - actionPanelHeight - GuiLayoutConstants.MARGIN_S;

        buildSlots(rightX, belowTabs, rightWidth, slotsHeight);
        autoSelectFirstOccupied();
    }

    private void onSlotClicked(RegionSlotWidget slot) {
        // Deselect previous
        if (selectedSlot != null) selectedSlot.setSelected(false);
        // Select new
        selectedSlot = slot;
        slot.setSelected(true);
        // Update action panel
        actionPanel.setContext(slot.getRegion(), slot.getItem());
    }

    private void autoSelectFirstOccupied() {
        if (currentSlots == null) return;
        for (RegionSlotWidget slot : currentSlots) {
            if (!slot.getItem().isEmpty()) {
                onSlotClicked(slot);
                return;
            }
        }
        // No occupied slots — select first slot anyway for equip
        if (currentSlots.length > 0) {
            onSlotClicked(currentSlots[0]);
        }
    }

    private void openPicker(BodyRegionV2 region) {
        pickerOverlay.open(
            region,
            mode == ActionPanel.ScreenMode.SELF,
            this.width,
            this.height
        );
    }

    private void onPickerItemSelected(BodyRegionV2 region, int inventorySlot) {
        if (mode == ActionPanel.ScreenMode.SELF) {
            ModNetwork.sendToServer(
                new PacketV2SelfEquip(region, inventorySlot)
            );
        } else {
            ModNetwork.sendToServer(
                new PacketMasterEquip(targetEntityUUID, region, inventorySlot)
            );
        }
        refreshCountdown = 10; // Refresh after server processes
    }

    @Override
    public void tick() {
        super.tick();
        if (preview != null) preview.tickZoom();

        if (refreshCountdown > 0) {
            refreshCountdown--;
        } else if (refreshCountdown == 0) {
            refreshCountdown = -1;
            rebuildCurrentTab();
        }
    }

    private void rebuildCurrentTab() {
        onTabChanged(tabBar.getActiveTab());
    }

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

        // MC-style raised panel
        GuiRenderUtil.drawMCPanel(
            graphics,
            leftPos,
            topPos,
            imageWidth,
            imageHeight
        );

        // Title (dark text, vanilla style)
        String titleText = this.title.getString();
        if (mode == ActionPanel.ScreenMode.MASTER && targetEntity != null) {
            titleText += " \u2014 " + targetEntity.getName().getString();
        }
        GuiRenderUtil.drawCenteredStringNoShadow(
            graphics,
            font,
            titleText,
            leftPos + imageWidth / 2,
            topPos + GuiLayoutConstants.MARGIN_M,
            TITLE_COLOR
        );

        // Mode badge (top-right) — sober gray badge
        int badgeWidth = 90;
        int badgeX =
            leftPos + imageWidth - badgeWidth - GuiLayoutConstants.MARGIN_M;
        int badgeY = topPos + GuiLayoutConstants.MARGIN_S;
        int badgeBg =
            mode == ActionPanel.ScreenMode.MASTER
                ? MODE_MASTER_BG
                : MODE_SELF_BG;
        graphics.fill(
            badgeX,
            badgeY,
            badgeX + badgeWidth,
            badgeY + 16,
            badgeBg
        );
        String badgeText =
            mode == ActionPanel.ScreenMode.MASTER
                ? Component.translatable("gui.tiedup.mode.master").getString()
                : Component.translatable("gui.tiedup.mode.self").getString();
        GuiRenderUtil.drawCenteredStringNoShadow(
            graphics,
            font,
            badgeText,
            badgeX + badgeWidth / 2,
            badgeY + 4,
            GuiRenderUtil.MC_TEXT_DARK
        );

        // Render all widgets
        super.render(graphics, mouseX, mouseY, partialTick);

        // Picker overlay renders on top of everything
        if (pickerOverlay.isOverlayVisible()) {
            pickerOverlay.render(graphics, mouseX, mouseY, partialTick);
        }
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        // Picker overlay captures all clicks when visible
        if (pickerOverlay.isOverlayVisible()) {
            return pickerOverlay.mouseClicked(mouseX, mouseY, button);
        }
        return super.mouseClicked(mouseX, mouseY, button);
    }

    @Override
    public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
        if (pickerOverlay.isOverlayVisible()) {
            return pickerOverlay.keyPressed(keyCode, scanCode, modifiers);
        }
        return super.keyPressed(keyCode, scanCode, modifiers);
    }

    @Override
    public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
        if (pickerOverlay.isOverlayVisible()) {
            return pickerOverlay.mouseScrolled(mouseX, mouseY, delta);
        }
        return super.mouseScrolled(mouseX, mouseY, delta);
    }
}
