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.entities.MerchantTrade;
import com.tiedup.remake.network.ModNetwork;
import com.tiedup.remake.network.merchant.PacketPurchaseTrade;
import java.util.List;
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.network.chat.Component;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Items;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

/**
 * Trading screen for EntityKidnapperMerchant.
 * Displays available trades and allows purchasing items for gold.
 */
@OnlyIn(Dist.CLIENT)
public class MerchantTradingScreen extends BaseScreen {

    private final UUID merchantUUID;
    private final List<MerchantTrade> trades;
    private int selectedTradeIndex = -1;

    private Button buyButton;
    private Button cancelButton;

    private static final int TRADE_BUTTON_HEIGHT = 30;
    private static final int TRADE_BUTTON_SPACING = 4;

    // Scroll state
    private int scrollOffset = 0;
    private int maxScrollOffset = 0;
    private int tradeListStartY;
    private int tradeListHeight;

    public MerchantTradingScreen(
        UUID merchantUUID,
        List<MerchantTrade> trades
    ) {
        super(Component.translatable("gui.tiedup.merchant.title"));
        this.merchantUUID = merchantUUID;
        this.trades = trades;
    }

    @Override
    protected int getPreferredWidth() {
        // 60% width, min 320px, max 500px
        return GuiLayoutConstants.getResponsiveWidth(
            this.width,
            0.6f,
            320,
            500
        );
    }

    @Override
    protected int getPreferredHeight() {
        // 70% height, min 300px, max 450px
        return GuiLayoutConstants.getResponsiveHeight(
            this.height,
            0.7f,
            300,
            450
        );
    }

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

        // Gold count area (just below title)
        int goldDisplayY = this.topPos + 25;

        // Trade list area (minimal spacing - only 8px gap)
        this.tradeListStartY = goldDisplayY + 18;
        this.tradeListHeight = this.imageHeight - 80; // Maximum space for trades

        // Calculate max scroll offset
        int totalTradeListHeight =
            trades.size() * (TRADE_BUTTON_HEIGHT + TRADE_BUTTON_SPACING);
        this.maxScrollOffset = Math.max(
            0,
            totalTradeListHeight - tradeListHeight
        );

        // Create trade buttons
        int tradeButtonWidth = this.imageWidth - 40;
        int tradeButtonX = this.leftPos + 20;

        for (int i = 0; i < trades.size(); i++) {
            final int tradeIndex = i;
            MerchantTrade trade = trades.get(i);

            TradeButton button = new TradeButton(
                tradeButtonX,
                0,
                tradeButtonWidth,
                TRADE_BUTTON_HEIGHT,
                trade,
                tradeIndex,
                btn -> onTradeClicked(tradeIndex)
            );
            this.addRenderableWidget(button);
        }

        // Bottom buttons
        int buttonY =
            this.topPos +
            this.imageHeight -
            GuiLayoutConstants.BUTTON_HEIGHT -
            10;
        int buttonSpacing = 10;
        int totalButtonWidth =
            GuiLayoutConstants.BUTTON_WIDTH_L * 2 + buttonSpacing;
        int buttonStartX =
            this.leftPos + (this.imageWidth - totalButtonWidth) / 2;

        // Buy button (disabled by default)
        buyButton = Button.builder(
            Component.translatable("gui.tiedup.merchant.buy"),
            b -> onBuyClicked()
        )
            .bounds(
                buttonStartX,
                buttonY,
                GuiLayoutConstants.BUTTON_WIDTH_L,
                GuiLayoutConstants.BUTTON_HEIGHT
            )
            .build();
        buyButton.active = false;
        this.addRenderableWidget(buyButton);

