-- ResizeFix.lua
-- Fixes ISInventoryPane, ISInventoryPage, and ISScrollBar resizing issues for RE Tetris UI [B42]

local Logger = require("Utils/Logger")
local ResizeFix = {}

function ResizeFix.apply()
    Logger.log("Applying Resize Fix patches...")

    if not ISInventoryPane or not ISInventoryPage then
        Logger.log("Required classes not yet available", "RETRY")
        return false
    end

    local patchesApplied = 0
    local totalPatches = 3

    ----------------------------------------------------------
    -- Patch 1 : ISInventoryPane Full Lifecycle
    ----------------------------------------------------------
    do
        Logger.debug("Applying Patch 1 – ISInventoryPane lifecycle...")

        local og_new = ISInventoryPane.new
        function ISInventoryPane:new(x, y, w, h, inv, zoom)
            local o = og_new(self, x, y, w, h, inv, zoom)
            o.anchorLeft, o.anchorRight, o.anchorTop, o.anchorBottom = true, true, true, true
            return o
        end

        local og_createChildren = ISInventoryPane.createChildren
        function ISInventoryPane:createChildren()
            og_createChildren(self)
            if self.scrollView then
                self.scrollView.anchorLeft = true
                self.scrollView.anchorRight = true
                self.scrollView.anchorTop = true
                self.scrollView.anchorBottom = true
                self.scrollView:setX(0)
                self.scrollView:setY(0)
                self.scrollView:setWidth(self.width)
                self.scrollView:setHeight(self.height)
                if self.vscroll then
                    self.vscroll:setHeight(self.height)
                    self.vscroll:setX(self.width - 17)
                    self.vscroll:bringToTop()
                end
                if self.hscroll then
                    self.hscroll:setWidth(self.width)
                    self.hscroll:setY(self.height - 17)
                    self.hscroll:bringToTop()
                end
                if self.scrollView.vscroll then self.scrollView.vscroll:bringToTop() end
                if self.scrollView.hscroll then self.scrollView.hscroll:bringToTop() end
            end
        end

        if not ISInventoryPane._originalSetWidth then ISInventoryPane._originalSetWidth = ISInventoryPane.setWidth end
        if not ISInventoryPane._originalSetHeight then ISInventoryPane._originalSetHeight = ISInventoryPane.setHeight end

        function ISInventoryPane:setWidth(w)
            ISInventoryPane._originalSetWidth(self, w)
            if self.scrollView then self.scrollView:setWidth(w) end
            if self.vscroll then self.vscroll:setX(w - 17) end
            if self.hscroll then self.hscroll:setWidth(w) end
        end

        function ISInventoryPane:setHeight(h)
            ISInventoryPane._originalSetHeight(self, h)
            if self.scrollView then self.scrollView:setHeight(h) end
            if self.vscroll then self.vscroll:setHeight(h) end
            if self.hscroll then self.hscroll:setY(h - 17) end
        end

        local og_prerender = ISInventoryPane.prerender
        function ISInventoryPane:prerender()
            if self.vscroll then
                self.vscroll:bringToTop()
                if math.abs(self.vscroll.height - self.height) > 2 then
                    self.vscroll:setHeight(self.height)
                end
            end
            if self.scrollView then
                if self.scrollView.vscroll then
                    self.scrollView.vscroll:bringToTop()
                    local expectedX = self.scrollView.width - 17
                    if math.abs(self.scrollView.vscroll.x - expectedX) > 2 then
                        self.scrollView.vscroll:setX(expectedX)
                    end
                end
                if self.scrollView.hscroll then
                    self.scrollView.hscroll:bringToTop()
                    local expectedY = self.scrollView.height - 17
                    if math.abs(self.scrollView.hscroll.y - expectedY) > 2 then
                        self.scrollView.hscroll:setY(expectedY)
                    end
                end
            end
            og_prerender(self)
        end

        patchesApplied = patchesApplied + 1
        Logger.debug("Patch 1/3 complete.")
    end

    ----------------------------------------------------------
    -- Patch 2 : ISInventoryPage Full Lifecycle
    ----------------------------------------------------------
    do
        Logger.debug("Applying Patch 2 – ISInventoryPage lifecycle...")

        local og_createChildren = ISInventoryPage.createChildren
        function ISInventoryPage:createChildren()
            og_createChildren(self)
            if self.inventoryPane then
                self.inventoryPane.anchorLeft = true
                self.inventoryPane.anchorRight = true
                self.inventoryPane.anchorTop = true
                self.inventoryPane.anchorBottom = true
                local titleBarHeight = self:titleBarHeight()
                local rh = math.floor((getTextManager():getFontHeight(UIFont.Small) + 6) / 2 + 1)
                local bottomSpace = rh + (self.controlsUI and self.controlsUI.height or 0)
                local height = self.height - titleBarHeight - bottomSpace
                self.inventoryPane:setHeight(height)
            end
        end

        local og_prerender = ISInventoryPage.prerender
        function ISInventoryPage:prerender()
            local p = getPlayer()
            if not p or p:isDead() or not self.inventoryPane then return end
            if self.controlsUI and self.controlsUI.arrange then self.controlsUI:arrange() end
            if self.containerButtonPanel and self.inventoryPane then
                self.containerButtonPanel:setHeight(self.inventoryPane.height)
                self.containerButtonPanel:setY(self.inventoryPane.y)
            end
            og_prerender(self)
        end

        local og_update = ISInventoryPage.update
        function ISInventoryPage:update()
            local p = getPlayer()
            if not p or p:isDead() or not self.inventoryPane then return end
            og_update(self)
            local expectedWidth = self.width - self.buttonSize
            if math.abs(self.inventoryPane.width - expectedWidth) > 3 then
                self.inventoryPane:setWidth(expectedWidth)
            end
        end

        local og_onSize = ISInventoryPage.onInventoryContainerSizeChanged
        function ISInventoryPage:onInventoryContainerSizeChanged()
            if og_onSize then og_onSize(self) end
            if self.inventoryPane then
                local titleBarHeight = self:titleBarHeight()
                local rh = math.floor((getTextManager():getFontHeight(UIFont.Small) + 6) / 2 + 1)
                local bottomSpace = rh + (self.controlsUI and self.controlsUI.height or 0)
                local height = self.height - titleBarHeight - bottomSpace
                self.inventoryPane:setHeight(height)
            end
        end

        local og_render = ISInventoryPage.render
        function ISInventoryPage:render()
            local p = getPlayer()
            if not p or p:isDead() or not self.inventoryPane then return end
            local expectedWidth = self.width - self.buttonSize
            if math.abs(self.inventoryPane.width - expectedWidth) > 5 then
                self.inventoryPane:setWidth(expectedWidth)
            end
            if self.inventoryPane.scrollView then
                if math.abs(self.inventoryPane.scrollView.width - self.inventoryPane.width) > 5 then
                    self.inventoryPane.scrollView:setWidth(self.inventoryPane.width)
                end
                if math.abs(self.inventoryPane.scrollView.height - self.inventoryPane.height) > 5 then
                    self.inventoryPane.scrollView:setHeight(self.inventoryPane.height)
                end
            end
            og_render(self)
        end

        patchesApplied = patchesApplied + 1
        Logger.debug("Patch 2/3 complete.")
    end

    ----------------------------------------------------------
    -- Patch 3 : ISScrollBar Visibility Fix
    ----------------------------------------------------------
    do
        local og_scrollRender = ISScrollBar.render
        function ISScrollBar:render()
            local effParent = self.parent and self.parent.scrollView or self.parent
            local old = self.parent
            self.parent = effParent
            og_scrollRender(self)
            self.parent = old
        end
        patchesApplied = patchesApplied + 1
        Logger.debug("Patch 3/3 complete.")
    end

    ----------------------------------------------------------
    -- Verification
    ----------------------------------------------------------
    if patchesApplied == totalPatches then
        Logger.success("All " .. patchesApplied .. " patches applied successfully.")
        return true
    else
        Logger.error("Only " .. patchesApplied .. "/" .. totalPatches .. " patches applied.")
        return false
    end
end

return ResizeFix
