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.CellListRenderer;
import com.tiedup.remake.network.ModNetwork;
import com.tiedup.remake.network.cell.PacketCellAction;
import com.tiedup.remake.network.cell.PacketOpenCellManager.CellSyncData;
import com.tiedup.remake.network.cell.PacketOpenCellManager.PrisonerInfo;
import com.tiedup.remake.network.cell.PacketRenameCell;
import java.util.List;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.network.chat.Component;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.Nullable;

/**
 * Screen for managing player-owned cells.
 * Shows list of cells with prisoners and management actions.
 *
 * Operators (OP) can see and manage ALL cells.
 * Non-operators can only manage their own cells.
 */
@OnlyIn(Dist.CLIENT)
public class CellManagerScreen extends BaseScreen {

    private final List<CellSyncData> cells;
    private final boolean isOperator;

    // Selection state
    @Nullable
    private CellSyncData selectedCell;

    @Nullable
    private PrisonerInfo selectedPrisoner;

    // UI state
    private boolean renameMode = false;
    private EditBox renameBox;

    // Layout
    private int listStartY;
    private int listHeight;
    private int cellEntryHeight = 24;
    private int prisonerEntryHeight = 18;
    private int scrollOffset = 0;

    // Buttons
    private Button closeButton;
    private Button renameButton;
    private Button deleteButton;
    private Button releaseButton;
    private Button teleportButton;

    /**
     * Create the cell manager screen.
     *
     * @param cells      List of cells to display
     * @param isOperator True if the viewing player is an operator (can manage all cells)
     */
    public CellManagerScreen(List<CellSyncData> cells, boolean isOperator) {
        super(Component.translatable("gui.tiedup.cell_manager"));
        this.cells = cells;
        this.isOperator = isOperator;
    }

    /**
     * Legacy constructor (assumes not operator).
     */
    public CellManagerScreen(List<CellSyncData> cells) {
        this(cells, false);
    }

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

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

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

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

        // Calculate list height (leave room for buttons at bottom)
        int buttonsAreaHeight =
            GuiLayoutConstants.BUTTON_HEIGHT * 2 +
            GuiLayoutConstants.MARGIN_L +
            GuiLayoutConstants.MARGIN_M;
        listHeight =
            this.imageHeight - (listStartY - this.topPos) - buttonsAreaHeight;

        // === Action Buttons (bottom) ===
        int buttonY =
            this.topPos +
            this.imageHeight -
            GuiLayoutConstants.BUTTON_HEIGHT * 2 -
            GuiLayoutConstants.MARGIN_L;
        int buttonWidth = 80;
        int buttonSpacing = 6;
        int buttonsStartX = this.leftPos + GuiLayoutConstants.MARGIN_M;

        // Row 1: Rename, Delete
        renameButton = Button.builder(
            Component.translatable("gui.tiedup.cell_manager.button.rename"),
            b -> toggleRenameMode()
        )
            .bounds(
                buttonsStartX,
                buttonY,
                buttonWidth,
                GuiLayoutConstants.BUTTON_HEIGHT
            )
            .build();
        this.addRenderableWidget(renameButton);

        deleteButton = Button.builder(
            Component.translatable(
                "gui.tiedup.cell_manager.button.delete"
            ).withStyle(ChatFormatting.RED),
            b -> deleteSelectedCell()
        )
            .bounds(
                buttonsStartX + buttonWidth + buttonSpacing,
                buttonY,
                buttonWidth,
                GuiLayoutConstants.BUTTON_HEIGHT
            )
            .build();
        this.addRenderableWidget(deleteButton);

        // Row 2: Release, Teleport
        int row2Y =
            buttonY +
            GuiLayoutConstants.BUTTON_HEIGHT +
            GuiLayoutConstants.MARGIN_S;

        releaseButton = Button.builder(
            Component.translatable("gui.tiedup.cell_manager.button.release"),
            b -> releaseSelectedPrisoner()
        )
            .bounds(
                buttonsStartX,
                row2Y,
                buttonWidth,
                GuiLayoutConstants.BUTTON_HEIGHT
            )
            .build();
        this.addRenderableWidget(releaseButton);

        teleportButton = Button.builder(
            Component.translatable("gui.tiedup.cell_manager.button.teleport"),
            b -> teleportSelectedPrisoner()
        )
            .bounds(
                buttonsStartX + buttonWidth + buttonSpacing,
                row2Y,
                buttonWidth,
                GuiLayoutConstants.BUTTON_HEIGHT
            )
            .build();
        this.addRenderableWidget(teleportButton);