        // Cancel button
        cancelButton = Button.builder(
            Component.translatable("gui.tiedup.cancel"),
            b -> onClose()
        )
            .bounds(
                buttonStartX +
                    GuiLayoutConstants.BUTTON_WIDTH_L +
                    buttonSpacing,
                buttonY,
                GuiLayoutConstants.BUTTON_WIDTH_L,
                GuiLayoutConstants.BUTTON_HEIGHT
            )
            .build();
        this.addRenderableWidget(cancelButton);
    }

    private void onTradeClicked(int index) {
        selectedTradeIndex = index;
        buyButton.active = true;
    }

    private void onBuyClicked() {
        if (selectedTradeIndex >= 0 && selectedTradeIndex < trades.size()) {
            ModNetwork.sendToServer(
                new PacketPurchaseTrade(merchantUUID, selectedTradeIndex)
            );
            onClose();
        }
    }

    @Override
    public void onClose() {
        // Notify server that we closed the trading screen
        ModNetwork.sendToServer(
            new com.tiedup.remake.network.merchant.PacketCloseMerchantScreen(
                merchantUUID
            )
        );
        super.onClose();
    }

    @Override
    public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
        if (maxScrollOffset > 0) {
            // Scroll by 20 pixels per tick
            int scrollAmount = (int) (delta * 20);
            scrollOffset = Math.max(
                0,
                Math.min(maxScrollOffset, scrollOffset - scrollAmount)
            );
            return true;
        }
        return super.mouseScrolled(mouseX, mouseY, delta);
    }

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

        // Title (blue color for merchant)
        graphics.drawCenteredString(
            this.font,
            this.title,
            this.leftPos + this.imageWidth / 2,
            this.topPos + GuiLayoutConstants.MARGIN_M,
            GuiColors.INFO
        );

        // Gold display (matches goldDisplayY from init)
        Player player = Minecraft.getInstance().player;
        if (player != null) {
            int goldIngots = countItemInInventory(player, Items.GOLD_INGOT);
            int goldNuggets = countItemInInventory(player, Items.GOLD_NUGGET);

            Component goldText = Component.translatable("gui.tiedup.merchant.your_gold")
                .append(
                    Component.translatable("gui.tiedup.merchant.gold_amount", goldIngots).withStyle(style ->
                        style.withColor(0xFFFFD700)
                    )
                )
                .append(
                    Component.translatable("gui.tiedup.merchant.gold_icon").withStyle(style ->
                        style.withColor(0xFFFFD700)
                    )
                )
                .append(
                    Component.translatable("gui.tiedup.merchant.nugget_amount", goldNuggets).withStyle(
                        style -> style.withColor(0xFFFFA500)
                    )
                )
                .append(
                    Component.translatable("gui.tiedup.merchant.nugget_icon").withStyle(style ->
                        style.withColor(0xFFFFA500)
                    )
                );

            graphics.drawCenteredString(
                this.font,
                goldText,
                this.leftPos + this.imageWidth / 2,
                this.topPos + 25,
                GuiColors.TEXT_WHITE
            );
        }

        // Update trade button positions based on scroll
        updateTradeButtonPositions();
    }

    /**
     * Update trade button positions based on scroll offset.
     */
    private void updateTradeButtonPositions() {
        int tradeButtonWidth = this.imageWidth - 40;
        int tradeButtonX = this.leftPos + 20;

        // Get all renderable widgets (includes our trade buttons)
        for (int i = 0; i < this.renderables.size(); i++) {
            if (this.renderables.get(i) instanceof TradeButton tradeButton) {
                int tradeIndex = tradeButton.getTradeIndex();

                // Calculate Y position with scroll offset
                // tradeListStartY already includes topPos, don't add it twice!
                int y =
                    this.tradeListStartY +
                    tradeIndex * (TRADE_BUTTON_HEIGHT + TRADE_BUTTON_SPACING) -
                    scrollOffset;

                // Update button position
                tradeButton.setPosition(tradeButtonX, y);

                // Check if button is visible in the scroll area
                boolean isVisible =
                    y >= this.tradeListStartY &&
                    y + TRADE_BUTTON_HEIGHT <=
                    this.tradeListStartY + this.tradeListHeight;
                tradeButton.visible = isVisible;
            }
        }
    }

    /**
     * Count how many of a specific item are in the player's inventory.
     */
    private int countItemInInventory(
        Player player,
        net.minecraft.world.item.Item item
    ) {
        int count = 0;
        for (net.minecraft.world.item.ItemStack stack : player.getInventory().items) {
            if (stack.is(item)) {
                count += stack.getCount();
            }
        }
        return count;
    }

    /**
     * Custom button for displaying a trade.
     */
    private class TradeButton extends Button {

        private final MerchantTrade trade;
        private final int tradeIndex;

        public TradeButton(
            int x,
            int y,
            int width,
            int height,
            MerchantTrade trade,
            int tradeIndex,
            OnPress onPress
        ) {
            super(
                x,
                y,
                width,
                height,
                Component.empty(),
                onPress,
                DEFAULT_NARRATION
            );
            this.trade = trade;
            this.tradeIndex = tradeIndex;
        }

        public int getTradeIndex() {
            return this.tradeIndex;
        }

        @Override
        public void renderWidget(
            GuiGraphics graphics,
            int mouseX,
            int mouseY,
            float partialTick
        ) {
            boolean selected = (tradeIndex == selectedTradeIndex);
            boolean hovered = this.isHovered();

            // Background color
            int bgColor;
            if (selected) {
                bgColor = GuiColors.SLOT_SELECTED; // Brown for selected
            } else if (hovered) {
                bgColor = GuiColors.SLOT_HOVER;
            } else {
                bgColor = GuiColors.BG_LIGHT;
            }

            graphics.fill(
                getX(),
                getY(),
                getX() + width,
                getY() + height,
                bgColor
            );

            // Border
            int borderColor = selected
                ? GuiColors.ACCENT_TAN
                : GuiColors.BORDER_LIGHT;
            graphics.fill(
                getX(),
                getY(),
                getX() + width,
                getY() + 1,
                borderColor
            );
            graphics.fill(
                getX(),
                getY() + height - 1,
                getX() + width,
                getY() + height,
                borderColor
            );
            graphics.fill(
                getX(),
                getY(),
                getX() + 1,
                getY() + height,
                borderColor
            );
            graphics.fill(
                getX() + width - 1,
                getY(),
                getX() + width,
                getY() + height,
                borderColor
            );

            // Item preview (left side)
            net.minecraft.world.item.ItemStack itemStack = trade.getItem();
            graphics.renderItem(itemStack, getX() + 5, getY() + 7);

            // Item name (after item preview)
            Component itemName = trade.getItemName();
            String itemText = font.plainSubstrByWidth(
                itemName.getString(),
                width - 140
            );
            graphics.drawString(
                font,
                itemText,
                getX() + 28,
                getY() + 5,
                GuiColors.TEXT_WHITE
            );

            // Price (after item name, below item preview)
            Component priceText = trade.getPriceDisplay();
            graphics.drawString(
                font,
                priceText,
                getX() + 28,
                getY() + 17,
                GuiColors.TEXT_GRAY
            );
        }
    }
}
