local _,ns = ...

local oneUpdateFrame = CreateFrame("Frame")
local whatToUpdate = {}
local oneUpdateLimit

local function getTextureIcon(icon) --1AS, 2moneda, 3whitelist, 4 diamon(+10kvalue)
        local numIcon
        if icon == 1 then
            numIcon = 1
        elseif icon == 2 then
            numIcon = 2
        elseif icon == 3 then
            numIcon = 5
        elseif icon == 4 then
            numIcon = 7
        end
        return 14*(numIcon-1)/512, 14*(numIcon)/512, 50/512 , 63/512
end

local function updateFrameItemWithItemID(frameIconTex, itemID)
    local price = ns.getItemCachedPrice(itemID)
    if itemID then
        if AutoScrap_CharSettings.noVenderList[itemID] then
            frameIconTex:SetTexCoord(getTextureIcon(3))
            frameIconTex:ClearAllPoints()
            frameIconTex:SetPoint('TOPLEFT',2, -2)
            frameIconTex:SetSize(14, 13)
            frameIconTex:Show()
            return true
        elseif ns.isJunkBL(itemID) then
            frameIconTex:SetTexCoord(getTextureIcon(2))
            frameIconTex:ClearAllPoints()
            --frameIconTex:SetPoint('TOPLEFT',2, 0) --old simple coin
            frameIconTex:SetPoint('TOPLEFT',2, -2)
            frameIconTex:SetSize(14, 13)
            frameIconTex:Show()
            return true
        elseif ns.isJunkAS(itemID) then
            frameIconTex:SetTexCoord(getTextureIcon(1))
            frameIconTex:ClearAllPoints()
            frameIconTex:SetPoint('TOPLEFT',2, -2)
            frameIconTex:SetSize(14, 13)
            frameIconTex:Show()
            return true
        elseif  price and (price/10000)>10000 then
            frameIconTex:SetTexCoord(getTextureIcon(4))
            frameIconTex:ClearAllPoints()
            frameIconTex:SetPoint('TOPLEFT',2, -2)
            frameIconTex:SetSize(14, 13)
            frameIconTex:Show()
            return true
        else
            frameIconTex:Hide()
            return false
        end
    else
        frameIconTex:Hide()
        return false
    end
    return false
end

local function updateFrameItem(frameIcon,bag,slot)
    if not frameIcon.texTL then
        frameIcon.texTL = frameIcon:CreateTexture(nil,"OVERLAY")
        frameIcon.texTL:SetTexture("Interface\\AddOns\\AutoScrap\\images\\mailpanel")
    end
    local itemID = C_Container.GetContainerItemID(bag,slot)
    updateFrameItemWithItemID(frameIcon.texTL, itemID)
end

local function updateBagnonBagTable(frameTable, bag)
    for k,v in pairs(frameTable) do
        updateFrameItem(v,bag,v:GetID())
    end
end

local function updateUIBagFrame(frame)

    --print ("piii",frame:IsCombinedBagContainer())
    if frame:IsCombinedBagContainer() then
        for i, itemButton in ContainerFrameCombinedBags:EnumerateValidItems() do
            --print(i,itemButton,itemButton:GetName(), itemButton:GetBagID(), itemButton:GetID())
            updateFrameItem(itemButton,itemButton:GetBagID(),itemButton:GetID())
        end
    else
        --código antiguo antes de 11.1.0
        -- --print(frame:GetName(), frame:GetID(), frame.size)
        -- local name, bag, tam = frame:GetName(), frame:GetID() ,frame.size
        -- if name and bag and tam and tam>=1 then
        --     for i=1, tam do
        --         local numUI = tam-i+1
        --         local frameIcon = _G[name.."Item"..numUI]
        --         updateFrameItem(frameIcon,bag,i)
        --     end
        -- end

        --file https://www.townlong-yak.com/framexml/live/Blizzard_UIPanels_Game/ContainerFrame.lua
        -- print("updating...")
        for i, itemButton in frame:EnumerateValidItems() do
            local info = C_Container.GetContainerItemInfo(itemButton:GetBagID(), itemButton:GetID());
            updateFrameItem(itemButton,itemButton:GetBagID(),itemButton:GetID())
        end
    end
