local _, _ns = ...
local AC = _G.ArenaCore
if not AC then return end

-- =============================================================================
-- Core/GearReminder.lua - PvE Gear Reminder for arena/BG prep rooms
-- because walking into arena with PvE gear on is a recipe for disaster
-- =============================================================================

local GR = {}
AC.GearReminder = GR

local frame = nil
local eventFrame = nil
local bgHideTimer = nil
local scanTooltip = nil
local lastScanResult = nil
local scanPending = false
local dismissed = false

------------------------------------------------------------------------
-- slot config - only armor/weapon slots that matter for PvP item level
------------------------------------------------------------------------
local CHECK_SLOTS = {
    { slot = INVSLOT_HEAD,       name = "Head" },
    { slot = INVSLOT_NECK,       name = "Neck" },
    { slot = INVSLOT_SHOULDER,   name = "Shoulder" },
    { slot = INVSLOT_CHEST,      name = "Chest" },
    { slot = INVSLOT_WAIST,      name = "Waist" },
    { slot = INVSLOT_LEGS,       name = "Legs" },
    { slot = INVSLOT_FEET,       name = "Feet" },
    { slot = INVSLOT_WRIST,      name = "Wrist" },
    { slot = INVSLOT_HAND,       name = "Hands" },
    { slot = INVSLOT_FINGER1,    name = "Finger 1" },
    { slot = INVSLOT_FINGER2,    name = "Finger 2" },
    { slot = INVSLOT_TRINKET1,   name = "Trinket 1" },
    { slot = INVSLOT_TRINKET2,   name = "Trinket 2" },
    { slot = INVSLOT_BACK,       name = "Back" },
    { slot = INVSLOT_MAINHAND,   name = "Main Hand" },
    { slot = INVSLOT_OFFHAND,    name = "Off Hand" },
}

------------------------------------------------------------------------
-- helpers
------------------------------------------------------------------------
local function GetDB()
    if not AC.DB or not AC.DB.profile then
        return { enabled = true }
    end
    AC.DB.profile.gearReminder = AC.DB.profile.gearReminder or {}
    local db = AC.DB.profile.gearReminder
    if db.enabled == nil then db.enabled = true end
    return db
end

local function IsInPvPInstance()
    local _, instanceType = IsInInstance()
    return instanceType == "arena" or instanceType == "pvp"
end

local function IsArenaPrep()
    local numSpecs = GetNumArenaOpponentSpecs and GetNumArenaOpponentSpecs() or 0
    local numOpps = GetNumArenaOpponents and GetNumArenaOpponents() or 0
    return numSpecs > 0 and numOpps == 0
end

local function IsBattlegroundStarting()
    local _, instanceType = IsInInstance()
    if instanceType ~= "pvp" then return false end
    local isArena = IsActiveBattlefieldArena and IsActiveBattlefieldArena()
    if isArena then return false end
    local duration = 0
    if C_PvP and C_PvP.GetActiveMatchDuration then
        duration = C_PvP.GetActiveMatchDuration() or 0
    end
    return duration < 5
end

------------------------------------------------------------------------
-- tooltip scanning for PvP gear detection
------------------------------------------------------------------------
local function HasPvPScalingText(text)
    if not text then return false end
    text = text:lower()
    -- catches "in arenas and battlegrounds", "in arenas, battlegrounds and war mode", etc.
    return text:find("arena") and text:find("battleground")
end

local function IsItemPvP_Gear(slot)
    local itemLink = GetInventoryItemLink("player", slot)
    if not itemLink then return nil end -- empty slot, skip

    -- modern retail API (TWW / Dragonflight+)
    if C_TooltipInfo and C_TooltipInfo.GetInventoryItem then
        local info = C_TooltipInfo.GetInventoryItem("player", slot)
        if info and info.lines then
            for _, line in ipairs(info.lines) do
                if HasPvPScalingText(line.leftText) then
                    return true
                end
            end
        end
        return false
    end

    -- fallback: hidden GameTooltip scan for older clients
    if not scanTooltip then
        scanTooltip = CreateFrame("GameTooltip", "ArenaCoreGearScanTooltip", nil, "GameTooltipTemplate")
        scanTooltip:SetOwner(UIParent, "ANCHOR_NONE")
    end
    scanTooltip:ClearLines()
    scanTooltip:SetInventoryItem("player", slot)

    for i = 1, scanTooltip:NumLines() do
        local line = _G["ArenaCoreGearScanTooltipTextLeft" .. i]
        if line and HasPvPScalingText(line:GetText()) then
            return true
        end
    end
    return false
end