        // Close button (right side)
        closeButton = Button.builder(
            Component.translatable("gui.tiedup.close"),
            b -> onClose()
        )
            .bounds(
                this.leftPos +
                    this.imageWidth -
                    GuiLayoutConstants.BUTTON_WIDTH_M -
                    GuiLayoutConstants.MARGIN_M,
                row2Y,
                GuiLayoutConstants.BUTTON_WIDTH_M,
                GuiLayoutConstants.BUTTON_HEIGHT
            )
            .build();
        this.addRenderableWidget(closeButton);

        // Rename edit box (hidden by default)
        renameBox = new EditBox(
            this.font,
            this.leftPos + GuiLayoutConstants.MARGIN_M,
            buttonY - 25,
            this.imageWidth - GuiLayoutConstants.MARGIN_M * 2 - 60,
            20,
            Component.translatable("gui.tiedup.cell_manager.cell_name")
        );
        renameBox.setMaxLength(32);
        renameBox.setVisible(false);
        this.addRenderableWidget(renameBox);

        updateButtonStates();
    }

    private void updateButtonStates() {
        boolean hasCellSelected = selectedCell != null;
        boolean hasPrisonerSelected = selectedPrisoner != null;

        // Determine if player can manage the selected cell
        // OP can manage any cell, non-OP can only manage their owned cells
        boolean canManageCell =
            hasCellSelected && (isOperator || selectedCell.isOwned);

        renameButton.active = canManageCell && !renameMode;
        deleteButton.active = canManageCell && !renameMode;
        releaseButton.active =
            canManageCell && hasPrisonerSelected && !renameMode;
        teleportButton.active =
            canManageCell && hasPrisonerSelected && !renameMode;
    }

    private void toggleRenameMode() {
        if (selectedCell == null) return;

        renameMode = !renameMode;
        renameBox.setVisible(renameMode);

        if (renameMode) {
            String currentName =
                selectedCell.name != null ? selectedCell.name : "";
            renameBox.setValue(currentName);
            renameBox.setFocused(true);
            renameButton.setMessage(
                Component.translatable(
                    "gui.tiedup.cell_manager.button.save"
                ).withStyle(ChatFormatting.GREEN)
            );
        } else {
            // Save the name
            String newName = renameBox.getValue().trim();
            ModNetwork.sendToServer(
                new PacketRenameCell(selectedCell.cellId, newName)
            );
            renameButton.setMessage(
                Component.translatable("gui.tiedup.cell_manager.button.rename")
            );
        }

        updateButtonStates();
    }

    private void deleteSelectedCell() {
        if (selectedCell == null) return;

        ModNetwork.sendToServer(
            new PacketCellAction(
                PacketCellAction.Action.DELETE_CELL,
                selectedCell.cellId,
                null,
                null
            )
        );

        // Remove from local list and deselect
        cells.remove(selectedCell);
        selectedCell = null;
        selectedPrisoner = null;
        updateButtonStates();
    }

    private void releaseSelectedPrisoner() {
        if (selectedCell == null || selectedPrisoner == null) return;

        ModNetwork.sendToServer(
            new PacketCellAction(
                PacketCellAction.Action.RELEASE,
                selectedCell.cellId,
                selectedPrisoner.prisonerId,
                null
            )
        );

        // Remove prisoner from local state
        selectedCell.prisoners.remove(selectedPrisoner);
        selectedPrisoner = null;
        updateButtonStates();
    }

    private void teleportSelectedPrisoner() {
        if (selectedCell == null || selectedPrisoner == null) return;

        ModNetwork.sendToServer(
            new PacketCellAction(
                PacketCellAction.Action.TELEPORT,
                selectedCell.cellId,
                selectedPrisoner.prisonerId,
                null
            )
        );
    }

    @Override
    protected void renderContent(
        GuiGraphics graphics,
        int mouseX,
        int mouseY,
        float partialTick
    ) {
        // Cell count subtitle (show OP mode indicator if operator)
        Component subtitle = Component.translatable(
            "gui.tiedup.cell_manager.label.cell_count",
            cells.size()
        );
        if (isOperator) {
            subtitle = subtitle
                .copy()
                .append(" ")
                .append(
                    Component.translatable(
                        "gui.tiedup.cell_manager.label.op_mode"
                    )
                );
        }
        graphics.drawCenteredString(
            this.font,
            subtitle
                .copy()
                .withStyle(
                    isOperator ? ChatFormatting.GOLD : ChatFormatting.GRAY
                ),
            this.leftPos + this.imageWidth / 2,
            this.topPos + GuiLayoutConstants.MARGIN_M + 12,
            isOperator ? GuiColors.WARNING : GuiColors.TEXT_GRAY
        );

        // Render cell list
        renderCellList(graphics, mouseX, mouseY);

        // Render rename mode hint
        if (renameMode) {
            graphics.drawString(
                this.font,
                Component.translatable(
                    "gui.tiedup.cell_manager.status.rename_hint"
                ).getString(),
                this.leftPos + GuiLayoutConstants.MARGIN_M,
                renameBox.getY() - 12,
                GuiColors.TEXT_GRAY
            );
        }
    }

    /**
     * Calculate the total pixel height of all cell entries.
     */
    private int getTotalContentHeight() {
        int total = 0;
        for (CellSyncData cell : cells) {
            total += cellEntryHeight;
            int prisoners = cell.prisoners.isEmpty()
                ? 1
                : cell.prisoners.size();
            total += prisoners * prisonerEntryHeight;
            total += 4; // spacing
        }
        return total;
    }

    private int getMaxScrollOffset() {
        int totalHeight = getTotalContentHeight();
        return Math.max(0, totalHeight - listHeight);
    }

    @Override
    public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
        int maxScroll = getMaxScrollOffset();
        if (maxScroll > 0) {
            int scrollAmount = (int) (delta * 20);
            scrollOffset = Math.max(
                0,
                Math.min(maxScroll, scrollOffset - scrollAmount)
            );
            return true;
        }
        return super.mouseScrolled(mouseX, mouseY, delta);
    }

    private void renderCellList(GuiGraphics graphics, int mouseX, int mouseY) {
        int listX = this.leftPos + GuiLayoutConstants.MARGIN_M;
        int listWidth = this.imageWidth - GuiLayoutConstants.MARGIN_M * 2;

        // Apply scroll offset to starting Y
        int currentY = listStartY - scrollOffset;

        for (CellSyncData cell : cells) {
            if (currentY > listStartY + listHeight) break;
            if (currentY + cellEntryHeight < listStartY) {
                currentY +=
                    cellEntryHeight +
                    cell.prisoners.size() * prisonerEntryHeight;
                continue;
            }

            // Cell header background
            boolean cellSelected = cell == selectedCell;
            boolean cellHovered =
                mouseX >= listX &&
                mouseX < listX + listWidth &&
                mouseY >= currentY &&
                mouseY < currentY + cellEntryHeight;

            int bgColor;
            if (cellSelected) {
                bgColor = GuiColors.SLOT_SELECTED;
            } else if (cellHovered) {
                bgColor = GuiColors.SLOT_HOVER;
            } else {
                bgColor = GuiColors.BG_LIGHT;
            }

            graphics.fill(
                listX,
                currentY,
                listX + listWidth,
                currentY + cellEntryHeight,
                bgColor
            );

            // Cell icon - different color for owned vs not-owned cells
            int iconColor = cell.isOwned
                ? GuiColors.TYPE_COLLAR
                : GuiColors.TEXT_DISABLED;
            graphics.fill(
                listX + 4,
                currentY + 4,
                listX + 18,
                currentY + 18,
                iconColor
            );

            // Lock icon overlay if not owned and not OP
            if (!cell.isOwned && !isOperator) {
                graphics.drawString(
                    this.font,
                    "\uD83D\uDD12",
                    listX + 5,
                    currentY + 5,
                    GuiColors.TEXT_DISABLED
                ); // Lock emoji
            }

            // Cell name
            String displayName = cell.getDisplayName();
            int nameColor = cell.isOwned
                ? GuiColors.TEXT_WHITE
                : GuiColors.TEXT_GRAY;
            graphics.drawString(
                this.font,
                displayName,
                listX + 24,
                currentY + 4,
                nameColor
            );

            // Prisoner count badge
            CellListRenderer.renderCountBadge(
                graphics,
                this.font,
                cell.prisonerCount,
                cell.maxPrisoners,
                listX + listWidth,
                currentY + 4
            );

            // Location + owner info for non-owned cells
            String locStr = "@ " + cell.spawnPoint.toShortString();
            if (!cell.isOwned && cell.ownerName != null) {
                locStr +=
                    " (" +
                    Component.translatable(
                        "gui.tiedup.cell_manager.label.owner",
                        cell.ownerName
                    ).getString() +
                    ")";
            }
            graphics.drawString(
                this.font,
                locStr,
                listX + 24,
                currentY + 14,
                GuiColors.TEXT_DISABLED
            );

            currentY += cellEntryHeight;

            // Render prisoners under this cell
            for (PrisonerInfo prisoner : cell.prisoners) {
                if (currentY > listStartY + listHeight) break;

                boolean prisonerSelected =
                    prisoner == selectedPrisoner && cell == selectedCell;
                boolean prisonerHovered =
                    mouseX >= listX + 20 &&
                    mouseX < listX + listWidth &&
                    mouseY >= currentY &&
                    mouseY < currentY + prisonerEntryHeight;

                int prisonerBg;
                if (prisonerSelected) {
                    prisonerBg = GuiColors.lighten(
                        GuiColors.SLOT_SELECTED,
                        0.2f
                    );
                } else if (prisonerHovered) {
                    prisonerBg = GuiColors.SLOT_HOVER;
                } else {
                    prisonerBg = GuiColors.BG_DARK;
                }

                graphics.fill(
                    listX + 20,
                    currentY,
                    listX + listWidth,
                    currentY + prisonerEntryHeight,
                    prisonerBg
                );

                // Prisoner indicator
                graphics.drawString(
                    this.font,
                    "  \u2514\u2500 ",
                    listX,
                    currentY + 2,
                    GuiColors.TEXT_DISABLED
                );

                // Prisoner name
                graphics.drawString(
                    this.font,
                    prisoner.prisonerName,
                    listX + 40,
                    currentY + 4,
                    GuiColors.TEXT_WHITE
                );

                currentY += prisonerEntryHeight;
            }

            // If no prisoners, show "(empty)"
            if (cell.prisoners.isEmpty()) {
                graphics.drawString(
                    this.font,
                    Component.translatable("gui.tiedup.cell_manager.tree_prefix")
                        .append(
                            Component.translatable(
                                "gui.tiedup.cell_manager.label.empty"
                            )
                        )
                        .withStyle(ChatFormatting.ITALIC),
                    listX,
                    currentY + 2,
                    GuiColors.TEXT_DISABLED
                );
                currentY += prisonerEntryHeight;
            }

            // Spacing between cells
            currentY += 4;
        }

        // If no cells
        if (cells.isEmpty()) {
            CellListRenderer.renderEmptyState(
                graphics,
                this.font,
                this.leftPos + this.imageWidth / 2,
                listStartY,
                "gui.tiedup.cell_manager.status.no_cells",
                "gui.tiedup.cell_manager.status.use_cellwand"
            );
        }
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        if (button == 0 && !renameMode) {
            // Only handle clicks within the visible list area
            if (mouseY < listStartY || mouseY > listStartY + listHeight) {
                return super.mouseClicked(mouseX, mouseY, button);
            }

            // Handle cell/prisoner selection
            int listX = this.leftPos + GuiLayoutConstants.MARGIN_M;
            int listWidth = this.imageWidth - GuiLayoutConstants.MARGIN_M * 2;
            int currentY = listStartY - scrollOffset;

            for (CellSyncData cell : cells) {
                if (currentY > listStartY + listHeight) break;

                // Check cell header click
                if (
                    mouseX >= listX &&
                    mouseX < listX + listWidth &&
                    mouseY >= currentY &&
                    mouseY < currentY + cellEntryHeight
                ) {
                    selectedCell = cell;
                    selectedPrisoner = null;
                    updateButtonStates();
                    return true;
                }

                currentY += cellEntryHeight;

                // Check prisoner clicks
                for (PrisonerInfo prisoner : cell.prisoners) {
                    if (currentY > listStartY + listHeight) break;

                    if (
                        mouseX >= listX + 20 &&
                        mouseX < listX + listWidth &&
                        mouseY >= currentY &&
                        mouseY < currentY + prisonerEntryHeight
                    ) {
                        selectedCell = cell;
                        selectedPrisoner = prisoner;
                        updateButtonStates();
                        return true;
                    }

                    currentY += prisonerEntryHeight;
                }

                // Empty cell placeholder height
                if (cell.prisoners.isEmpty()) {
                    currentY += prisonerEntryHeight;
                }

                currentY += 4; // Spacing
            }
        }

        return super.mouseClicked(mouseX, mouseY, button);
    }

    @Override
    public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
        if (renameMode) {
            if (keyCode == 257) {
                // Enter
                toggleRenameMode(); // Save
                return true;
            } else if (keyCode == 256) {
                // Escape
                renameMode = false;
                renameBox.setVisible(false);
                renameButton.setMessage(
                    Component.translatable(
                        "gui.tiedup.cell_manager.button.rename"
                    )
                );
                updateButtonStates();
                return true;
            }
        }

        return super.keyPressed(keyCode, scanCode, modifiers);
    }
}
