require("ISUI/ISUIElement")
require "REInterface_Config"
local TetrisContainerData = require("InventoryTetris/Data/TetrisContainerData")
local TetrisItemCategory = require("InventoryTetris/Data/TetrisItemCategory")
local OPT = require("InventoryTetris/Settings")
local DragAndDrop = require("InventoryTetris/System/DragAndDrop")
local NotlocControllerNode = require("InventoryTetris/UI/NotlocControllerNode")
local ItemGridUI = require("InventoryTetris/UI/Grid/ItemGridUI")
local TetrisDevTool = require("InventoryTetris/Dev/TetrisDevTool")

local ICON_PADDING_X = 12
local ICON_PADDING_Y = 8
local ICON_SIZE = 64

local WEIGHT_TEXTURE = getTexture("media/textures/InventoryTetris/weight.png")
local SELECTED_TEXTURE = getTexture("media/ui/FavoriteStar.png")
local UNKNOWN_WEIGHT = "?"

local textManager = getTextManager()
local mediumFont = UIFont.Medium

local GridContainerInfo = ISUIElement:derive("GridContainerInfo")

function GridContainerInfo:new(containerUi)
    local o = ISUIElement:new(0,0, 500, 500)
    setmetatable(o, self)
    self.__index = self

    o.containerUi = containerUi
    return o
end

function GridContainerInfo:createChildren()
    NotlocControllerNode
        :injectControllerNode(self)
        :doSimpleFocusHighlight()
        :setJoypadDownHandler(self.controllerNodeOnJoypadDown)
end

local function getWeightColor(weight, capacity)
    local ratio = weight / capacity
    if ratio <= 1.0 then
        return 1,1,1
    elseif ratio <= 1.25 then
        return 1,1,0
    elseif ratio <= 1.5 then 
        return 1,0.3,0
    elseif ratio <= 1.75 then
        return 1,0,0
    else 
        return 0.6,0,0
    end
end

function GridContainerInfo:prerender()
    local containerUi = self.containerUi
    local inv = containerUi.inventory
    local scale = OPT.CONTAINER_INFO_SCALE

    local r,g,b = 1,1,1
    if containerUi.item then
        r,g,b = ItemGridUI.getItemColor(containerUi.item, 0.5)
    end

    -- Icon center based on ICON_SIZE + padding (same as original)
    local offsetX = (ICON_SIZE * 0.5 + ICON_PADDING_X) * scale
    local offsetY = (ICON_SIZE * 0.5 + ICON_PADDING_Y) * scale

    ------------------------------------------------------------
    -- Dark background: EXACTLY matches the slot's white border
    -- (uses self.width / self.height so it stays correct if
    --  the UI or slot size ever changes)
    ------------------------------------------------------------
    local isVisible =
        not containerUi.collapsed
        and containerUi:isVisible()

    if _G.REHUD_cfg and _G.REHUD_cfg.containerBG and isVisible then
        -- Fill the whole slot area
        self:drawRect(0, 0, self.width, self.height, 0.55, 0, 0, 0)
        -- Border is drawn once at the end of this function,
        -- so we do NOT draw another border here.
    end

    -- Icon still draws always, centered in the slot
    self:drawTextureCenteredAndSquare(
        containerUi.invTexture,
        offsetX,
        offsetY + 4,
        ICON_SIZE * scale,
        1,
        r, g, b
    )

    local topIconY = 3 * scale

    local gridUis = containerUi.gridUis[inv]
    local containerDef = gridUis[1].grid.containerDefinition
    local category = TetrisContainerData.getSingleValidCategory(containerDef)
    if category then
        local icon = TetrisItemCategory.getCategoryIcon(category)
        self:drawTextureScaledAspect(
            icon,
            self.width - (18 * scale),
            topIconY,
            16 * scale,
            16 * scale,
            1, 1, 1, 1
        )
    end

    local isSelected = containerUi.isOnPlayer
        and containerUi.inventory == containerUi.inventoryPane.inventory
    if isSelected then
        local tx = SELECTED_TEXTURE:getWidth() * scale
        local ty = SELECTED_TEXTURE:getHeight() * scale
        self:drawTextureScaled(SELECTED_TEXTURE, 4, topIconY + 2, tx, ty, 1, 1, 1, 1)
    end

    local player = self.containerUi.player

    local realWeight
    local capacity

    -- PLAYER INVENTORY USES TRUE TETRIS PLAYER WEIGHT
    if containerUi.isPlayerInventory then
        realWeight = player:getInventoryWeight()
        capacity   = player:getMaxWeight()
    -- ALL OTHER CONTAINERS USE TETRIS CONTAINER WEIGHT
    else
        realWeight = inv:getCapacityWeight()
        capacity   = math.floor(containerUi.containerGrid:_getCapacity(player))
    end

    -- Round weight AFTER override
    local roundedWeight = round(realWeight, 1)

    -- Search mode override ("?")
    if SandboxVars.InventoryTetris.EnableSearch
        and self.containerUi.containerGrid:areAnyUnsearched() then
        roundedWeight = UNKNOWN_WEIGHT
    end

    ------------------------------------------------------------
    -- Respect sandbox option: InventoryTetris.EnforceCarryWeight
    ------------------------------------------------------------
    local showFull = SandboxVars.InventoryTetris.EnforceCarryWeight == true

    if showFull then
        -- user wants full display everywhere
        self.weightText = string.format("%s / %s", roundedWeight, capacity)
    else
        -- user wants minimal display (only weight)
        self.weightText = tostring(roundedWeight)
    end

    -- Color logic only for player inventory
    local wr,wg,wb = 1,1,1
    if containerUi.isPlayerInventory then
        wr,wg,wb = getWeightColor(realWeight, capacity)
    end

    -- Place text centered under the slot, based on the slot size
	local centerX = offsetX           -- anchor X to icon center
	local textY   = offsetY + (ICON_SIZE * 0.5 * scale) + (4 * scale)

    self:drawTextCentre(self.weightText, centerX, textY, wr, wg, wb, 1, mediumFont)

    local lineHeight = textManager:getFontFromEnum(mediumFont):getLineHeight()
    local lineWidth  = textManager:MeasureStringX(mediumFont, self.weightText)

    local weightXOff = 2
    local weightYOff = 0
    if wg == 0 then
        weightXOff = weightXOff + ZombRand(-1 / wr, 1 / wr)
        weightYOff = weightYOff + ZombRand(-1 / wr, 1 / wr)
    end

    local weightX = centerX + lineWidth * 0.5 + weightXOff * scale
    local weightY = textY + lineHeight * 0.75 + weightYOff - (8 * scale) - 2
    if wr == 1 and wg == 1 and wb == 1 then
        self:drawTextureScaledUniform(WEIGHT_TEXTURE, weightX, weightY, scale, 1, 1, 0.92, 0.75)
    else
        self:drawTextureScaledUniform(
            WEIGHT_TEXTURE,
            weightX,
            weightY,
            scale,
            1,
            math.max(wr * 0.65, 0.4),
            wg * 0.65,
            wb * 0.65
        )
    end

    -- This is the slot white border we’re matching with the BG fill
    self:drawRectBorder(0, 0, self.width, self.height, 0.5, 1, 1, 1)
