local ADDON_NAME = "PrismaticMito"
local TEXTURE_PATH = "Interface\\AddOns\\PrismaticMito\\border_prismatic"

-------------------------------------------------
-- 🔍 Detectar si un ítem es "Mito 8/8"
-------------------------------------------------
local function IsMitoMax(itemLink)
    if not itemLink then return false end
    local tooltip = CreateFrame("GameTooltip", "PrismaticMitoTooltip", nil, "GameTooltipTemplate")
    tooltip:SetOwner(UIParent, "ANCHOR_NONE")
    tooltip:SetHyperlink(itemLink)

    for i = 1, tooltip:NumLines() do
        local text = _G["PrismaticMitoTooltipTextLeft" .. i]:GetText()
        if text and string.find(text, "Mito 8/8") then
            return true
        end
    end
    return false
end

-------------------------------------------------
-- 🌈 Aplica el borde prismatico a un icono (sin error)
-------------------------------------------------
local function ApplyPrismaticBorder(frame)
    if frame.PrismaticBorderFrame then
        frame.PrismaticBorderFrame:Show()
        return
    end

    -- Frame contenedor para poder usar OnUpdate
    local borderFrame = CreateFrame("Frame", nil, frame)
    borderFrame:SetAllPoints(frame)
    borderFrame:SetFrameLevel(frame:GetFrameLevel() + 7)

    -- Textura del borde dentro del frame
    local border = borderFrame:CreateTexture(nil, "OVERLAY")
    border:SetPoint("TOPLEFT", borderFrame, "TOPLEFT", -15, 15)
    border:SetPoint("BOTTOMRIGHT", borderFrame, "BOTTOMRIGHT", 15, -15)
    border:SetTexture(TEXTURE_PATH)
    border:SetBlendMode("ADD")
    border:SetAlpha(1)

    -- Guardar referencia
    frame.PrismaticBorderFrame = borderFrame
    frame.PrismaticBorder = border

    -- 🌈 Animación continua del color (en el frame)
    local hue = math.random()
    borderFrame:SetScript("OnUpdate", function(_, elapsed)
        hue = (hue + elapsed * 0.5) % 1 -- velocidad
        local i = math.floor(hue * 6)
        local f = hue * 6 - i
        local q = 1 - f
        local r, g, b
        if i % 6 == 0 then r, g, b = 1, f, 0
        elseif i % 6 == 1 then r, g, b = q, 1, 0
        elseif i % 6 == 2 then r, g, b = 0, 1, f
        elseif i % 6 == 3 then r, g, b = 0, q, 1
        elseif i % 6 == 4 then r, g, b = f, 0, 1
        else r, g, b = 1, 0, q end
        border:SetVertexColor(r, g, b)
    end)
end

-------------------------------------------------
-- 💎 Tus ítems equipados (Character Frame)
-------------------------------------------------
local slotNames = {
    "Head", "Neck", "Shoulder", "Shirt", "Chest", "Waist", "Legs", "Feet",
    "Wrist", "Hands", "Finger0", "Finger1", "Trinket0", "Trinket1",
    "Back", "MainHand", "SecondaryHand", "Tabard"
}

local function UpdateCharacterFrameBorders()
    for i, name in ipairs(slotNames) do
        local slotFrame = _G["Character" .. name .. "Slot"]
        if slotFrame and slotFrame.icon then
            local itemLink = GetInventoryItemLink("player", slotFrame:GetID())
            if IsMitoMax(itemLink) then
                ApplyPrismaticBorder(slotFrame)
            elseif slotFrame.PrismaticBorder then
                slotFrame.PrismaticBorder:Hide()
            end
        end
    end
end

hooksecurefunc("PaperDollItemSlotButton_Update", UpdateCharacterFrameBorders)

