-- ============================================================================
-- pom/pvp/pvp.lua
-- PvP visuals (12.0 secret-safe)
--
-- FEATURES (NO SKINS):
--  - Class colors on enemy PLAYER nameplates (SetStatusBarColor)
--  - Grey HP-bar background (inside the HP bar) toggle
--  - Arena numbers 1-5 ABOVE nameplate (secret-safe: SetAlphaFromBoolean(UnitIsUnit))
--  - Healer marker (arena spec scan) via ns.pvp_healer_mark (green square)
--  - Target / Focus border (secret-safe: holder SetAlphaFromBoolean(UnitIsUnit))
--  - Target CC icon (secret-safe: holder SetAlphaFromBoolean(UnitIsUnit))
--
-- IMPORTANT:
--  - Does NOT change textures (no SetStatusBarTexture)
--  - Restores original statusbar color when module isn't active
-- ============================================================================

local ADDON_NAME, ns = ...

ns = _G[ADDON_NAME] or ns
_G[ADDON_NAME] = ns

ns.pvp = ns.pvp or {}
local P = ns.pvp

local DB  = ns.pvp_db
local U   = ns.util
local CUA = C_UnitAuras

local RAID_CLASS_COLORS = RAID_CLASS_COLORS
local pcall = pcall

-- ------------------------------------------------------------
-- Instance checks
-- ------------------------------------------------------------
local function GetInstType()
local inInstance, instType = IsInInstance()
if not inInstance then return "world" end
    if instType == "arena" then return "arena" end
        if instType == "pvp"   then return "bg" end
            return "other"
            end

            local function ShouldRun(dbpvp)
            if not (dbpvp and dbpvp.enabled) then return false end
                local t = GetInstType()
                if t == "arena" then return dbpvp.useArena and true or false end
                    if t == "bg"    then return dbpvp.useBG    and true or false end
                        if t == "world" then return dbpvp.useWorld and true or false end
                            return false
                            end

                            local function IsEnemyPlayer(unit)
                            if not unit or not UnitExists(unit) then return false end
                                if not UnitIsPlayer(unit) then return false end
                                    return UnitIsEnemy("player", unit) and true or false
                                    end

                                    local function GetEnemyClassToken(unit)
                                    if not unit or not UnitExists(unit) then return nil end
                                        local _, classToken = UnitClass(unit)
                                        return classToken
                                        end

                                        -- ------------------------------------------------------------
                                        -- Small helpers
                                        -- ------------------------------------------------------------
                                        local function GetHB(frame)
                                        return frame.healthBar or (frame.HealthBarsContainer and frame.HealthBarsContainer.healthBar)
                                        end

                                        local function SafeSetAlphaFromBoolean(obj, boolMaybeSecret, aTrue, aFalse)
                                        if not obj then return end
                                            if obj.SetAlphaFromBoolean then
                                                pcall(obj.SetAlphaFromBoolean, obj, boolMaybeSecret, aTrue or 1, aFalse or 0)
                                                else
                                                    -- if method missing, safest is hide
                                                    obj:SetAlpha(aFalse or 0)
                                                    end
                                                    end

                                                    local function SetFontSize(fs, size)
                                                    if not fs or not fs.GetFont or not fs.SetFont then return end
                                                        local path, _, flags = fs:GetFont()
                                                        if path then
                                                            fs:SetFont(path, size, flags)
                                                            end
                                                            end

                                                            -- ------------------------------------------------------------
                                                            -- Widgets on healthbar
                                                            -- ------------------------------------------------------------
                                                            local function EnsureWidgets(frame, hb)
                                                            if not hb or hb:IsForbidden() then return end

                                                                -- Grey HP-bar background (INSIDE hp bar)
                                                                if not hb.pomPvpHB_BG then
                                                                    local bg = hb:CreateTexture(nil, "BACKGROUND", nil, 0)
                                                                    bg:SetAllPoints(hb)
                                                                    bg:SetTexture("Interface\\Buttons\\WHITE8x8")
                                                                    bg:SetVertexColor(0.18, 0.18, 0.18, 0.92)
                                                                    bg:Hide()
                                                                    hb.pomPvpHB_BG = bg
                                                                    end

                                                                    -- Target CC (use holder to drive alpha from UnitIsUnit safely)
                                                                    if not hb.pomPvpCCHolder then
                                                                        local h = CreateFrame("Frame", nil, hb)
                                                                        h:SetAllPoints(hb)
                                                                        h:SetAlpha(0)
                                                                        hb.pomPvpCCHolder = h

                                                                        local ic = h:CreateTexture(nil, "OVERLAY", nil, 7)
                                                                        ic:SetSize(18, 18)
                                                                        ic:SetPoint("LEFT", hb, "RIGHT", 6, 0)
                                                                        ic:Hide()
                                                                        hb.pomPvpCC = ic
                                                                        end

                                                                        -- Arena numbers: 5 holders (alpha driven by SetAlphaFromBoolean)
                                                                        if not hb.pomArenaHolders then
                                                                            hb.pomArenaHolders = {}
                                                                            for i=1,5 do
                                                                                local holder = CreateFrame("Frame", nil, hb)
                                                                                holder:SetAllPoints(hb)
                                                                                holder:SetAlpha(0)

                                                                                local fs = holder:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
                                                                                fs:SetJustifyH("CENTER")
                                                                                fs:SetText(tostring(i))
                                                                                fs:SetTextColor(1, 0, 0, 1) -- RED

                                                                                holder._fs = fs
                                                                                hb.pomArenaHolders[i] = holder
                                                                                end
                                                                                end

                                                                                -- Borders: make borders once, then drive alpha on a holder (secret-safe)
                                                                                if U and U.MakeBorder then
                                                                                    if not hb.pomPvpTargetBorder then
                                                                                        hb.pomPvpTargetBorder = U.MakeBorder(hb, "pomPvpTargetBorder")
                                                                                        -- make a holder so we can alpha toggle without UnitIsUnit if-tests
                                                                                        local h = CreateFrame("Frame", nil, hb)
                                                                                        h:SetAllPoints(hb)
                                                                                        h:SetAlpha(0)
                                                                                        hb.pomPvpTargetBorderHolder = h
                                                                                        for i=1,4 do
                                                                                            local t = hb.pomPvpTargetBorder[i]
                                                                                            if t then
                                                                                                t:SetParent(h)
                                                                                                t:Show() -- always shown; holder alpha controls visibility
                                                                                                end
                                                                                                end
                                                                                                end

                                                                                                if not hb.pomPvpFocusBorder then
                                                                                                    hb.pomPvpFocusBorder = U.MakeBorder(hb, "pomPvpFocusBorder")
                                                                                                    local h = CreateFrame("Frame", nil, hb)
                                                                                                    h:SetAllPoints(hb)
                                                                                                    h:SetAlpha(0)
                                                                                                    hb.pomPvpFocusBorderHolder = h
                                                                                                    for i=1,4 do
                                                                                                        local t = hb.pomPvpFocusBorder[i]
                                                                                                        if t then
                                                                                                            t:SetParent(h)
                                                                                                            t:Show()
                                                                                                            end
                                                                                                            end
                                                                                                            end
                                                                                                            end
                                                                                                            end

                                                                                                            local function ApplyArenaNumberLayout(hb, dbpvp)
                                                                                                            if not hb or not hb.pomArenaHolders then return end

                                                                                                                local size = tonumber(dbpvp.arenaNumbersSize or 18) or 18
                                                                                                                local ax   = tonumber(dbpvp.arenaNumbersX or 0) or 0
                                                                                                                local ay   = tonumber(dbpvp.arenaNumbersY or 8) or 8

                                                                                                                for i=1,5 do
                                                                                                                    local h = hb.pomArenaHolders[i]
                                                                                                                    if h and h._fs then
                                                                                                                        h._fs:ClearAllPoints()
                                                                                                                        h._fs:SetPoint("BOTTOM", hb, "TOP", ax, ay)
                                                                                                                        SetFontSize(h._fs, size)
                                                                                                                        end
                                                                                                                        end
                                                                                                                        end

                                                                                                                        -- ------------------------------------------------------------
                                                                                                                        -- Target CC icon (SECRET-SAFE)
                                                                                                                        -- - NO duration compares
                                                                                                                        -- - if icon exists -> alpha driven by UnitIsUnit("target", frame.unit)
                                                                                                                        -- ------------------------------------------------------------
                                                                                                                        local function UpdateTargetCC(frame, hb, dbpvp)
                                                                                                                        if not (dbpvp and dbpvp.showTargetCC) then
                                                                                                                            if hb.pomPvpCCHolder then hb.pomPvpCCHolder:SetAlpha(0) end
                                                                                                                                if hb.pomPvpCC then hb.pomPvpCC:Hide() end
                                                                                                                                    return
                                                                                                                                    end

                                                                                                                                    if not (CUA and CUA.GetAuraDataByIndex) then
                                                                                                                                        if hb.pomPvpCCHolder then hb.pomPvpCCHolder:SetAlpha(0) end
                                                                                                                                            if hb.pomPvpCC then hb.pomPvpCC:Hide() end
                                                                                                                                                return
                                                                                                                                                end

                                                                                                                                                local icon = nil
                                                                                                                                                for i=1, 40 do
                                                                                                                                                    local a = CUA.GetAuraDataByIndex(frame.unit, i, "HARMFUL")
                                                                                                                                                    if not a then break end
                                                                                                                                                        if a.icon then
                                                                                                                                                            icon = a.icon
                                                                                                                                                            break
                                                                                                                                                            end
                                                                                                                                                            end

                                                                                                                                                            if icon and hb.pomPvpCC then
                                                                                                                                                                hb.pomPvpCC:SetTexture(icon)
                                                                                                                                                                hb.pomPvpCC:Show()
                                                                                                                                                                -- IMPORTANT: UnitIsUnit may be secret boolean -> do NOT if-test
                                                                                                                                                                SafeSetAlphaFromBoolean(hb.pomPvpCCHolder, UnitIsUnit("target", frame.unit), 1, 0)
                                                                                                                                                                else
                                                                                                                                                                    if hb.pomPvpCCHolder then hb.pomPvpCCHolder:SetAlpha(0) end
                                                                                                                                                                        if hb.pomPvpCC then hb.pomPvpCC:Hide() end
                                                                                                                                                                            end
                                                                                                                                                                            end

                                                                                                                                                                            -- ------------------------------------------------------------
                                                                                                                                                                            -- Class color apply/restore
                                                                                                                                                                            -- ------------------------------------------------------------
                                                                                                                                                                            local function StoreOrigColor(hb)
                                                                                                                                                                            if hb.pomPvpOrigColorStored then return end
                                                                                                                                                                                if hb.GetStatusBarColor then
                                                                                                                                                                                    local r,g,b = hb:GetStatusBarColor()
                                                                                                                                                                                    hb.pomPvpOrigR = r
                                                                                                                                                                                    hb.pomPvpOrigG = g
                                                                                                                                                                                    hb.pomPvpOrigB = b
                                                                                                                                                                                    hb.pomPvpOrigColorStored = true
                                                                                                                                                                                    end
                                                                                                                                                                                    end

                                                                                                                                                                                    local function RestoreOrigColor(hb)
                                                                                                                                                                                    if not hb.pomPvpOrigColorStored then return end
                                                                                                                                                                                        if hb.SetStatusBarColor then
                                                                                                                                                                                            hb:SetStatusBarColor(hb.pomPvpOrigR or 1, hb.pomPvpOrigG or 1, hb.pomPvpOrigB or 1)
                                                                                                                                                                                            end
                                                                                                                                                                                            end

                                                                                                                                                                                            local function ApplyClassColor(hb, unit)
                                                                                                                                                                                            if not (hb and hb.SetStatusBarColor) then return end
                                                                                                                                                                                                local ct = GetEnemyClassToken(unit)
                                                                                                                                                                                                if not ct then return end
                                                                                                                                                                                                    local c = RAID_CLASS_COLORS and RAID_CLASS_COLORS[ct]
                                                                                                                                                                                                    if not c then return end
                                                                                                                                                                                                        hb:SetStatusBarColor(c.r or 1, c.g or 1, c.b or 1)
                                                                                                                                                                                                        end

                                                                                                                                                                                                        -- ------------------------------------------------------------
                                                                                                                                                                                                        -- Arena numbers (SECRET-BOOLEAN SAFE)
                                                                                                                                                                                                        -- ------------------------------------------------------------
                                                                                                                                                                                                        local function UpdateArenaNumbers(frame, hb, dbpvp, inst, isEnemyPl)
                                                                                                                                                                                                        local holders = hb.pomArenaHolders
                                                                                                                                                                                                        if not holders then return end

                                                                                                                                                                                                            local enabled = (dbpvp.arenaNumbersEnabled and inst == "arena" and isEnemyPl) and true or false

                                                                                                                                                                                                            if not enabled then
                                                                                                                                                                                                                for i=1,5 do
                                                                                                                                                                                                                    local h = holders[i]
                                                                                                                                                                                                                    if h then h:SetAlpha(0) end
                                                                                                                                                                                                                        end
                                                                                                                                                                                                                        return
                                                                                                                                                                                                                        end

                                                                                                                                                                                                                        for i=1,5 do
                                                                                                                                                                                                                            local h = holders[i]
                                                                                                                                                                                                                            if h then
                                                                                                                                                                                                                                if dbpvp.arenaNumbersOnly123 and i > 3 then
                                                                                                                                                                                                                                    h:SetAlpha(0)
                                                                                                                                                                                                                                    else
                                                                                                                                                                                                                                        -- UnitIsUnit may be secret boolean -> do NOT if-test
                                                                                                                                                                                                                                        SafeSetAlphaFromBoolean(h, UnitIsUnit(frame.unit, "arena"..i), 1, 0)
                                                                                                                                                                                                                                        end
                                                                                                                                                                                                                                        end
                                                                                                                                                                                                                                        end
                                                                                                                                                                                                                                        end

                                                                                                                                                                                                                                        -- ------------------------------------------------------------
                                                                                                                                                                                                                                        -- Borders (SECRET-BOOLEAN SAFE via holder alpha)
                                                                                                                                                                                                                                        -- ------------------------------------------------------------
                                                                                                                                                                                                                                        local function UpdateBorders(frame, hb, dbpvp)
                                                                                                                                                                                                                                        if not U or not U.LayoutBorder then return end

                                                                                                                                                                                                                                            if hb.pomPvpTargetBorder and hb.pomPvpTargetBorderHolder then
                                                                                                                                                                                                                                                if dbpvp.showTargetBorder then
                                                                                                                                                                                                                                                    local c = dbpvp.targetBorderColor or { r=1.0, g=0.82, b=0.0, a=1.0 }
                                                                                                                                                                                                                                                    for i=1,4 do
                                                                                                                                                                                                                                                        local t = hb.pomPvpTargetBorder[i]
                                                                                                                                                                                                                                                        if t then t:SetColorTexture(c.r or 1, c.g or 0.82, c.b or 0, c.a or 1) end
                                                                                                                                                                                                                                                            end
                                                                                                                                                                                                                                                            U.LayoutBorder(hb.pomPvpTargetBorder, hb, 3)
                                                                                                                                                                                                                                                            SafeSetAlphaFromBoolean(hb.pomPvpTargetBorderHolder, UnitIsUnit("target", frame.unit), 1, 0)
                                                                                                                                                                                                                                                            else
                                                                                                                                                                                                                                                                hb.pomPvpTargetBorderHolder:SetAlpha(0)
                                                                                                                                                                                                                                                                end
                                                                                                                                                                                                                                                                end

                                                                                                                                                                                                                                                                if hb.pomPvpFocusBorder and hb.pomPvpFocusBorderHolder then
                                                                                                                                                                                                                                                                if dbpvp.showFocusBorder then
                                                                                                                                                                                                                                                                local c = dbpvp.focusBorderColor or { r=0.0, g=0.8, b=1.0, a=1.0 }
                                                                                                                                                                                                                                                                for i=1,4 do
                                                                                                                                                                                                                                                                local t = hb.pomPvpFocusBorder[i]
                                                                                                                                                                                                                                                                if t then t:SetColorTexture(c.r or 0, c.g or 0.8, c.b or 1, c.a or 1) end
                                                                                                                                                                                                                                                                end
                                                                                                                                                                                                                                                                U.LayoutBorder(hb.pomPvpFocusBorder, hb, 3)
                                                                                                                                                                                                                                                                SafeSetAlphaFromBoolean(hb.pomPvpFocusBorderHolder, UnitIsUnit("focus", frame.unit), 1, 0)
                                                                                                                                                                                                                                                                else
                                                                                                                                                                                                                                                                hb.pomPvpFocusBorderHolder:SetAlpha(0)
                                                                                                                                                                                                                                                                end
                                                                                                                                                                                                                                                                end
                                                                                                                                                                                                                                                                end

                                                                                                                                                                                                                                                                -- ------------------------------------------------------------
                                                                                                                                                                                                                                                                -- Cleanup (avoid sticky visuals)
                                                                                                                                                                                                                                                                -- ------------------------------------------------------------
                                                                                                                                                                                                                                                                local function Cleanup(frame)
                                                                                                                                                                                                                                                                local hb = frame and GetHB(frame)
                                                                                                                                                                                                                                                                if hb and not hb:IsForbidden() then
                                                                                                                                                                                                                                                                if hb.pomPvpHB_BG then hb.pomPvpHB_BG:Hide() end

                                                                                                                                                                                                                                                                if hb.pomPvpCCHolder then hb.pomPvpCCHolder:SetAlpha(0) end
                                                                                                                                                                                                                                                                if hb.pomPvpCC then hb.pomPvpCC:Hide() end

                                                                                                                                                                                                                                                                if hb.pomArenaHolders then
                                                                                                                                                                                                                                                                for i=1,5 do
                                                                                                                                                                                                                                                                local h = hb.pomArenaHolders[i]
                                                                                                                                                                                                                                                                if h then h:SetAlpha(0) end
                                                                                                                                                                                                                                                                end
                                                                                                                                                                                                                                                                end

                                                                                                                                                                                                                                                                if hb.pomPvpHealerSquares then
                                                                                                                                                                                                                                                                for i=1,5 do
                                                                                                                                                                                                                                                                local h = hb.pomPvpHealerSquares[i]
                                                                                                                                                                                                                                                                if h then h:SetAlpha(0) end
                                                                                                                                                                                                                                                                end
                                                                                                                                                                                                                                                                end

                                                                                                                                                                                                                                                                if hb.pomPvpTargetBorderHolder then hb.pomPvpTargetBorderHolder:SetAlpha(0) end
                                                                                                                                                                                                                                                                if hb.pomPvpFocusBorderHolder  then hb.pomPvpFocusBorderHolder:SetAlpha(0) end

                                                                                                                                                                                                                                                                RestoreOrigColor(hb)
                                                                                                                                                                                                                                                                end
                                                                                                                                                                                                                                                                end

                                                                                                                                                                                                                                                                -- ------------------------------------------------------------
                                                                                                                                                                                                                                                                -- Apply
                                                                                                                                                                                                                                                                -- ------------------------------------------------------------
                                                                                                                                                                                                                                                                function P:Apply(frame)
                                                                                                                                                                                                                                                                if not frame or frame:IsForbidden() then return end
                                                                                                                                                                                                                                                                if not (U and U.IsNameplateUnit and U.IsNameplateUnit(frame.unit)) then return end
                                                                                                                                                                                                                                                                if not (DB and DB.Get) then return end

                                                                                                                                                                                                                                                                local dbpvp = DB:Get()
                                                                                                                                                                                                                                                                if not ShouldRun(dbpvp) then
                                                                                                                                                                                                                                                                Cleanup(frame)
                                                                                                                                                                                                                                                                return
                                                                                                                                                                                                                                                                end

                                                                                                                                                                                                                                                                local hb = GetHB(frame)
                                                                                                                                                                                                                                                                if not hb or hb:IsForbidden() then return end

                                                                                                                                                                                                                                                                EnsureWidgets(frame, hb)

                                                                                                                                                                                                                                                                local inst = GetInstType()
                                                                                                                                                                                                                                                                local isEnemyPl = IsEnemyPlayer(frame.unit)

                                                                                                                                                                                                                                                                -- Grey background (inside HP bar)
                                                                                                                                                                                                                                                                if hb.pomPvpHB_BG then
                                                                                                                                                                                                                                                                if dbpvp.greyHPBackground and (inst == "arena" or inst == "bg") and isEnemyPl then
                                                                                                                                                                                                                                                                hb.pomPvpHB_BG:Show()
                                                                                                                                                                                                                                                                else
                                                                                                                                                                                                                                                                hb.pomPvpHB_BG:Hide()
                                                                                                                                                                                                                                                                end
                                                                                                                                                                                                                                                                end

                                                                                                                                                                                                                                                                -- Class colors (NO skins)
                                                                                                                                                                                                                                                                if dbpvp.classColorBars and isEnemyPl and (inst == "arena" or inst == "bg" or dbpvp.useWorld) then
                                                                                                                                                                                                                                                                StoreOrigColor(hb)
                                                                                                                                                                                                                                                                ApplyClassColor(hb, frame.unit)
                                                                                                                                                                                                                                                                else
                                                                                                                                                                                                                                                                RestoreOrigColor(hb)
                                                                                                                                                                                                                                                                end

                                                                                                                                                                                                                                                                -- Apply arena number layout from DB (size + offsets)
                                                                                                                                                                                                                                                                ApplyArenaNumberLayout(hb, dbpvp)

                                                                                                                                                                                                                                                                -- Arena numbers (red, above nameplate; secret-boolean safe)
                                                                                                                                                                                                                                                                UpdateArenaNumbers(frame, hb, dbpvp, inst, isEnemyPl)

                                                                                                                                                                                                                                                                -- Healer marker (arena spec scan) - uses DB layout too
                                                                                                                                                                                                                                                                if ns.pvp_healer_mark and ns.pvp_healer_mark.Apply then
                                                                                                                                                                                                                                                                ns.pvp_healer_mark:Apply(frame, hb, inst, isEnemyPl)
                                                                                                                                                                                                                                                                end

                                                                                                                                                                                                                                                                -- Target CC icon (secret-safe)
                                                                                                                                                                                                                                                                UpdateTargetCC(frame, hb, dbpvp)

                                                                                                                                                                                                                                                                -- Borders (secret-safe)
                                                                                                                                                                                                                                                                UpdateBorders(frame, hb, dbpvp)
                                                                                                                                                                                                                                                                end