local function ScanGear()
    local pveSlots = {}
    for _, slotInfo in ipairs(CHECK_SLOTS) do
        local isPvP = IsItemPvP_Gear(slotInfo.slot)
        if isPvP == false then
            -- item exists but has no PvP scaling text = PvE gear
            table.insert(pveSlots, slotInfo.name)
        end
        -- isPvP == nil means empty slot, skip it
    end
    lastScanResult = pveSlots
    return pveSlots
end

------------------------------------------------------------------------
-- frame creation
------------------------------------------------------------------------
local function CreateReminderFrame()
    if frame then return frame end

    local f = CreateFrame("Frame", "ArenaCoreGearReminder", UIParent)
    f:SetSize(380, 135)
    f:SetPoint("TOP", UIParent, "TOP", 0, -240)
    f:SetFrameStrata("HIGH")
    f:SetFrameLevel(200)
    f:Hide()
    f:EnableMouse(true)

    -- ===================================================================
    -- BACKDROP - very dark with subtle red tint
    -- ===================================================================
    local bg = f:CreateTexture(nil, "BACKGROUND")
    bg:SetAllPoints()
    bg:SetColorTexture(0.03, 0.01, 0.01, 0.96)
    f.bg = bg

    -- ===================================================================
    -- SCAN LINES - horizontal subtle stripes for that CRT / alert vibe
    -- ===================================================================
    local scanGroup = CreateFrame("Frame", nil, f)
    scanGroup:SetAllPoints()
    local spacing = 6
    local maxLines = math.floor(f:GetHeight() / spacing)
    for i = 1, maxLines do
        local line = scanGroup:CreateTexture(nil, "BORDER", nil, -1)
        line:SetHeight(1)
        line:SetColorTexture(0, 0, 0, 0.25)
        line:SetPoint("TOPLEFT", scanGroup, "TOPLEFT", 2, -(i * spacing))
        line:SetPoint("TOPRIGHT", scanGroup, "TOPRIGHT", -2, -(i * spacing))
    end
    f.scanGroup = scanGroup

    -- ===================================================================
    -- OUTER RED BORDER (2px)
    -- ===================================================================
    local borderOuter = f:CreateTexture(nil, "BORDER")
    borderOuter:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0)
    borderOuter:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, 0)
    borderOuter:SetHeight(2)
    borderOuter:SetColorTexture(0.75, 0.05, 0.05, 1)
    f.borderTop = borderOuter

    local borderBot = f:CreateTexture(nil, "BORDER")
    borderBot:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 0)
    borderBot:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 0)
    borderBot:SetHeight(2)
    borderBot:SetColorTexture(0.75, 0.05, 0.05, 1)
    f.borderBot = borderBot

    local borderLeft = f:CreateTexture(nil, "BORDER")
    borderLeft:SetPoint("TOPLEFT", f, "TOPLEFT", 0, -2)
    borderLeft:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 0, 2)
    borderLeft:SetWidth(2)
    borderLeft:SetColorTexture(0.75, 0.05, 0.05, 1)
    f.borderLeft = borderLeft

    local borderRight = f:CreateTexture(nil, "BORDER")
    borderRight:SetPoint("TOPRIGHT", f, "TOPRIGHT", 0, -2)
    borderRight:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 2)
    borderRight:SetWidth(2)
    borderRight:SetColorTexture(0.75, 0.05, 0.05, 1)
    f.borderRight = borderRight

    -- ===================================================================
    -- INNER GLOW / ACCENT
    -- ===================================================================
    local innerGlow = f:CreateTexture(nil, "BACKGROUND", nil, 1)
    innerGlow:SetPoint("TOPLEFT", f, "TOPLEFT", 4, -4)
    innerGlow:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -4, 4)
    innerGlow:SetColorTexture(0.25, 0.02, 0.02, 0.15)
    f.innerGlow = innerGlow

    -- ===================================================================
    -- TITLE - bold red
    -- ===================================================================
    local title = f:CreateFontString(nil, "OVERLAY")
    title:SetPoint("TOP", f, "TOP", 0, -12)
    title:SetJustifyH("CENTER")
    title:SetTextColor(1, 0.15, 0.15, 1)
    if title.SetFont then
        title:SetFont(AC.FONT_PATH or "Interface\\AddOns\\ArenaCore\\Media\\Fonts\\arenacore.ttf", 16, "OUTLINE")
    end
    title:SetText("GEAR WARNING")
    f.title = title

    -- ===================================================================
    -- BODY TEXT
    -- ===================================================================
    local body = f:CreateFontString(nil, "OVERLAY")
    body:SetPoint("TOP", title, "BOTTOM", 0, -6)
    body:SetWidth(340)
    body:SetJustifyH("CENTER")
    body:SetTextColor(0.95, 0.95, 0.95, 1)
    if body.SetFont then
        body:SetFont(AC.FONT_PATH or "Interface\\AddOns\\ArenaCore\\Media\\Fonts\\arenacore.ttf", 12, "OUTLINE")
    end
    body:SetText("You currently have PvE gear equipped!\nSwap before the match starts.")
    f.body = body

    -- ===================================================================
    -- SLOTS TEXT - shows which pieces are PvE
    -- ===================================================================
    local slotsText = f:CreateFontString(nil, "OVERLAY")
    slotsText:SetPoint("TOP", body, "BOTTOM", 0, -5)
    slotsText:SetWidth(350)
    slotsText:SetJustifyH("CENTER")
    slotsText:SetTextColor(1, 0.65, 0.2, 1)
    if slotsText.SetFont then
        slotsText:SetFont(AC.FONT_PATH or "Interface\\AddOns\\ArenaCore\\Media\\Fonts\\arenacore.ttf", 10, "OUTLINE")
    end
    f.slotsText = slotsText

    -- ===================================================================
    -- DISMISS BUTTON
    -- ===================================================================
    local btn = CreateFrame("Button", nil, f)
    btn:SetSize(80, 22)
    btn:SetPoint("TOP", slotsText, "BOTTOM", 0, -8)
    btn:EnableMouse(true)

    -- button bg
    local btnBg = btn:CreateTexture(nil, "BACKGROUND")
    btnBg:SetAllPoints()
    btnBg:SetColorTexture(0.08, 0.01, 0.01, 0.9)
    btn.bg = btnBg

    -- button border
    local btnBorder = btn:CreateTexture(nil, "BORDER")
    btnBorder:SetPoint("TOPLEFT", btn, "TOPLEFT", 0, 0)
    btnBorder:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 0, 0)
    btnBorder:SetColorTexture(0.7, 0.1, 0.1, 1)
    btnBorder:SetHeight(1)
    btn.border = btnBorder

    local btnBorderB = btn:CreateTexture(nil, "BORDER")
    btnBorderB:SetPoint("BOTTOMLEFT", btn, "BOTTOMLEFT", 0, 0)
    btnBorderB:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 0, 0)
    btnBorderB:SetHeight(1)
    btnBorderB:SetColorTexture(0.7, 0.1, 0.1, 1)

    local btnBorderL = btn:CreateTexture(nil, "BORDER")
    btnBorderL:SetPoint("TOPLEFT", btn, "TOPLEFT", 0, -1)
    btnBorderL:SetPoint("BOTTOMLEFT", btn, "BOTTOMLEFT", 0, 1)
    btnBorderL:SetWidth(1)
    btnBorderL:SetColorTexture(0.7, 0.1, 0.1, 1)

    local btnBorderR = btn:CreateTexture(nil, "BORDER")
    btnBorderR:SetPoint("TOPRIGHT", btn, "TOPRIGHT", 0, -1)
    btnBorderR:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 0, 1)
    btnBorderR:SetWidth(1)
    btnBorderR:SetColorTexture(0.7, 0.1, 0.1, 1)

    -- button text
    local btnText = btn:CreateFontString(nil, "OVERLAY")
    btnText:SetAllPoints()
    btnText:SetJustifyH("CENTER")
    btnText:SetJustifyV("MIDDLE")
    btnText:SetTextColor(1, 0.25, 0.25, 1)
    if btnText.SetFont then
        btnText:SetFont(AC.FONT_PATH or "Interface\\AddOns\\ArenaCore\\Media\\Fonts\\arenacore.ttf", 11, "OUTLINE")
    end
    btnText:SetText("Dismiss")
    btn.text = btnText

    -- hover / click effects
    btn:SetScript("OnEnter", function(self)
        self.bg:SetColorTexture(0.2, 0.02, 0.02, 0.95)
        self.text:SetTextColor(1, 0.5, 0.5, 1)
    end)
    btn:SetScript("OnLeave", function(self)
        self.bg:SetColorTexture(0.08, 0.01, 0.01, 0.9)
        self.text:SetTextColor(1, 0.25, 0.25, 1)
    end)
    btn:SetScript("OnMouseDown", function(self)
        self.bg:SetColorTexture(0.35, 0.02, 0.02, 1)
    end)
    btn:SetScript("OnMouseUp", function(self)
        self.bg:SetColorTexture(0.2, 0.02, 0.02, 0.95)
    end)
    btn:SetScript("OnClick", function()
        dismissed = true
        f:Hide()
    end)

    f.dismissBtn = btn

    -- ===================================================================
    -- TOP RED GLOW BAR (subtle pulse anchor)
    -- ===================================================================
    local topGlow = f:CreateTexture(nil, "ARTWORK", nil, -1)
    topGlow:SetPoint("TOPLEFT", f, "TOPLEFT", 2, -2)
    topGlow:SetPoint("TOPRIGHT", f, "TOPRIGHT", -2, -2)
    topGlow:SetHeight(1)
    topGlow:SetColorTexture(1, 0.1, 0.1, 0.6)
    f.topGlow = topGlow

    frame = f
    return f
