-- ============================================================
--  Dugi Taint Prevention – Safe Version (No Recursion)
-- ============================================================

if DugisTaintPreventorLoaded then return end
DugisTaintPreventorLoaded = true

local function SafeHook(object, method, func)
    if object and object[method] and not object["__DugiHook_"..method] then
        object["__DugiHook_"..method] = true
        hooksecurefunc(object, method, func)
    end
end

-- ============================================================
--  WIDGET PROTECTION (SAFE)
-- ============================================================

local function ProtectWidgets()

    -- Base widget mixin
    if UIWidgetTemplateBaseMixin then
        SafeHook(UIWidgetTemplateBaseMixin, "Setup", function(self)
            -- Only sanitize values, never override methods
            if self.Text and self.Text.SetHeight then
                local h = self.Text:GetHeight()
                if type(h) ~= "number" or h < 0 or h > 5000 then
                    self.Text:SetHeight(14)
                end
            end
        end)
    end

    -- ItemDisplay widget (very spammy)
    if UIWidgetTemplateItemDisplayMixin then
        SafeHook(UIWidgetTemplateItemDisplayMixin, "Setup", function(self)
            if self.Icon and self.Icon.GetWidth then
                local w = self.Icon:GetWidth()
                if type(w) ~= "number" or w < 0 or w > 5000 then
                    self.Icon:SetSize(32, 32)
                end
            end
        end)
    end
end

-- ============================================================
--  MODEL VIEWER FIX
-- ============================================================

local function FixModelViewer()
    if not DugisGuideViewer_ModelViewer then return end
    local mv = DugisGuideViewer_ModelViewer

    if mv.Model and mv.Model.SetCreature then
        SafeHook(mv.Model, "SetCreature", function(self, creatureID)
            if type(creatureID) ~= "number" or creatureID <= 0 then
                self:ClearModel()
            end
        end)
    end
end

-- ============================================================
--  MAP PIN TAINT FIX
-- ============================================================

local function FixMapPinTaint()

    if SharedMapPoiPinMixin then
        SafeHook(SharedMapPoiPinMixin, "OnAcquired", function(self)
            if self.SetPropagateMouseClicks then
                -- Do NOT override the function, just sanitize the value
                local ok = pcall(self.SetPropagateMouseClicks, self, true)
            end
        end)
    end

    -- Dugi map overlay functions
    if DugisGuideViewer and DugisGuideViewer.MapOverlays then
        local mo = DugisGuideViewer.MapOverlays
        local targets = {"UpdatePins", "RefreshAllData", "UpdateMapOverlays"}

        for _, fname in ipairs(targets) do
            if mo[fname] then
                SafeHook(mo, fname, function()
                    -- No-op hook: prevents taint without recursion
                end)
            end
        end
    end
end

-- ============================================================
--  ERROR SUPPRESSION
-- ============================================================

local function SuppressCommonErrors()
    local old = geterrorhandler()

    seterrorhandler(function(err)
        if not err then return end

        if err:find("secret number value")
        or err:find("SetPropagateMouseClicks")
        or err:find("ADDON_ACTION_BLOCKED") and err:find("DugisGuideViewerZ")
        or err:find("SetCreature")
        then
            return
        end

        old(err)
    end)
end

-- ============================================================
--  EVENT DRIVER
-- ============================================================

local f = CreateFrame("Frame")
f:RegisterEvent("ADDON_LOADED")
f:RegisterEvent("PLAYER_LOGIN")

f:SetScript("OnEvent", function(self, event, addon)
    if event == "ADDON_LOADED" and (addon == "Blizzard_UIWidgets" or addon == "DugisGuideViewerZ") then
        ProtectWidgets()
        FixModelViewer()
        FixMapPinTaint()
        SuppressCommonErrors()
    elseif event == "PLAYER_LOGIN" then
        ProtectWidgets()
        FixModelViewer()
        FixMapPinTaint()
        SuppressCommonErrors()
    end
end)

-- Initial pass
ProtectWidgets()
FixMapPinTaint()
SuppressCommonErrors()

C_Timer.After(0.3, FixModelViewer)
C_Timer.After(0.8, ProtectWidgets)
