--***********************************************************
--** TM_SidebarTrapButton.lua                              **
--***********************************************************
-- Adds a hover "slide-out" popup next to the left sidebar Zone icon.
-- Safe: does not edit vanilla or third-party files; only wraps ISEquippedItem methods.

require "ISUI/ISPanel"
require "ISUI/ISToolTip"
require "ISUI/ISEquippedItem"

if not ISPanel or not ISEquippedItem then return end

------------------------------------------------------------
-- Mod presence detection
------------------------------------------------------------
local function TM_isModActive(modID)
    local activeModIDs = getActivatedMods()
    if not activeModIDs then return false end
    for i = 0, activeModIDs:size() - 1 do
        local id = activeModIDs:get(i)
        if id and (id == modID or id:contains(modID)) then return true end
    end
    return false
end

-- Flags: other mods that interact with zoneBtn
TM_isLivestockZonesExpandedActive = TM_isModActive("WeeezLivestockZonesExpanded")
TM_isHomeInventoryImprovedActive  = TM_isModActive("cf_home")

------------------------------------------------------------
-- Size helpers
------------------------------------------------------------
local function TM_getTextureWidth()
    -- Mirrors vanilla sidebar sizing (including "auto"=6 derived from font size)
    local size = getCore():getOptionSidebarSize()
    if size == 6 then
        size = getCore():getOptionFontSizeReal() - 1
    end
    local TW = 48
    if     size == 2 then TW = 64
    elseif size == 3 then TW = 80
    elseif size == 4 then TW = 96
    elseif size == 5 then TW = 128
    end
    return TW
end

-- Horizontal spacing (px) between buttons:
-- When Home is active: widen the gap (prevents visual crowding).
-- When Home is not active: tighten the gap (brings Trap closer to Zone).
local TRAP_GAP_HOME   = 17  -- Home -> Trap
local TRAP_GAP_NOHOME = 7   -- Zone -> Trap (when Home is absent)

------------------------------------------------------------
-- Window state helper: is Trap Manager window open/visible?
------------------------------------------------------------
local function TM_IsTrapWindowOpen()
    local inst = TrapManagerWindow and TrapManagerWindow.instance
    if inst and inst.getIsVisible then
        local ok, vis = pcall(inst.getIsVisible, inst)
        if ok and vis then return true end
    end
    return false
end

------------------------------------------------------------
-- Small transparent popup panel anchored to zoneBtn
------------------------------------------------------------
TM_TrapPopup = ISPanel:derive("TM_TrapPopup")

function TM_TrapPopup:new(x, y, w, h, chr)
    local o = ISPanel.new(self, x, y, w, h)
    o:setAnchorLeft(true); o:setAnchorRight(false)
    o:setAnchorTop(true);  o:setAnchorBottom(false)
    o.background = false
    o.borderColor = { r=0, g=0, b=0, a=0 }
    o.chr = chr

    -- Base texture slot size (scaled by sidebar size)
    o.TEXTURE_WIDTH  = math.floor((w > 0) and (w / 2) or TM_getTextureWidth())
    o.TEXTURE_HEIGHT = math.floor(o.TEXTURE_WIDTH * 0.75)

    -- Trap icons (off/on)
    o.trapIconOff = getTexture("media/ui/trapOFF.png")
    o.trapIconOn  = getTexture("media/ui/trapON.png")

    -- Tooltip widget
    o.tooltip = ISToolTip:new()
    o.tooltip:initialise()
    o.tooltip:setVisible(false)

    -- Geometry state (filled each prerender)
    o.homeActive     = false       -- true when Home popup is present
    o.trapXRel       = nil         -- trap left X relative to zoneBtn left
    o.panelW         = nil         -- total panel width (for hitbox & visibility)
    o.homeLeftRel    = nil         -- Home left relative to zone
    o.homeWidth      = nil         -- Home width (panel/texture width)

    -- Owner (ISEquippedItem instance) set by creator
    o.owner = nil
    return o
end

-- Draw Trap icon at its computed relative X (no overlap with Home)
function TM_TrapPopup:render()
    local TW  = self.TEXTURE_WIDTH
    local TH  = self.TEXTURE_HEIGHT

    -- Preferred geometry from prerender; fallback to safe defaults
    local trapX = self.trapXRel
    local wantW = self.panelW
    if not trapX or not wantW then
        if self.homeActive then
            trapX = (TW * 2) + TRAP_GAP_HOME
            wantW = trapX + TW
        else
            trapX = TW + TRAP_GAP_NOHOME
            wantW = trapX + TW
        end
    end

    if self.width ~= wantW then self:setWidth(wantW) end
    if self.height ~= TH then self:setHeight(TH) end

    local isOpen = TM_IsTrapWindowOpen()
    local tex = (isOpen and self.trapIconOn) or self.trapIconOff
    if tex then
        self:drawTextureScaled(tex, trapX, 0, TW, TH, 1, 1, 1, 1)
    end