end

------------------------------------------------------------------------
-- show / hide
------------------------------------------------------------------------
function GR:Show()
    local db = GetDB()
    if not db.enabled then return end
    if dismissed then return end
    if not frame then CreateReminderFrame() end
    if not frame then return end

    -- only show if we actually found PvE gear
    local pveSlots = lastScanResult
    if not pveSlots or #pveSlots == 0 then
        frame:Hide()
        return
    end

    frame.slotsText:SetText(table.concat(pveSlots, ", "))
    frame:Show()
end

function GR:Hide()
    if frame then frame:Hide() end
    if bgHideTimer then
        bgHideTimer:Cancel()
        bgHideTimer = nil
    end
end

function GR:Dismiss()
    dismissed = true
    if frame then frame:Hide() end
end

function GR:ResetDismiss()
    dismissed = false
end

function GR:IsShown()
    return frame and frame:IsShown()
end

------------------------------------------------------------------------
-- main check + display logic
------------------------------------------------------------------------
function GR:CheckAndShow()
    local db = GetDB()
    if not db.enabled then return end

    -- delay scan slightly to ensure item data is loaded
    if scanPending then return end
    scanPending = true

    C_Timer.After(0.1, function()
        scanPending = false
        local pveSlots = ScanGear()
        if #pveSlots > 0 then
            GR:Show()
        else
            GR:Hide()
        end
    end)