end


function ns.updateUIALLBags()
    if Baganator and Baganator.API and Baganator.API.RequestItemButtonsRefresh then
         Baganator.API.RequestItemButtonsRefresh()
    elseif Bagnon then
        if BagnonInventory1 and BagnonInventory1:IsShown() then -- sólo sacar si está shown.
            --se pueden sacar la bolsas después la verdad, este no manda update por bolsa, por item o por show total.
            oneUpdateLimit()
        end
        if BagnonBank1 and BagnonBank1:IsShown() then
            oneUpdateLimit()
        end
    elseif ElvUI then--IsAddOnLoaded("ElvUI")
        if ElvUI_ContainerFrame and ElvUI_ContainerFrame:IsShown() then
            oneUpdateLimit()
        end
    else -- interfaz original
        if ContainerFrameCombinedBags:IsShown() then
            whatToUpdate[ContainerFrameCombinedBags] = true
        end
        --also bags even combinedbags is shown because reagent bags can be open too
        local i = 1
        local frame = _G['ContainerFrame' .. i]
        while frame do
            if frame:IsShown() then
                --updateUIBagFrame(frame)
                whatToUpdate[frame] = true
            end
            i = i + 1
            frame = _G['ContainerFrame' .. i]
        end
        oneUpdateLimit()
    end
end


-- antes del 10.0 era así, lo guardo comentado a como lo he conseguido hacer ahora
-- hooksecurefunc('ContainerFrame_Update', function (frame) -- para las bolsas de retail
--     --print("Signal ", frame:GetName(), frame:GetID())
--     whatToUpdate[frame] = true
--     oneUpdateLimit()
-- end)

--esto está bien pero da error al usar la piedra de hogar, no sé pro qué, entonces los enumero a mano con la global. Son del 1 al 13 en la 10.0.0.2
-- for i, frame in ContainerFrameUtil_EnumerateContainerFrames() do
--     --print("hook", frame:GetName())
--     hooksecurefunc(frame,'Update', function (f) -- para las bolsas de retail
--         --print ("signal: ", f, f:GetName())
--         whatToUpdate[f] = true
--         oneUpdateLimit()
--     end)
--  end

for i=1,20 do --son 13, dejo 20 por posibles actualizaciones. ojo que puede dar lugar a bug porque lo de arriba antes petaba al usar la piedra de hogar por hacer un look en el enumerate aunque fuera vacío
    if _G['ContainerFrame' .. i] then
        hooksecurefunc(_G['ContainerFrame' .. i],'Update', function (f) -- para las bolsas de retail
            --print ("signal: ", f, f:GetName())
            whatToUpdate[f] = true
            oneUpdateLimit()
        end)
    end
end


hooksecurefunc(ContainerFrameCombinedBags,'Update', function (f) -- para las bolsas de retail combined
    --print ("signal: ", f, f.size)
    whatToUpdate[f] = true
    oneUpdateLimit()
end)


function ns.hookBagnonInventoryFrameOnShow()
    hooksecurefunc(Bagnon.Item, "Update", function(frame)
        -- -- Código anterior funcionando antes de 11.1.0
        -- local bag = frame:GetBag()
        -- print("enganchado",frame, "bag:"..bag, "id:"..frame:GetID(), frame:GetParent():GetParent():GetParent().frameID)
        -- if bag>=0 and bag<=4 and frame:GetParent() and frame:GetParent():GetParent() and frame:GetParent():GetParent():GetParent() and frame:GetParent():GetParent():GetParent().frameID == "inventory" then -- en el banco de  hay bolsas 8 y -1 y aquí saltan todas, aparte el banco de guild da bolsas 1 y se mezclan
        --     updateFrameItem(frame,bag,frame:GetID())
        -- end
        slot, bag = frame:GetSlotAndBagID()
        updateFrameItem(frame, bag, slot)
    end)
end