end

------------------------------------------------------------
-- Tooltip helpers
------------------------------------------------------------
function TM_TrapPopup:showTooltip(text)
    if not text then return end
    self.tooltip.description = text
    -- Only add to UI when transitioning from hidden -> visible
    if not self.tooltip:getIsVisible() then
        self.tooltip:setVisible(true)
        self.tooltip:addToUIManager()
    end
    self.tooltip:setX(getMouseX() + 16)
    self.tooltip:setY(getMouseY() + 16)
end

function TM_TrapPopup:hideTooltip()
    if self.tooltip and self.tooltip:getIsVisible() then
        self.tooltip:setVisible(false)
        self.tooltip:removeFromUIManager()
    end
end

-- Tooltips use real geometry (no ghost areas)
function TM_TrapPopup:onMouseMove(dx, dy)
    local TW  = self.TEXTURE_WIDTH
    local x   = self:getMouseX()
    local trapX = self.trapXRel
    if not trapX then
        trapX = (self.homeActive and (TW * 2 + TRAP_GAP_HOME)) or (TW + TRAP_GAP_NOHOME)
    end

    -- Zone area: [0, TW)
    if x >= 0 and x < TW then
        self:showTooltip(getText("IGUI_Zone_Name") or "Zones")
        return true
    end

    -- Home area: [homeLeftRel, homeLeftRel + homeWidth) ONLY when active
    if self.homeActive and self.homeLeftRel and self.homeWidth then
        local hx1, hx2 = self.homeLeftRel, self.homeLeftRel + self.homeWidth
        if x >= hx1 and x < hx2 then
            self:showTooltip(getText("UI_CFN_Home_ItemPanelTitle") or "Home Inventory")
            return true
        end
    end

    -- Trap area: [trapX, trapX + TW)
    if x >= trapX and x < trapX + TW then
        self:showTooltip(getText("UI_TM_Title") or "Trap Manager")
    else
        self:hideTooltip()
    end
    return true
end

function TM_TrapPopup:onMouseMoveOutside(dx, dy)
    -- Hide and remove from UI to avoid any oversized box lingering
    self:hideTooltip()
    return true
end

-- Use LEFT CLICK for actions (Zones / Home / Trap)
function TM_TrapPopup:onMouseUp(mx, my)
    self:hideTooltip()
    local TW  = self.TEXTURE_WIDTH
    local trapX = self.trapXRel
    if not trapX then
        trapX = (self.homeActive and (TW * 2 + TRAP_GAP_HOME)) or (TW + TRAP_GAP_NOHOME)
    end
    -- Create a local alias so future transforms are easy (e.g., absolute->relative)
    local x = mx

    -- Zone click
    if x >= 0 and x < TW then
        self:_openZones()
        return true
    end

    -- Home click (if active)
    if self.homeActive and self.homeLeftRel and self.homeWidth then
        local hx1, hx2 = self.homeLeftRel, self.homeLeftRel + self.homeWidth
        if x >= hx1 and x < hx2 then
            self:_toggleHome()
            return true
        end
    end

    -- Trap click
    if x >= trapX and x < trapX + TW then
        if TrapManagerWindow and TrapManagerWindow.OnOpenPanel then
            TrapManagerWindow.OnOpenPanel()
        end
        return true
    end

    return true
end

-- Keep popup visible while any related window is open
function TM_TrapPopup:isAnyWindowOpen()
    local trapOpen = TM_IsTrapWindowOpen()
    local homeOpen = false
    if TM_isHomeInventoryImprovedActive and CFN and CFN.Home and CFN.Home.Exist then
        local ok, val = pcall(CFN.Home.Exist)
        homeOpen = ok and val or false
    end
    return trapOpen or homeOpen
end

-- Open Zones with priority: Livestock (if available) > vanilla
function TM_TrapPopup:_openZones()
    local pn = self.playerNum or 0
    if TM_isLivestockZonesExpandedActive and ISEntityUI and ISEntityUI.OpenLivestockZones then
        pcall(ISEntityUI.OpenLivestockZones, self.chr, nil)
        return
    end
    if ISDesignationZonePanel and ISDesignationZonePanel.toggleZoneUI then
        pcall(ISDesignationZonePanel.toggleZoneUI, pn)
    end
    if ISAnimalZoneFirstInfo and ISAnimalZoneFirstInfo.showUI then
        pcall(ISAnimalZoneFirstInfo.showUI, pn, false)
    end
end