end

------------------------------------------------------------------------
-- event handling
------------------------------------------------------------------------
local function OnEvent(self, event, ...)
    local db = GetDB()
    if not db.enabled then return end

    if event == "ARENA_PREP_OPPONENT_SPECIALIZATIONS" then
        dismissed = false
        GR:CheckAndShow()

    elseif event == "ARENA_OPPONENT_UPDATE" then
        GR:Hide()

    elseif event == "PLAYER_ENTERING_WORLD" then
        local _, instanceType = IsInInstance()
        if instanceType == "arena" then
            local numSpecs = GetNumArenaOpponentSpecs and GetNumArenaOpponentSpecs() or 0
            local numOpps = GetNumArenaOpponents and GetNumArenaOpponents() or 0
            if numSpecs > 0 and numOpps == 0 then
                dismissed = false
                GR:CheckAndShow()
            else
                GR:Hide()
            end
        elseif instanceType == "pvp" then
            local isArena = IsActiveBattlefieldArena and IsActiveBattlefieldArena()
            if not isArena then
                dismissed = false
                GR:CheckAndShow()
                -- safety net: auto-hide after 2 minutes
                if bgHideTimer then bgHideTimer:Cancel() end
                bgHideTimer = C_Timer.NewTimer(120, function()
                    GR:Hide()
                end)
            end
        else
            GR:Hide()
        end

    elseif event == "START_TIMER" then
        local timerType = ...
        if timerType == Enum.StartTimerType.PvPBeginTimer then
            GR:Hide()
        end

    elseif event == "UNIT_INVENTORY_CHANGED" then
        -- player swapped gear, rescan
        local unit = ...
        if unit == "player" and GR:IsShown() then
            GR:CheckAndShow()
        end
    end
end

------------------------------------------------------------------------
-- init
------------------------------------------------------------------------
local function InitEventFrame()
    if eventFrame then return end

    eventFrame = CreateFrame("Frame")
    eventFrame:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
    eventFrame:RegisterEvent("ARENA_OPPONENT_UPDATE")
    eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
    eventFrame:RegisterEvent("START_TIMER")
    eventFrame:RegisterEvent("UNIT_INVENTORY_CHANGED")
    eventFrame:SetScript("OnEvent", OnEvent)
end

function GR:Initialize()
    InitEventFrame()

    -- check if already in a prep room on reload
    local _, instanceType = IsInInstance()
    if instanceType == "arena" then
        local numSpecs = GetNumArenaOpponentSpecs and GetNumArenaOpponentSpecs() or 0
        local numOpps = GetNumArenaOpponents and GetNumArenaOpponents() or 0
        if numSpecs > 0 and numOpps == 0 then
            dismissed = false
            GR:CheckAndShow()
        end
    elseif instanceType == "pvp" then
        local isArena = IsActiveBattlefieldArena and IsActiveBattlefieldArena()
        if not isArena then
            dismissed = false
            GR:CheckAndShow()
        end
    end
end

function GR:SetEnabled(enabled)
    enabled = (enabled == true)
    local db = GetDB()
    db.enabled = enabled

    if enabled then
        InitEventFrame()
    else
        GR:Hide()
    end
end

function GR:ForceRescan()
    lastScanResult = nil
    GR:CheckAndShow()
end