function ns.hookElvUIInventoryFrameOnShow()
    hooksecurefunc(ElvUI[1].Bags,"UpdateSlot",function(self, frame, bagID, slotID)
        if frame.Bags and frame.Bags[bagID] and frame.Bags[bagID][slotID] and bagID >= 0 and bagID <= 4 then --a veces viene bolsa -1, 4,5,6,7,8
            --print("Fired me enganchoo ", bagID, slotID)
            updateFrameItem(frame.Bags[bagID][slotID],bagID,slotID)
        end
    end)
end

function ns.hookBaganator()
    Baganator.API.RegisterCornerWidget(
        "AutoScrap Icon",
        "autoscrap_icon",
        function(frameIcon, details)
            local itemID = details.itemID
            local price = ns.getItemCachedPrice(itemID)
            return updateFrameItemWithItemID(frameIcon, itemID)
        end,
        function(itemButton)
            local tex = itemButton:CreateTexture(nil, "OVERLAY")
            tex:SetTexture("Interface\\AddOns\\AutoScrap\\images\\mailpanel")
            tex:SetPoint("TOPLEFT", 2, -2)
            tex:SetSize(14, 13)
            --tex.padding = 0 -- puedes ajustar este valor según necesites
            return tex
        end,
        {corner = "top_left", priority = 1}, -- puedes ajustar posición y prioridad
        true -- es un widget "rápido"
    )
end




oneUpdateLimit = function ()
    oneUpdateFrame:SetScript ("OnUpdate", function (self, ...) -- a esta funcion llegan las bags que están enVista
        --local time = GetTimePreciseSec()
        --print("OneUpdate ", GetTime())

        --verision funcionando antes de la v12
        -- if BagnonInventoryFrame1 then
        --     for b=0,4 do
        --         if BagnonInventoryFrame1:IsShowingBag(b) and BagnonInventoryFrame1.itemGroup and BagnonInventoryFrame1.itemGroup.buttons and BagnonInventoryFrame1.itemGroup.buttons[b] then
        --             updateBagnonBagTable(BagnonInventoryFrame1.itemGroup.buttons[b],b) -- volver a comprobar que b es el orden de la tabla ordenada y no una key cualquiera
        --         end
        --     end
        if Bagnon then
            if BagnonInventory1 then
                if BagnonInventory1.ItemGroup and BagnonInventory1.ItemGroup.buttons and BagnonInventory1.ItemGroup.buttons then
                    for k,v in ipairs(BagnonInventory1.ItemGroup.buttons) do
                        local bagID, slotID = BagnonInventory1.ItemGroup.buttons[k]:GetSlot()
                        updateFrameItem(v, bagID, slotID)
                    end
                end
            end
            if BagnonBank1 then
                if BagnonBank1.ItemGroup and BagnonBank1.ItemGroup.buttons and BagnonBank1.ItemGroup.buttons then
                    for k,v in ipairs(BagnonBank1.ItemGroup.buttons) do
                        local bagID, slotID = BagnonBank1.ItemGroup.buttons[k]:GetSlot()
                        updateFrameItem(v, bagID, slotID)
                    end
                end
            end
        elseif ElvUI_ContainerFrame and ElvUI_ContainerFrame.Bags then
            for k, v in pairs(ElvUI_ContainerFrame.Bags) do
                --local bagid = k --tiene un id de bolsa el frame al final.
                for x, y in pairs(v) do
                    if (type(y) == "table" and y.bagID and y.slotID) then -- hay objetos en la tabla que son el número de slots y otra chorrada que no son tablas, además tiene tablas de más, creo que son fijas y simplemente las rellena de datos. Tiene hastItem y itemID tb.
                        --mostramos todas las bolsas, que yo sepa no hay una forma de no mostrar todas las boslas en ElvUI
                        --local frame, bagID, slotID = y, y.bagID, y.slotID
                        if y.slotID <= C_Container.GetContainerNumSlots(y.bagID) then
                            --print("Fired ElvUI", y.bagID,y.slotID)
                            updateFrameItem(y, y.bagID, y.slotID)
                        end
                    end
                end

            end

        else
            for k,v in pairs(whatToUpdate) do
                updateUIBagFrame(k)
            end
            whatToUpdate = {}
        end
        self:SetScript ("OnUpdate",nil)
        --print("total exec time oneUpdateFrame: ",(GetTimePreciseSec()-time)*1000)
    end)
end