-- Toggle Home Inventory Improved UI (if exposed)
function TM_TrapPopup:_toggleHome()
    if not TM_isHomeInventoryImprovedActive then return end
    if CFN and CFN.Home then
        if CFN.Home.Toggle then
            pcall(CFN.Home.Toggle, self.chr)
            return
        end
        if self.owner and self.owner.tmHomePopup and self.owner.tmHomePopup.toggle then
            pcall(self.owner.tmHomePopup.toggle, self.owner.tmHomePopup)
            return
        end
        if CFN.Home.Open then
            pcall(CFN.Home.Open, self.chr)
            return
        end
    end
end

------------------------------------------------------------
-- Wrap/extend ISEquippedItem to attach popups and logic
------------------------------------------------------------
local _orig_init = ISEquippedItem.initialise
local _orig_pre  = ISEquippedItem.prerender
local _orig_rm   = ISEquippedItem.removeFromUIManager
local _orig_chk  = ISEquippedItem.checkSidebarSizeOption

-- 1) Create/attach popups in initialise (after vanilla builds buttons)
function ISEquippedItem:initialise(...)
    _orig_init(self, ...)

    -- Only attach for main player 0 (matches vanilla pattern)
    if not self.chr or self.chr:getPlayerNum() ~= 0 then return end
    if not self.zoneBtn or self.tmTrapPopup then return end

    local TW = TM_getTextureWidth()
    local TH = math.floor(TW * 0.75)

    -- Anchor popup at absolute position of zoneBtn (screen space)
    local absX = self:getAbsoluteX() + self.zoneBtn:getX()
    local absY = self:getAbsoluteY() + self.zoneBtn:getY()

    -- Width will be adjusted in prerender/render
    self.tmTrapPopup = TM_TrapPopup:new(absX, absY, TW * 2, TH, self.chr)
    self.tmTrapPopup.owner = self
    self.tmTrapPopup.playerNum = self.chr:getPlayerNum()
    self.tmTrapPopup:initialise()
    self.tmTrapPopup:addToUIManager()
    self.tmTrapPopup:setVisible(false)

    -- Integrate Home Inventory Improved, if active:
    -- - Remove its original zonePopup to avoid duplicates.
    -- - Create/attach its Entry panel adjacent to zoneBtn (to the right using the mod's offset model).
    if TM_isHomeInventoryImprovedActive then
        if self.zonePopup and self.zonePopup.removeFromUIManager then
            self.zonePopup:removeFromUIManager()
            self.zonePopup = nil
        end
        if CFN and CFN.Home and CFN.Home.Panels and CFN.Home.Panels.Entry then
            local GAP = (CFN and CFN.Home and CFN.Home.PopupOffset) or 5
            local homeLeft = absX + TW - GAP -- Home aligns "over" zone width minus GAP
            self.tmHomePopup = CFN.Home.Panels.Entry:new(homeLeft, absY, self.chr)
            if self.tmHomePopup.initialise then self.tmHomePopup:initialise() end
            if self.tmHomePopup.addToUIManager then self.tmHomePopup:addToUIManager() end
            if self.tmHomePopup.setVisible then self.tmHomePopup:setVisible(false) end
        end
    end
end

-- 2) Keep positions/sizes in sync; control visibility on combined hitbox
function ISEquippedItem:prerender(...)
    _orig_pre(self, ...)

    if self.tmTrapPopup and self.zoneBtn then
        -- --- Geometry (absolute/screen coordinates) ---
        local TW = TM_getTextureWidth()
        local TH = math.floor(TW * 0.75)
        local GAP = (CFN and CFN.Home and CFN.Home.PopupOffset) or 5

        local zoneX = self:getAbsoluteX() + self.zoneBtn:getX()
        local zoneY = self:getAbsoluteY() + self.zoneBtn:getY()

        -- Anchor TM popup at zone (we draw relatively inside)
        if self.tmTrapPopup.x ~= zoneX or self.tmTrapPopup.y ~= zoneY then
            self.tmTrapPopup:setX(zoneX); self.tmTrapPopup:setY(zoneY)
        end
        if self.tmTrapPopup.TEXTURE_WIDTH ~= TW or self.tmTrapPopup.TEXTURE_HEIGHT ~= TH then
            self.tmTrapPopup.TEXTURE_WIDTH  = TW
            self.tmTrapPopup.TEXTURE_HEIGHT = TH
        end

        -- Is Home active (and panel created)?
        local homeActive = TM_isHomeInventoryImprovedActive and self.tmHomePopup ~= nil
        self.tmTrapPopup.homeActive = homeActive

        -- Compute real left/right edges
        local zoneLeft, zoneRight = zoneX, zoneX + TW
        local trapLeftAbs, panelRightAbs

        if homeActive then
            -- Prefer Home panel's real width if available (more accurate hit-test)
            local homeLeftAbs  = zoneRight - GAP
            local homeW = TW
            if self.tmHomePopup and self.tmHomePopup.getWidth then
                local w = self.tmHomePopup:getWidth()
                if type(w) == "number" and w > 0 then homeW = w end
            elseif CFN and CFN.Home and CFN.Home.Utils and CFN.Home.Utils.GetTextureDimension then
                local ok,w,h = pcall(CFN.Home.Utils.GetTextureDimension)
                if ok and type(w)=="number" and w>0 then homeW = w end
            end
            local homeRightAbs = homeLeftAbs + homeW

            -- Place Trap: left = homeRight + TRAP_GAP_HOME (wider separation)
            trapLeftAbs    = homeRightAbs + TRAP_GAP_HOME
            panelRightAbs  = trapLeftAbs + TW

            -- Keep Home panel aligned where the mod expects
            if self.tmHomePopup:getX() ~= homeLeftAbs or self.tmHomePopup:getY() ~= zoneY then
                self.tmHomePopup:setX(homeLeftAbs); self.tmHomePopup:setY(zoneY)
            end

            -- Store Home relative geometry for accurate tooltips/clicks
            self.tmTrapPopup.homeLeftRel = homeLeftAbs - zoneX
            self.tmTrapPopup.homeWidth   = homeW
        else
            -- No Home: Trap sits to the right of Zone with TRAP_GAP_NOHOME
            trapLeftAbs   = zoneRight + TRAP_GAP_NOHOME
            panelRightAbs = trapLeftAbs + TW

            -- Clear Home geometry
            self.tmTrapPopup.homeLeftRel = nil
            self.tmTrapPopup.homeWidth   = nil
        end

        -- Store relative X for TM popup renderer and set panel width (used for hitbox & visibility)
        self.tmTrapPopup.trapXRel = trapLeftAbs - zoneX
        self.tmTrapPopup.panelW   = panelRightAbs - zoneX
        self.tmTrapPopup:setWidth(self.tmTrapPopup.panelW)
        self.tmTrapPopup:setHeight(TH)

        -- Combined visibility area (zone + home + trap + defined gaps)
        local areaLeft  = zoneLeft
        local areaRight = panelRightAbs
        local areaTop   = zoneY
        local areaBot   = zoneY + TH

        local mx, my = getMouseX(), getMouseY()
        local insideArea = (mx >= areaLeft and mx < areaRight and my >= areaTop and my < areaBot)

        local anyOpen = self.tmTrapPopup:isAnyWindowOpen()
        local show = (insideArea or anyOpen) and (getCore():getGameMode() ~= "Tutorial")

        self.tmTrapPopup:setVisible(show)
        if self.tmHomePopup then self.tmHomePopup:setVisible(show and homeActive) end
        if not show then self.tmTrapPopup:hideTooltip() end
    end