-------------------------------------------------
-- 🧍‍♂️ Inspeccionar a otro jugador (versión estable)
-------------------------------------------------
local function ClearInspectBorders()
    for _, name in ipairs(slotNames) do
        local slot = _G["Inspect"..name.."Slot"]
        if slot and slot.PrismaticBorderFrame then
            slot.PrismaticBorderFrame:Hide()
        end
    end
end

local function UpdateInspectFrameBorders(unit)
    if not InspectFrame or not unit or not UnitExists(unit) then return end

    ClearInspectBorders() -- limpia bordes antiguos

    -- esperamos un poco para asegurarnos que el inventario esté cargado
    C_Timer.After(0.3, function()
        for _, name in ipairs(slotNames) do
            local slot = _G["Inspect"..name.."Slot"]
            if slot and slot.icon then
                local itemLink = GetInventoryItemLink(unit, slot:GetID())
                if itemLink and IsMitoMax(itemLink) then
                    ApplyPrismaticBorder(slot)
                elseif slot.PrismaticBorderFrame then
                    slot.PrismaticBorderFrame:Hide()
                end
            end
        end
    end)
end

-- Evento principal del inspector
local inspectFrame = CreateFrame("Frame")
inspectFrame:RegisterEvent("INSPECT_READY")
inspectFrame:SetScript("OnEvent", function(_, event, guid)
    if event == "INSPECT_READY" and InspectFrame and InspectFrame.unit then
        UpdateInspectFrameBorders(InspectFrame.unit)
    end
end)

-- Limpia los bordes cuando se cierra la ventana de inspección
if InspectFrame then
    InspectFrame:HookScript("OnHide", function()
        ClearInspectBorders()
    end)
end

-------------------------------------------------
-- 🎒 Mochila / Bag Slots (versión compatible 11.x)
-- Recorre los ContainerFrame visibles y actualiza bordes
-------------------------------------------------
local function UpdateVisibleContainerFrames()
    -- NUM_CONTAINER_FRAMES es una constante global que define cuantos frames hay
    for i = 1, (NUM_CONTAINER_FRAMES or 12) do
        local cframe = _G["ContainerFrame"..i]
        if cframe and cframe:IsShown() then
            local bag = cframe:GetID() -- devuelve el id de la bolsa asociada a ese frame
            local size = cframe.size or C_Container.GetContainerNumSlots(bag) or 0
            for slot = 1, size do
                local btn = _G[cframe:GetName() .. "Item" .. slot]
                if btn and (btn.Icon or btn.icon) then
                    -- usar la API del contenedor para obtener el itemLink
                    local itemLink = C_Container.GetContainerItemLink(bag, slot)
                    if itemLink and IsMitoMax(itemLink) then
                        ApplyPrismaticBorder(btn)
                    elseif btn.PrismaticBorder then
                        btn.PrismaticBorder:Hide()
                    end
                end
            end
        end
    end
end

-- Hook a eventos relevantes
local bagFrameUpdater = CreateFrame("Frame")
bagFrameUpdater:RegisterEvent("BAG_UPDATE")            -- al cambiar contenido de bolsas
bagFrameUpdater:RegisterEvent("BAG_UPDATE_DELAYED")   -- en caso de que haya retrasos procesados por Blizzard
bagFrameUpdater:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
bagFrameUpdater:SetScript("OnEvent", function(_, event, ...)
    -- Actualizar visible inmediatamente
    C_Timer.After(0.05, UpdateVisibleContainerFrames)
end)

-- Hookea cada ContainerFrame para actualizar cuando se muestre (evita depender de funciones internas)
for i = 1, (NUM_CONTAINER_FRAMES or 12) do
    local cframe = _G["ContainerFrame"..i]
    if cframe then
        cframe:HookScript("OnShow", UpdateVisibleContainerFrames)
        cframe:HookScript("OnHide", UpdateVisibleContainerFrames)
    end
end

-- Revisión inicial al cargar y tras 1s (cuando se haya creado la UI)
C_Timer.After(1, UpdateVisibleContainerFrames)

print("|cff00ffcc[PrismaticMito]|r Cargado con éxito")