end

local function isPointOverContainerIcon(x, y)
    local scale = OPT.CONTAINER_INFO_SCALE
    return x > ICON_PADDING_X * scale and x < (ICON_SIZE + ICON_PADDING_X) * scale  and y > ICON_PADDING_Y * scale and y < (ICON_SIZE + ICON_PADDING_Y) * scale
end

function GridContainerInfo:onRightMouseUp(x, y)
    local menu
    if self.containerUi.item and isPointOverContainerIcon(x, y) then
        menu = ItemGridUI.openItemContextMenu(self, x, y, self.containerUi.item, self.containerUi.inventoryPane, self.containerUi.playerNum)
    else
        menu = ISContextMenu.get(0, getMouseX(), getMouseY());
    end
    TetrisDevTool.insertDebugOptions(menu, self.containerUi.item, self.containerUi.inventory, self.containerUi)
end

function GridContainerInfo:onMouseDown(x, y)
    if self.containerUi.item and isPointOverContainerIcon(x, y) then
        local vanillaStack = DragAndDrop.convertItemToStack(self.containerUi.item)
        DragAndDrop.prepareDrag(self, vanillaStack, x, y)
    end
end

function GridContainerInfo:onMouseMove(dx, dy)
    if self.containerUi.item then
        DragAndDrop.startDrag(self)
    end
end

function GridContainerInfo:onMouseMoveOutside(dx, dy)
    if self.containerUi.item then
        DragAndDrop.startDrag(self)
    end
end

function GridContainerInfo:onMouseUp(x, y)
    local stacks = DragAndDrop.getDraggedStacks()
    if stacks then
        if stacks.items then
            stacks = {stacks}
        end

        if stacks and #stacks > 0 then
            for _, stack in ipairs(stacks) do
                local item = stack.items[1]
                local playerObj = getSpecificPlayer(self.containerUi.playerNum)
                if self.containerUi.containerGrid:canAddItem(item) then
                    for i=2, #stack.items do
                        local item = stack.items[i]
                        ISTimedActionQueue.add(ISInventoryTransferAction:new(playerObj, item, item:getContainer(), self.containerUi.inventory))
                    end
                end
            end
        end
    end
    DragAndDrop.endDrag(self)
end

function GridContainerInfo:onMouseDoubleClick(x, y)
    if self.containerUi.item and isPointOverContainerIcon(x, y) then
        self.containerUi.inventoryPane.tetrisWindowManager:openContainerPopup(self.containerUi.item, self.containerUi.inventoryPane)
    end
    DragAndDrop.endDrag(self)
end

function GridContainerInfo:onMouseUpOutside(x, y)
    if self.containerUi.item then
        DragAndDrop.cancelDrag(self, self.cancelDragDropItem)
    end
end

function GridContainerInfo:cancelDragDropItem()
    local stack = DragAndDrop.getDraggedStack()
    if not stack or not stack.items then return end

    local item = stack.items[1]
    if not item then return end

    if not ISUIElement.isMouseOverAnyUI() then
        ISInventoryPaneContextMenu.dropItem(item, self.containerUi.playerNum)
    end
end

function GridContainerInfo:controllerNodeOnJoypadDown(button)
    if button == Joypad.BButton then
        self.containerUi:onCollapseButtonClick()
        self.containerUi.inventoryPane:refreshContainer()
        return true
    end

    if button == Joypad.AButton then
        if self.containerUi.item then
            local menu = ItemGridUI.openItemContextMenu(self, 10, 10, self.containerUi.item, self.containerUi.inventoryPane, self.containerUi.playerNum)
            TetrisDevTool.insertDebugOptions(menu, self.containerUi.item, self.containerUi.inventory, self.containerUi)

        end
        return true
    end
end

return GridContainerInfo