end

-- 3) Cleanup on removal
function ISEquippedItem:removeFromUIManager(...)
    if self.tmHomePopup and self.tmHomePopup.removeFromUIManager then
        self.tmHomePopup:removeFromUIManager()
        self.tmHomePopup = nil
    end
    if self.tmTrapPopup then
        self.tmTrapPopup:removeFromUIManager()
        self.tmTrapPopup = nil
    end
    _orig_rm(self, ...)
end

-- 4) React to sidebar size changes (rescale popups and re-anchor)
function ISEquippedItem:checkSidebarSizeOption(...)
    _orig_chk(self, ...)

    if self.tmTrapPopup and self.zoneBtn then
        local TW = TM_getTextureWidth()
        local TH = math.floor(TW * 0.75)

        -- Resize trap popup
        self.tmTrapPopup.TEXTURE_WIDTH  = TW
        self.tmTrapPopup.TEXTURE_HEIGHT = TH

        -- Re-apply textures (engine scales 128px textures fine)
        self.tmTrapPopup.trapIconOn  = getTexture("media/ui/trapON.png")
        self.tmTrapPopup.trapIconOff = getTexture("media/ui/trapOFF.png")

        -- Re-anchor to the Zone button absolute position
        local absX = self:getAbsoluteX() + self.zoneBtn:getX()
        local absY = self:getAbsoluteY() + self.zoneBtn:getY()
        self.tmTrapPopup:setX(absX)
        self.tmTrapPopup:setY(absY)

        -- Re-anchor Home popup if present (using the mod's offset model)
        if self.tmHomePopup and TM_isHomeInventoryImprovedActive then
            local GAP = (CFN and CFN.Home and CFN.Home.PopupOffset) or 5
            self.tmHomePopup:setX(absX + TW - GAP)
            self.tmHomePopup:setY(absY)
        end
    end
end
