local addonName, NS = ...
local GR = NS.GR -- Reference the Core Frame

-- =========================================================================
-- UI: HELPERS
-- =========================================================================

local function CreateBg(f, r, g, b, a)
    local t = f:CreateTexture(nil, "BACKGROUND")
    t:SetAllPoints()
    t:SetColorTexture(r, g, b, a)
    f.bg = t
end

local function CreateBorder(f, r, g, b, a)
    if f.border then f.border:Hide() end
    
    local border = f:CreateTexture(nil, "BORDER")
    border:SetPoint("TOPLEFT", -1, 1)
    border:SetPoint("BOTTOMRIGHT", 1, -1)
    border:SetColorTexture(r, g, b, a)
    f.border = border
end

-- [[ NEW: THICK BORDER HELPER (2px) ]]
local function CreateThickBorder(f, r, g, b, a, thickness)
    thickness = thickness or 2
    if f.thickBorder then 
        for _, t in ipairs(f.thickBorder) do t:Hide() end 
    end
    
    local lines = {}
    
    -- Top
    local t = f:CreateTexture(nil, "BORDER")
    t:SetPoint("TOPLEFT", 0, 0)
    t:SetPoint("TOPRIGHT", 0, 0)
    t:SetHeight(thickness)
    t:SetColorTexture(r,g,b,a)
    table.insert(lines, t)
    
    -- Bottom
    local b_line = f:CreateTexture(nil, "BORDER")
    b_line:SetPoint("BOTTOMLEFT", 0, 0)
    b_line:SetPoint("BOTTOMRIGHT", 0, 0)
    b_line:SetHeight(thickness)
    b_line:SetColorTexture(r,g,b,a)
    table.insert(lines, b_line)
    
    -- Left
    local l = f:CreateTexture(nil, "BORDER")
    l:SetPoint("TOPLEFT", 0, 0)
    l:SetPoint("BOTTOMLEFT", 0, 0)
    l:SetWidth(thickness)
    l:SetColorTexture(r,g,b,a)
    table.insert(lines, l)
    
    -- Right
    local ri = f:CreateTexture(nil, "BORDER")
    ri:SetPoint("TOPRIGHT", 0, 0)
    ri:SetPoint("BOTTOMRIGHT", 0, 0)
    ri:SetWidth(thickness)
    ri:SetColorTexture(r,g,b,a)
    table.insert(lines, ri)
    
    f.thickBorder = lines
end

local function SkinButton(btn)
    if not btn then return end
    
    btn:SetNormalTexture("")
    btn:SetHighlightTexture("")
    btn:SetPushedTexture("")
    btn:SetDisabledTexture("")
    
    if btn.Left then btn.Left:SetAlpha(0) end
    if btn.Middle then btn.Middle:SetAlpha(0) end
    if btn.Right then btn.Right:SetAlpha(0) end
    if btn.Top then btn.Top:SetAlpha(0) end
    if btn.Bottom then btn.Bottom:SetAlpha(0) end
    
    CreateBg(btn, 0.2, 0.2, 0.2, 1)
    CreateBorder(btn, 0, 0, 0, 1)
    
    btn:HookScript("OnEnter", function(s) 
        if s.bg then s.bg:SetColorTexture(0.3, 0.3, 0.3, 1) end 
    end)
    btn:HookScript("OnLeave", function(s) 
        if s.bg then s.bg:SetColorTexture(0.2, 0.2, 0.2, 1) end 
    end)
    btn:HookScript("OnMouseDown", function(s) 
        if s.bg then s.bg:SetColorTexture(0.1, 0.1, 0.1, 1) end 
    end)
    btn:HookScript("OnMouseUp", function(s) 
        if s.bg then s.bg:SetColorTexture(0.3, 0.3, 0.3, 1) end 
    end)
    
    local fs = btn:GetFontString()
    if fs then fs:SetTextColor(1, 1, 1) end
end

-- Export helpers to NS
NS.CreateBg = CreateBg
NS.CreateBorder = CreateBorder
NS.SkinButton = SkinButton

-- =========================================================================
-- UI: STRUCTURE & TABS
-- =========================================================================

function GR:UpdateResizeBounds()
    local currentScale = self:GetScale() or 1
    
    -- General Constraints adjusted for scale
    local maxWidth = 1980 / currentScale
    local maxHeight = 750 / currentScale 
    
    -- Determine Minimum Width based on Active Tab
    local minWidth = 1280
    if self.activeTab == 5 then
        minWidth = 1640 -- Enforce 1640 minimum for Guild Roster
    end

    -- Safety: MaxWidth must never be less than MinWidth (e.g., if scale is very high)
    if maxWidth < minWidth then 
        maxWidth = minWidth 
    end

    -- Apply Bounds: (minWidth, minHeight, maxWidth, maxHeight)
    self:SetResizeBounds(minWidth, 750, maxWidth, maxHeight) 
    
    -- Auto-Correct: If current width is invalid for the new constraints, snap it.
    local w = self:GetWidth()
    if w < minWidth then self:SetWidth(minWidth) end
    if w > maxWidth then self:SetWidth(maxWidth) end
end

function GR:BuildStructuralUI()
    self:SetFrameStrata("DIALOG") 
    self:SetToplevel(true)
    self:EnableMouse(true)
    self:SetMovable(true)
    self:SetResizable(true)
    self:SetClampedToScreen(true)
    self:SetSize(1280, 750) -- Increased height to accommodate new header
    self:SetPoint("CENTER")

    CreateBg(self, 0, 0, 0, 0.85)
    CreateBorder(self, 0.3, 0.3, 0.3, 1)

    self:RegisterForDrag("LeftButton")
    self:SetScript("OnDragStart", self.StartMoving)
    self:SetScript("OnDragStop", function(self)
        self:StopMovingOrSizing()
    end)
    
    self:UpdateResizeBounds()

    local resize = CreateFrame("Button", nil, self)
    resize:SetSize(16, 16); resize:SetPoint("BOTTOMRIGHT")
    resize:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
    resize:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
    resize:SetScript("OnMouseDown", function() self:StartSizing("BOTTOMRIGHT") end)
    resize:SetScript("OnMouseUp", function() 
        self:StopMovingOrSizing() 
        if self.db then
            self.db.windowWidth = self:GetWidth()
            self.db.windowHeight = self:GetHeight()
        end
    end)
    
    table.insert(UISpecialFrames, self:GetName()) 
    
    -- =========================================================================
    -- AXIOM GLOBAL HEADER
    -- =========================================================================
    local axiomHeader = CreateFrame("Frame", "GRS_AxiomHeader", self)
    axiomHeader:SetHeight(30)
    axiomHeader:SetPoint("TOPLEFT", 0, 0)
    axiomHeader:SetPoint("TOPRIGHT", 0, 0)
    CreateBg(axiomHeader, 0.1, 0.1, 0.1, 1) -- Consistent dark background
    CreateBorder(axiomHeader, 0, 0, 0, 1)
    
    local axTitle = axiomHeader:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    axTitle:SetPoint("CENTER", 0, 0)
    axTitle:SetText("A.X.I.O.M.")
    axTitle:SetTextColor(0.4, 0.8, 1) -- Slight blue tint for branding
    
    -- Close Button (Moved to Global Header)
    local close = CreateFrame("Button", nil, axiomHeader)
    close:SetPoint("TOPRIGHT", -5, -3) 
    close:SetSize(24, 24)
    close:SetNormalFontObject("GameFontNormal")
    close:SetText("X")
    close:SetScript("OnClick", function() GR:Hide() end)
    SkinButton(close)
    
    -- Initialize Minimap Button
    if self.BuildMinimapButton then self:BuildMinimapButton() end

    -- =========================================================================
    -- SIDEBAR & CONTENT LAYOUT
    -- =========================================================================
    
    local sideBar = CreateFrame("Frame", "GRS_SideBar", self)
    sideBar:SetWidth(40)
    sideBar:SetPoint("TOPLEFT", 0, -30) -- Shifted down below Axiom Header
    sideBar:SetPoint("BOTTOMLEFT", 0, 0)
    CreateBg(sideBar, 0.15, 0.15, 0.15, 1)
    CreateBorder(sideBar, 0, 0, 0, 1)
    self.SideBar = sideBar
    
    local container = CreateFrame("Frame", "GRS_ViewContainer", self)
    container:SetPoint("TOPLEFT", sideBar, "TOPRIGHT", 0, 0)
    container:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, 0)
    self.ViewContainer = container

    -- Original Title Bar (Preserved as Sub-Header)
    local top = CreateFrame("Frame", nil, container)
    CreateBg(top, 0.1, 0.1, 0.1, 1)
    top:SetHeight(30); top:SetPoint("TOPLEFT"); top:SetPoint("TOPRIGHT")
    self.TitleBar = top
    
    local title = top:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    title:SetPoint("LEFT", 10, 0); title:SetText("Guild Recruiter System")
    self.MainTitle = title
    
    local ioStatus = top:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    ioStatus:SetPoint("LEFT", title, "RIGHT", 10, 0)
    self.ioStatus = ioStatus; self:UpdateRaiderIOStatus()
    
    local offStatus = top:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    offStatus:SetPoint("LEFT", ioStatus, "RIGHT", 10, 0)
    self.officerStatus = offStatus
    
    -- Tabs Generation
    self.Tabs = {}
    local tabsData = NS.Constants.TABS
    
    for i, data in ipairs(tabsData) do
        local tab = CreateFrame("Button", nil, sideBar)
        tab:SetSize(32, 32)
        tab:SetPoint("TOP", sideBar, "TOP", 0, -10 - ((i-1) * 40))
        
        local tex = tab:CreateTexture(nil, "ARTWORK")
        tex:SetAllPoints()
        tex:SetTexture(data.icon)
        tab.icon = tex
        
        tab:SetScript("OnEnter", function(s)
            GameTooltip:SetOwner(s, "ANCHOR_CURSOR")
            GameTooltip:SetText(data.title)
            GameTooltip:Show()
            if s.timer then s.timer:Cancel() end
            s.timer = C_Timer.NewTimer(5, function()
                GameTooltip:Hide()
            end)
            if s.bg then s.bg:SetColorTexture(0.3, 0.3, 0.3, 1) end
        end)
        
        tab:SetScript("OnLeave", function(s)
            GameTooltip:Hide()
            if s.timer then s.timer:Cancel() end
            if s.bg then 
                 if GR.activeTab == i then
                     s.bg:SetColorTexture(1, 1, 1, 0.2)
                 else
                     s.bg:SetColorTexture(0, 0, 0, 0)
                 end
            end
        end)
        
        tab:SetScript("OnClick", function()
            if data.id == 7 and GR.OpenSettings then
                GR:OpenSettings()
            else
                GR:SwitchView(data.id)
            end
        end)
        
        local selBg = tab:CreateTexture(nil, "BACKGROUND")
        selBg:SetAllPoints()
        selBg:SetColorTexture(1, 1, 1, 0.2)
        selBg:Hide()
        tab.selBg = selBg
        
        self.Tabs[i] = tab
    end
end

function GR:BuildMinimapButton()
    local btn = CreateFrame("Button", "GRS_MinimapButton", Minimap)
    btn:SetSize(32, 32)
    btn:SetFrameLevel(8)
    
    -- Highlight
    btn:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
    
    -- Icon (Background Layer)
    local bg = btn:CreateTexture(nil, "BACKGROUND")
    bg:SetSize(20, 20)
    bg:SetPoint("CENTER")
    bg:SetTexture("Interface\\AddOns\\" .. addonName .. "\\Icons\\Guild Recruitment System.tga")
    btn.icon = bg

    -- Border (Overlay Layer)
    local border = btn:CreateTexture(nil, "OVERLAY")
    border:SetSize(52, 52)
    border:SetPoint("TOPLEFT", 0, 0)
    border:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
    
    btn:RegisterForClicks("AnyUp")
    
    btn:SetScript("OnClick", function(self, button)
        if IsShiftKeyDown() then
            ReloadUI()
        else
            if GR:IsShown() then GR:Hide() else GR:Show() end
        end
    end)
    
    btn:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_LEFT")
        GameTooltip:SetText("A.X.I.O.M.")
        GameTooltip:AddLine("Click to open A.X.I.O.M.", 1, 1, 1)
        GameTooltip:AddLine("SHIFT+CLICK to reload UI.", 0.7, 0.7, 0.7)
        GameTooltip:Show()
    end)
    
    btn:SetScript("OnLeave", function() GameTooltip:Hide() end)
    
    -- Drag Logic
    btn:SetMovable(true)
    btn:RegisterForDrag("LeftButton")
    
    local function UpdatePos()
        local angle = GR.db.minimapAngle or 45
        local radians = math.rad(angle)
        local radius = 100 -- Requested Radius
        local x = math.cos(radians) * radius
        local y = math.sin(radians) * radius
        btn:SetPoint("CENTER", Minimap, "CENTER", x, y)
    end
    
    btn:SetScript("OnDragStart", function(self)
        self:SetScript("OnUpdate", function()
            local mx, my = Minimap:GetCenter()
            local cx, cy = GetCursorPosition()
            local scale = Minimap:GetEffectiveScale()
            cx, cy = cx/scale, cy/scale
            
            local dx, dy = cx - mx, cy - my
            local angle = math.deg(math.atan2(dy, dx))
            GR.db.minimapAngle = angle
            UpdatePos()
        end)
    end)
    
    btn:SetScript("OnDragStop", function(self)
        self:SetScript("OnUpdate", nil)
    end)
    
    UpdatePos()
end

function GR:SwitchView(id)
    self.activeTab = id
    self:UpdateResizeBounds() -- DYNAMIC CHECK: Re-evaluate lock on tab switch
    for i, tab in ipairs(self.Tabs) do
        if i == id then
            tab:SetAlpha(1.0)
            tab.selBg:Show()
        else
            tab:SetAlpha(0.6)
            tab.selBg:Hide()
        end
    end
    for viewId, frame in pairs(self.views) do
        if viewId == id then
            frame:Show()
            -- Note: Blacklist refresh logic is now handled in Blacklist.lua via OnShow or explicit calls
            -- We no longer call GR:RefreshBlacklistViews() here to avoid nil errors if logic is moved.
        else
            frame:Hide()
        end
    end
    self.MainTitle:SetText(NS.Constants.TABS[id].title)
end

function GR:BuildModuleContainers()
    -- Standard Modules (Requirements, History, Guild, Raid)
    -- Note: Blacklist (ID 2) is handled by Blacklist.lua attachment.
    for i = 3, 6 do
        local f = CreateFrame("Frame", nil, self.ViewContainer)
        f:SetAllPoints()
        f:Hide()
        self.views[i] = f
    end
    -- Initialize the MVP Module
    self:BuildMVPView()
end

-- =========================================================================
-- UI: HOME VIEW
-- =========================================================================

function GR:BuildHomeView()
    local parent = CreateFrame("Frame", "GRS_HomeView", self.ViewContainer)
    parent:SetPoint("TOPLEFT", 0, -30) 
    parent:SetPoint("BOTTOMRIGHT", 0, 0)
    self.views[1] = parent

    local outerScroll = CreateFrame("ScrollFrame", "GRS_OuterScroll", parent, "UIPanelScrollFrameTemplate")
    outerScroll:SetPoint("TOPLEFT", 0, 0)
    outerScroll:SetPoint("BOTTOMRIGHT", -28, 25) 
    
    if outerScroll.ScrollBar then outerScroll.ScrollBar:Hide(); outerScroll.ScrollBar:SetWidth(0) end
    
    local content = CreateFrame("Frame", "GRS_ScrollChild", outerScroll)
    outerScroll:SetScrollChild(content)
    
    local left = CreateFrame("Frame", nil, content)
    left:SetWidth(320); left:SetPoint("TOPLEFT"); left:SetPoint("BOTTOMLEFT")
    CreateBg(left, 0.1, 0.1, 0.1, 0.5); CreateBorder(left, 0.2, 0.2, 0.2, 1)
    self:BuildLeftPane(left)

    local rightPane = CreateFrame("Frame", "GRS_RightPane", content)
    rightPane:SetWidth(500)
    rightPane:SetPoint("TOPRIGHT"); rightPane:SetPoint("BOTTOMRIGHT")
    CreateBg(rightPane, 0.05, 0.05, 0.05, 0.8)
    CreateBorder(rightPane, 0.2, 0.2, 0.2, 1)
    self:BuildWhisperPane(rightPane)

    local center = CreateFrame("Frame", "GRS_CenterPane", content)
    center:SetPoint("TOPLEFT", left, "TOPRIGHT")
    center:SetPoint("BOTTOMRIGHT", rightPane, "BOTTOMLEFT")
    self:BuildCenterPane(center)
    
    if self.BuildFilterUI then self:BuildFilterUI() end
    
    parent:SetScript("OnSizeChanged", function(self, w, h)
        local scrollW = w - 52
        local scrollH = h - 45
        local leftPaneW = 320
        local rightPaneW = 500 
        local minCenterW = 760 
        local requiredMinW = leftPaneW + minCenterW + rightPaneW
        local finalContentW = math.max(scrollW, requiredMinW)
        local finalH = math.max(scrollH, 1)
        
        content:SetWidth(finalContentW)
        content:SetHeight(finalH)
        
        local listAvailable = finalH - 115
        if listAvailable < 20 then listAvailable = 20 end

        local whisperAvailable = finalH - 50
        if whisperAvailable < 20 then whisperAvailable = 20 end

        if GR.UpdateResultsLayout then GR:UpdateResultsLayout(listAvailable) end
        if GR.UpdateWhisperLayout then GR:UpdateWhisperLayout(whisperAvailable) end
    end)
    
    GR.UpdateHomeLayout = function()
        local w, h = parent:GetSize()
        parent:GetScript("OnSizeChanged")(parent, w, h)
    end
end

-- =========================================================================
-- UI: PANES (Left, Center, Whisper)
-- =========================================================================

function GR:BuildLeftPane(parent)
    local y = -15
    local function AddText(txt, font, dy)
        local t = parent:CreateFontString(nil, "OVERLAY", font)
        t:SetPoint("TOPLEFT", 15, y + (dy or 0)); t:SetText(txt)
    end
    
    AddText("SEARCH FILTERS", "GameFontNormal", 0); y = y - 30
    
    local dFilt = CreateFrame("Button", nil, parent); CreateBg(dFilt, 0.2, 0.2, 0.2, 1)
    dFilt:SetSize(180, 24); dFilt:SetPoint("TOPLEFT", 15, y)
    local dFiltTxt = dFilt:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); dFiltTxt:SetPoint("LEFT", 5, 0); dFiltTxt:SetText("Filter: Default (All)")
    self.dFiltTxt = dFiltTxt
    
    local dFiltArrow = dFilt:CreateTexture(nil, "ARTWORK")
    dFiltArrow:SetTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Up")
    dFiltArrow:SetSize(20, 20)
    dFiltArrow:SetPoint("RIGHT", -2, 0)
    
    local dFiltList = CreateFrame("Frame", nil, dFilt); CreateBg(dFiltList, 0.1, 0.1, 0.1, 1); CreateBorder(dFiltList, 0.5, 0.5, 0.5, 1)
    dFiltList:SetSize(180, 50); dFiltList:SetPoint("TOPLEFT", dFilt, "BOTTOMLEFT", 0, -2); dFiltList:SetFrameStrata("FULLSCREEN_DIALOG"); dFiltList:Hide()
    self.dFiltList = dFiltList; 
    -- RefreshMainFilterList is logic, handled in Engine.lua
    if GR.RefreshMainFilterList then GR:RefreshMainFilterList() end
    
    dFilt:SetScript("OnClick", function() 
        if GR.RefreshMainFilterList then GR:RefreshMainFilterList() end
        dFiltList:SetShown(not dFiltList:IsShown()) 
    end)
    
    local cIcon = CreateFrame("Button", nil, parent); cIcon:SetSize(24, 24); cIcon:SetPoint("LEFT", dFilt, "RIGHT", 5, 0)
    cIcon:SetNormalTexture("Interface\\Buttons\\UI-OptionsButton")
    cIcon:SetScript("OnClick", function() if GR.FilterFrame then GR.FilterFrame.OpenCreate() end end)

    local eIcon = CreateFrame("Button", nil, parent); eIcon:SetSize(24, 24); eIcon:SetPoint("LEFT", cIcon, "RIGHT", 2, 0)
    eIcon:SetNormalTexture("Interface\\Buttons\\UI-GuildButton-PublicNote-Up") 
    eIcon:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight")
    eIcon:SetScript("OnClick", function() 
        if GR.selectedFilterData then 
            GR.FilterFrame.OpenEdit(GR.selectedFilterData)
        else
            print("|cffff0000GRS: Cannot edit Default filter. Select a custom filter first.|r")
        end
    end)
    
    y = y - 40; AddText("Level Range", "GameFontHighlightSmall", 0)
    local minB = CreateFrame("EditBox", nil, parent, "InputBoxTemplate"); minB:SetSize(40, 20); minB:SetPoint("TOPLEFT", 15, y - 20); minB:SetNumeric(true); minB:SetText(self.db.minLevel)
    minB:SetAutoFocus(false)
    minB:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)
    minB:SetScript("OnEnterPressed", function(self) self:ClearFocus() end)
    minB:SetScript("OnTextChanged", function(e) self.db.minLevel = tonumber(e:GetText()) or 70 end)
    
    local maxB = CreateFrame("EditBox", nil, parent, "InputBoxTemplate"); maxB:SetSize(40, 20); maxB:SetPoint("LEFT", minB, "RIGHT", 15, 0); maxB:SetNumeric(true); maxB:SetText(self.db.maxLevel)
    maxB:SetAutoFocus(false)
    maxB:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)
    maxB:SetScript("OnEnterPressed", function(self) self:ClearFocus() end)
    maxB:SetScript("OnTextChanged", function(e) self.db.maxLevel = tonumber(e:GetText()) or 80 end)
    
    y = y - 50; AddText("Scan Scope", "GameFontHighlightSmall", 0); y = y - 20
    local function MkRemBtn(text, mode, x)
        local b = CreateFrame("Button", nil, parent); CreateBg(b, 0.2, 0.2, 0.2, 1); b:SetSize(80, 20); b:SetPoint("TOPLEFT", 15 + x, y)
        local t = b:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); t:SetPoint("CENTER"); t:SetText(text)
        b.bg = b.bg
        b:SetScript("OnClick", function() self.db.remixMode = mode; self:UpdateRemixVisuals() end)
        return b
    end
    -- [[ RETAIL RENAMED TO WORLD ]]
    self.btnRetail = MkRemBtn("World", "OFF", 0); 
    self.btnAllow = MkRemBtn("All", "ALLOW", 85); 
    -- self.btnRemix = MkRemBtn("Remix", "ONLY", 170) -- COMMENTED OUT
    
    -- [[ TOOLTIPS FOR SEARCH BUTTONS ]]
    self.btnRetail:SetScript("OnEnter", function(s)
        GameTooltip:SetOwner(s, "ANCHOR_RIGHT")
        GameTooltip:SetText("World Mode")
        GameTooltip:AddLine("Addon will search for players that are not inside of a dungeon or raid instance.", 1, 1, 1, true)
        GameTooltip:Show()
    end)
    self.btnRetail:SetScript("OnLeave", function() GameTooltip:Hide() end)

    self.btnAllow:SetScript("OnEnter", function(s)
        GameTooltip:SetOwner(s, "ANCHOR_RIGHT")
        GameTooltip:SetText("|cffff0000WARNING: All Mode|r")
        GameTooltip:AddLine("This will search and whisper players inside dungeons or raids.", 1, 0.5, 0.5, true)
        GameTooltip:AddLine("Some players do not take kindly to this and may report you.", 1, 0.5, 0.5, true)
        GameTooltip:AddLine("All responsibility is with the user of this addon.", 1, 0.2, 0.2, true)
        GameTooltip:Show()
    end)
    self.btnAllow:SetScript("OnLeave", function() GameTooltip:Hide() end)
    
    function GR:UpdateRemixVisuals()
        self.btnRetail.bg:SetColorTexture(0.2,0.2,0.2,1); self.btnAllow.bg:SetColorTexture(0.2,0.2,0.2,1); 
        -- self.btnRemix.bg:SetColorTexture(0.2,0.2,0.2,1) -- COMMENTED OUT
        
        if self.db.remixMode=="OFF" then self.btnRetail.bg:SetColorTexture(0,0.6,0,1) end
        if self.db.remixMode=="ALLOW" then self.btnAllow.bg:SetColorTexture(0,0.6,0,1) end
        -- if self.db.remixMode=="ONLY" then self.btnRemix.bg:SetColorTexture(0,0.6,0,1) end -- COMMENTED OUT
    end
    self:UpdateRemixVisuals()
    
    y = y - 40; AddText("MESSAGE TEMPLATES", "GameFontNormal", 0); y = y - 30
    local dTemp = CreateFrame("Button", nil, parent); CreateBg(dTemp, 0.2, 0.2, 0.2, 1); dTemp:SetSize(200, 24); dTemp:SetPoint("TOPLEFT", 15, y)
    local dTempTxt = dTemp:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); dTempTxt:SetPoint("LEFT", 5, 0); dTempTxt:SetText(self.db.messageTemplate)
    
    local dTempArrow = dTemp:CreateTexture(nil, "ARTWORK")
    dTempArrow:SetTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Up")
    dTempArrow:SetSize(20, 20)
    dTempArrow:SetPoint("RIGHT", -2, 0)
    
    local dTempList = CreateFrame("Frame", nil, dTemp); CreateBg(dTempList, 0.1, 0.1, 0.1, 1); CreateBorder(dTempList, 0.5, 0.5, 0.5, 1)
    dTempList:SetSize(200, 100); dTempList:SetPoint("TOPLEFT", dTemp, "BOTTOMLEFT", 0, -2); dTempList:SetFrameStrata("FULLSCREEN_DIALOG"); dTempList:Hide()
    
    dTemp:SetScript("OnClick", function() 
        local kids = {dTempList:GetChildren()}; for _, k in ipairs(kids) do k:Hide() end
        local ty = -5
        for k, v in pairs(GR.db.templates) do
            local b = CreateFrame("Button", nil, dTempList); b:SetSize(190, 20); b:SetPoint("TOPLEFT", 5, ty)
            local t = b:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); t:SetPoint("LEFT"); t:SetText(k)
            b:SetScript("OnClick", function() 
                GR.db.messageTemplate = k; dTempTxt:SetText(k); GR.InputBody:SetText(v); GR.InputName:SetText(k); dTempList:Hide() 
                if GR.InputBody:GetScript("OnTextChanged") then
                     GR.InputBody:GetScript("OnTextChanged")(GR.InputBody)
                end
                if GR.InputName:GetScript("OnTextChanged") then
                     GR.InputName:GetScript("OnTextChanged")(GR.InputName)
                end
            end)
            ty = ty - 20
        end
        dTempList:SetHeight(math.abs(ty) + 5)
        dTempList:SetShown(not dTempList:IsShown()) 
    end)
    
    local btnNew = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    btnNew:SetSize(50, 22); btnNew:SetPoint("LEFT", dTemp, "RIGHT", 5, 0); btnNew:SetText("New")
    btnNew:SetScript("OnClick", function() GR.InputName:SetText(""); GR.InputBody:SetText(""); GR.InputName:SetFocus() end)
    SkinButton(btnNew)

    y = y - 30
    local nameIn = CreateFrame("EditBox", nil, parent, "InputBoxTemplate")
    nameIn:SetSize(250, 20); nameIn:SetPoint("TOPLEFT", 15, y); nameIn:SetAutoFocus(false)
    nameIn:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)
    self.InputName = nameIn
    local ph = nameIn:CreateFontString(nil, "ARTWORK", "GameFontDisable"); ph:SetPoint("LEFT", 5, 0); ph:SetText("Template Name...")
    
    nameIn:SetScript("OnTextChanged", function(self) 
        if self:GetText() ~= "" then ph:Hide() else ph:Show() end 
    end)
    
    nameIn:SetScript("OnEditFocusGained", function() ph:Hide() end)
    nameIn:SetScript("OnEditFocusLost", function(s) if s:GetText()=="" then ph:Show() end end)
    
    y = y - 30
    -- FIXED: REDUCED CONTAINER WIDTH 275 -> 260
    local bodyF = CreateFrame("Frame", nil, parent); CreateBg(bodyF, 0.1, 0.1, 0.1, 0.5); bodyF:SetSize(260, 100); bodyF:SetPoint("TOPLEFT", 15, y)
    
    -- [[ FIXED LAYOUT FOR MESSAGE TEMPLATE BOX ]]
    local scrollM = CreateFrame("ScrollFrame", nil, bodyF, "UIPanelScrollFrameTemplate")
    scrollM:SetPoint("TOPLEFT", 5, -5)
    scrollM:SetPoint("BOTTOMRIGHT", -20, 5) -- Default gap for scrollbar
    
    -- 1. Offset Scrollbar Right (by 26px)
    if scrollM.ScrollBar then
        scrollM.ScrollBar:ClearAllPoints()
        scrollM.ScrollBar:SetPoint("TOPLEFT", scrollM, "TOPRIGHT", 28, -16) 
        scrollM.ScrollBar:SetPoint("BOTTOMLEFT", scrollM, "BOTTOMRIGHT", 28, 16)
    end

    local editM = CreateFrame("EditBox", nil, scrollM)
    -- 2. Width 225 (Fits nicely in 260 container with margins)
    editM:SetSize(225, 100) 
    editM:SetMultiLine(true)
    editM:SetFontObject(ChatFontNormal) 
    editM:SetMaxLetters(255)
    editM:SetAutoFocus(false) 
    
    editM:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)
    editM:SetText(self.db.templates[self.db.messageTemplate] or "")
    scrollM:SetScrollChild(editM)
    self.InputBody = editM

    -- 3. Click container to focus
    bodyF:SetScript("OnMouseDown", function()
        editM:SetFocus()
    end)

    local charCount = bodyF:CreateFontString(nil, "OVERLAY", "GameFontDisableSmall")
    charCount:SetPoint("BOTTOMRIGHT", -30, 2)
    
    local function UpdateCharCount()
        local len = string.len(editM:GetText() or "")
        charCount:SetText(len .. " / 255")
        if len >= 255 then charCount:SetTextColor(1, 0.2, 0.2) else charCount:SetTextColor(0.5, 0.5, 0.5) end
    end
    
    editM:SetScript("OnTextChanged", function(self)
        UpdateCharCount()
    end)
    
    -- 4. Focus resets cursor to start
    editM:SetScript("OnEditFocusGained", function(self) 
        self:SetCursorPosition(0)
        UpdateCharCount()
    end) 
    
    UpdateCharCount() 
    
    y = y - 110
    local btnSave = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate"); btnSave:SetSize(80, 22); btnSave:SetPoint("TOPLEFT", 15, y); btnSave:SetText("Save")
    btnSave:SetScript("OnClick", function()
        local n, b = self.InputName:GetText(), self.InputBody:GetText()
        if n ~= "" and b ~= "" then
            self.db.templates[n] = b; self.db.messageTemplate = n; dTempTxt:SetText(n); print("Saved Template: " .. n)
        end
    end)
    SkinButton(btnSave)

    -- HELP BUTTON
    local btnHelp = CreateFrame("Button", nil, parent)
    btnHelp:SetSize(80, 22)
    btnHelp:SetPoint("LEFT", btnSave, "RIGHT", 5, 0)
    
    -- Custom Red Skinning
    btnHelp:SetNormalTexture("")
    btnHelp:SetHighlightTexture("")
    btnHelp:SetPushedTexture("")
    btnHelp:SetDisabledTexture("")
    CreateBg(btnHelp, 0.4, 0.0, 0.0, 1)
    CreateBorder(btnHelp, 0, 0, 0, 1)
    
    local hText = btnHelp:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    hText:SetPoint("CENTER"); hText:SetText("HELP"); hText:SetTextColor(1, 1, 1) 
    btnHelp:SetFontString(hText)
    
    btnHelp:SetScript("OnClick", function()
        if GR.HelpFrame then GR.HelpFrame:SetShown(not GR.HelpFrame:IsShown()) else GR:BuildHelpPopup() end
    end)
    
    btnHelp:SetScript("OnEnter", function(s) if s.bg then s.bg:SetColorTexture(0.6, 0.1, 0.1, 1) end end)
    btnHelp:SetScript("OnLeave", function(s) if s.bg then s.bg:SetColorTexture(0.4, 0.0, 0.0, 1) end end)
    btnHelp:SetScript("OnMouseDown", function(s) if s.bg then s.bg:SetColorTexture(0.2, 0.0, 0.0, 1) end end)
    btnHelp:SetScript("OnMouseUp", function(s) if s.bg then s.bg:SetColorTexture(0.6, 0.1, 0.1, 1) end end)

    -- TEST BUTTON (UPDATED WITH EXPLICIT LIST)
    local btnTest = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    btnTest:SetSize(165, 22)
    btnTest:SetPoint("TOPLEFT", btnSave, "BOTTOMLEFT", 0, -5)
    btnTest:SetText("TEST ME")
    btnTest:SetScript("OnClick", function()
        if not GR.InputBody then return end
        local msg = GR.InputBody:GetText()
        if not msg or msg == "" then print("Template is empty."); return end
        
        local myName = UnitName("player")
        local myClass = UnitClass("player")
        local myGuild = GetGuildInfo("player") or "Guild"
        
        -- [[ PLACEHOLDER REPLACEMENT LOGIC (DUMB-PROOFED) ]]
        -- 1. Target Name (Variations) -> Becomes My Name for Test
        msg = msg:gsub("%[player%]", myName)
        msg = msg:gsub("%[Player%]", myName)
        msg = msg:gsub("%[PLAYER%]", myName)
        msg = msg:gsub("%[ player %]", myName)
        msg = msg:gsub("%[ Player %]", myName)
        msg = msg:gsub("%[ PLAYER %]", myName)
        
        -- 2. Own Name (Variations)
        msg = msg:gsub("%[ownname%]", myName)
        msg = msg:gsub("%[OwnName%]", myName)
        msg = msg:gsub("%[Ownname%]", myName)
        msg = msg:gsub("%[OWNNAME%]", myName)
        msg = msg:gsub("%[own name%]", myName)
        msg = msg:gsub("%[Own Name%]", myName)
        msg = msg:gsub("%[OWN NAME%]", myName)
        
        -- 3. Guild (Variations)
        msg = msg:gsub("%[guild%]", myGuild)
        msg = msg:gsub("%[Guild%]", myGuild)
        msg = msg:gsub("%[GUILD%]", myGuild)
        
        -- 4. Class (Variations)
        msg = msg:gsub("%[playerclass%]", myClass)
        msg = msg:gsub("%[PlayerClass%]", myClass)
        msg = msg:gsub("%[Playerclass%]", myClass)
        msg = msg:gsub("%[PLAYERCLASS%]", myClass)
        msg = msg:gsub("%[player class%]", myClass)
        msg = msg:gsub("%[Player Class%]", myClass)
        msg = msg:gsub("%[Player class%]", myClass)
        msg = msg:gsub("%[class%]", myClass)
        msg = msg:gsub("%[Class%]", myClass)
        msg = msg:gsub("%[CLASS%]", myClass)
        
        SendChatMessage(msg, "WHISPER", nil, myName)
        print("GRS: Test message sent to self.")
    end)
    SkinButton(btnTest)
    
    -- =========================================================================
    -- NEW: AUTOMATED WELCOME MESSAGE CONFIGURATION
    -- =========================================================================
    
    -- 1. Checkbox for Automation
    local chkWelcome = CreateFrame("CheckButton", nil, parent, "UICheckButtonTemplate")
    chkWelcome:SetSize(24, 24)
    chkWelcome:SetPoint("TOPLEFT", btnTest, "BOTTOMLEFT", 0, -20) -- 20px Gap
    
    chkWelcome.text = chkWelcome:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    chkWelcome.text:SetPoint("LEFT", chkWelcome, "RIGHT", 5, 0)
    chkWelcome.text:SetText("Automate Welcome message")
    
    -- Ensure DB table exists (Safety)
    if not self.db.welcomeMessages then self.db.welcomeMessages = {} end
    
    chkWelcome:SetChecked(self.db.automateWelcome or false)
    chkWelcome:SetScript("OnClick", function(s)
        self.db.automateWelcome = s:GetChecked()
    end)
    GR.WelcomeCheck = chkWelcome
    
    -- 2. Five EditBoxes for Random Rotation
    local wY = -10 -- Offset relative to Checkbox
    self.WelcomeInputs = {}
    
    for i = 1, 5 do
        local wb = CreateFrame("EditBox", nil, parent, "InputBoxTemplate")
        wb:SetSize(240, 20) 
        wb:SetPoint("TOPLEFT", chkWelcome, "BOTTOMLEFT", 5, wY)
        wb:SetAutoFocus(false)
        wb:SetScript("OnEscapePressed", function(s) s:ClearFocus() end)
        wb:SetScript("OnEnterPressed", function(s) s:ClearFocus() end)
        
        -- Load saved message
        wb:SetText(self.db.welcomeMessages[i] or "")
        
        wb:SetScript("OnTextChanged", function(s)
            self.db.welcomeMessages[i] = s:GetText()
        end)
        
        self.WelcomeInputs[i] = wb
        wY = wY - 25 -- Stack them downwards
    end
    
    -- 3. Test G Message Button
    local btnTestG = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    btnTestG:SetSize(120, 22)
    btnTestG:SetPoint("TOPLEFT", self.WelcomeInputs[5], "BOTTOMLEFT", 0, -5)
    btnTestG:SetText("Test G message")
    
    btnTestG:SetScript("OnClick", function()
        -- Gather candidates
        local candidates = {}
        for i=1, 5 do
            local txt = self.db.welcomeMessages[i]
            if txt and txt ~= "" then
                table.insert(candidates, txt)
            end
        end
        
        if #candidates == 0 then
            print("GRS: No welcome messages configured.")
            return
        end
        
        -- Logic: No same message > 3 times back-to-back
        -- We need a persistent state for this logic attached to GR
        if not GR.welcomeState then GR.welcomeState = {lastIdx = 0, repeatCount = 0} end
        
        local idx
        -- Simple RNG with streak breaking protection
        if #candidates > 1 then
             idx = math.random(1, #candidates)
             if idx == GR.welcomeState.lastIdx then
                 GR.welcomeState.repeatCount = GR.welcomeState.repeatCount + 1
             else
                 GR.welcomeState.repeatCount = 0
             end
             
             -- If we hit the limit (3 repeats means 4 times total, instruction said "more than 3 times back-to-back")
             if GR.welcomeState.repeatCount >= 3 then
                 -- Force a reroll until distinct
                 local safety = 0
                 repeat
                     idx = math.random(1, #candidates)
                     safety = safety + 1
                 until idx ~= GR.welcomeState.lastIdx or safety > 10
                 GR.welcomeState.repeatCount = 0
             end
        else
             idx = 1
        end
        
        GR.welcomeState.lastIdx = idx
        local raw = candidates[idx]
        
        -- Placeholder replacement (Standardized)
        local myName = UnitName("player")
        local myGuild = GetGuildInfo("player") or "Guild"
        local myClass = UnitClass("player")
        
        -- In a real welcome, [player] is the new guy. In test, it's me.
        local msg = raw
        msg = msg:gsub("%[player%]", myName)
        msg = msg:gsub("%[Player%]", myName)
        msg = msg:gsub("%[ownname%]", myName)
        msg = msg:gsub("%[OwnName%]", myName)
        msg = msg:gsub("%[guild%]", myGuild)
        msg = msg:gsub("%[Guild%]", myGuild)
        msg = msg:gsub("%[playerclass%]", myClass)
        msg = msg:gsub("%[PlayerClass%]", myClass)
        
        SendChatMessage(msg, "WHISPER", nil, myName)
        print("GRS: Test Guild Welcome sent to self: " .. msg)
    end)
    SkinButton(btnTestG)
end

function GR:BuildHelpPopup()
    local f = CreateFrame("Frame", "GRS_HelpPopup", UIParent)
    f:SetSize(400, 300)
    f:SetPoint("CENTER")
    f:SetFrameStrata("FULLSCREEN_DIALOG")
    CreateBg(f, 0, 0, 0, 0.95)
    CreateBorder(f, 0.5, 0.5, 0.5, 1)
    
    local close = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    close:SetPoint("TOPRIGHT", -5, -5)
    
    local title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    title:SetPoint("TOP", 0, -15)
    title:SetText("Template Help")
    
    local content = f:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    content:SetPoint("TOPLEFT", 20, -50)
    content:SetPoint("BOTTOMRIGHT", -20, 20)
    content:SetJustifyH("LEFT")
    content:SetJustifyV("TOP")
    
    local helpText = 
        "Extra functionalities for the message template:\n\n" ..
        "|cff00ffff[player]|r - Scans and mentions the players name.\n" ..
        "|cff00ffff[ownname]|r - Scans and mentions YOUR name.\n" ..
        "|cff00ffff[Guild]|r - Scans and mentions your guilds name.\n" ..
        "|cff00ffff[playerclass]|r - Scans and mentions players class.\n"
    
    content:SetText(helpText)
    
    GR.HelpFrame = f
end

function GR:BuildCenterPane(parent)
    self.ResultsHeader = parent:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    self.ResultsHeader:SetPoint("TOPLEFT", 15, -15); self.ResultsHeader:SetText("Unguilded Players - Current Filter: Default (All)")
    
    local sBtn = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    sBtn:SetSize(140, 30); sBtn:SetPoint("TOPRIGHT", -15, -10); sBtn:SetText("Search Players")
    self.SearchBtn = sBtn 
    sBtn:SetScript("OnClick", function() self:StartSearch() end)
    SkinButton(sBtn) 
    
    local rListBtn = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    rListBtn:SetSize(100, 30)
    rListBtn:SetPoint("RIGHT", sBtn, "LEFT", -5, 0)
    rListBtn:SetText("Reset List")
    rListBtn:SetScript("OnClick", function()
        GR.foundPlayers = {}
        GR:UpdateScrollFrame()
        if GR.StatusText then GR.StatusText:SetText("List Discarded.") end
    end)
    SkinButton(rListBtn)

    local headF = CreateFrame("Frame", nil, parent); headF:SetSize(750, 20); headF:SetPoint("TOPLEFT", 21, -45) 

    local selectAll = CreateFrame("CheckButton", nil, headF, "UICheckButtonTemplate")
    selectAll:SetSize(20, 20)
    selectAll:SetPoint("LEFT", 0, 0)
    selectAll:SetScript("OnClick", function(self)
        local state = self:GetChecked()
        for _, p in ipairs(GR.foundPlayers) do
            p.selected = state
        end
        GR:UpdateScrollFrame()
    end)
    
    local headers = {
        {text="Name", key="name", width=110}, 
        {text="Race", key="race", width=90},  
        {text="Class", key="fullClass", width=100},
        {text="Level", key="level", width=40}, 
        {text="Max Key", key="maxKey", width=70}, 
        {text="Zone", key="zone", width=110}, 
        {text="Score", key="rio", width=70},  
        {text="Heroic", key="heroic", width=70}, 
        {text="Mythic", key="mythic", width=70}  
    }
    
    local lastH = nil
    for i, data in ipairs(headers) do
        local btn = CreateFrame("Button", nil, headF)
        btn:SetSize(data.width, 20)
        
        if i==1 then 
            btn:SetPoint("LEFT", 30, 0) 
        else 
            btn:SetPoint("LEFT", lastH, "RIGHT", 0, 0) 
        end
        
        local txt = btn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        txt:SetPoint("LEFT", 0, 0)
        txt:SetText(data.text)
        btn:SetFontString(txt)
        
        btn:SetScript("OnEnter", function(s) 
            s:GetFontString():SetTextColor(1, 1, 1) 
        end)
        btn:SetScript("OnLeave", function(s) 
            s:GetFontString():SetTextColor(1, 0.82, 0) 
        end)
        
        btn:SetScript("OnClick", function() 
            GR:SortPlayers(data.key) 
        end)
        
        lastH = btn
    end
    
    local bot = CreateFrame("Frame", nil, parent); bot:SetHeight(40)
    bot:SetPoint("BOTTOMLEFT", 15, 5)
    bot:SetPoint("BOTTOMRIGHT", -15, 5)
    
    local slL = bot:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall"); slL:SetPoint("LEFT", 0, 0); slL:SetText("Msg Delay: 0.8s")
    local sl = CreateFrame("Slider", nil, bot, "OptionsSliderTemplate")
    sl:SetPoint("LEFT", slL, "RIGHT", 10, 0); sl:SetWidth(150); sl:SetMinMaxValues(0.5, 1.0); sl:SetValue(0.8); sl:SetValueStep(0.1); sl:SetObeyStepOnDrag(true)
    sl:SetScript("OnValueChanged", function(s,v) v=math.floor(v*10)/10; self.db.scanDelay=v; slL:SetText("Msg Delay: "..v.."s") end)
    
    local snd = CreateFrame("Button", nil, bot, "UIPanelButtonTemplate"); snd:SetSize(120, 30); snd:SetPoint("RIGHT", -10, 0); snd:SetText("Send Batch")
    snd:SetScript("OnClick", function() self:SendMessageSequence() end)
    SkinButton(snd) 

    local btnBL = CreateFrame("Button", nil, bot, "UIPanelButtonTemplate")
    btnBL:SetSize(130, 30)
    btnBL:SetPoint("RIGHT", snd, "LEFT", -10, 0)
    btnBL:SetText("Blacklist Selected")
    btnBL:SetScript("OnClick", function() self:ManualBlacklist() end)
    SkinButton(btnBL)

    self.StatusText = bot:CreateFontString(nil,"OVERLAY","GameFontNormal"); 
    self.StatusText:SetPoint("RIGHT", btnBL, "LEFT", -20, 0); 
    self.StatusText:SetText("Ready.")
    
    -- =========================================================================
    -- LAYERING FIX: Separate Backdrop from Scroll Logic
    -- =========================================================================
    
    -- 1. Create the Backdrop "Slab" first
    -- This frame sits at the bottom and holds the black background texture
    local listBackdrop = CreateFrame("Frame", nil, parent)
    listBackdrop:SetPoint("TOPLEFT", headF, "BOTTOMLEFT", 0, -5)
    listBackdrop:SetPoint("BOTTOMRIGHT", bot, "TOPRIGHT", -5, 5)
    listBackdrop:SetFrameLevel(parent:GetFrameLevel() + 1) -- Just above parent
    
    -- Apply background to THIS frame, not the scroll frame
    CreateBg(listBackdrop, 0, 0, 0, 0.8) 
    self.listBackdrop = listBackdrop

    -- 2. Create the Logical ScrollFrame
    self.scroll = CreateFrame("ScrollFrame", "GRS_S", parent, "FauxScrollFrameTemplate")
    parent.scrollFrame = self.scroll
    parent.scroll = self.scroll 
    local scrollFrame = self.scroll 
    
    -- Anchor scrollframe to the backdrop
    scrollFrame:SetAllPoints(listBackdrop)
    
    -- Ensure scroll logic sits ABOVE the backdrop
    scrollFrame:SetFrameLevel(listBackdrop:GetFrameLevel() + 5)
    
    -- ScrollBar Styling
    local scrollBar = _G["GRS_SScrollBar"]
    if scrollBar then
        CreateBg(scrollBar, 0.1, 0.1, 0.1, 0.8) 
    end

    scrollFrame:SetScript("OnVerticalScroll", function(s, offset)
        FauxScrollFrame_OnVerticalScroll(s, offset, 20, function() self:UpdateScrollFrame() end)
    end)
    
    scrollFrame:EnableMouseWheel(true)
    
    parent:SetScript("OnSizeChanged", function(frame, w, h)
        local sFrame = scrollFrame or frame.scrollFrame or frame.scroll
        if not sFrame then return end

        local availableW = w - 30 
        local MAX_WIDTH = 760 
        
        if availableW > MAX_WIDTH then
            bot:ClearAllPoints()
            bot:SetPoint("BOTTOMLEFT", 15, 5)
            bot:SetWidth(MAX_WIDTH)
            
            -- Update Backdrop
            if self.listBackdrop then
                self.listBackdrop:ClearAllPoints()
                self.listBackdrop:SetPoint("TOPLEFT", headF, "BOTTOMLEFT", 0, -5)
                self.listBackdrop:SetPoint("BOTTOMLEFT", bot, "TOPLEFT", 0, 5)
                self.listBackdrop:SetWidth(MAX_WIDTH)
            end
            
            -- Snap Scroll to Backdrop
            sFrame:ClearAllPoints()
            sFrame:SetAllPoints(self.listBackdrop)
        else
            bot:ClearAllPoints()
            bot:SetPoint("BOTTOMLEFT", 15, 5)
            bot:SetPoint("BOTTOMRIGHT", -15, 5)
            
            -- Update Backdrop
            if self.listBackdrop then
                self.listBackdrop:ClearAllPoints()
                self.listBackdrop:SetPoint("TOPLEFT", headF, "BOTTOMLEFT", 0, -5)
                self.listBackdrop:SetPoint("BOTTOMRIGHT", bot, "TOPRIGHT", -5, 5)
            end
            
            -- Snap Scroll to Backdrop
            sFrame:ClearAllPoints()
            sFrame:SetAllPoints(self.listBackdrop)
        end
    end)
    
    self.rows = {}
    
    function GR:UpdateResultsLayout(height)
        if not height then height = self.scroll:GetHeight() end
        local numRows = math.floor(height / 20)
        self.visibleRows = numRows 
        
        for i = 1, numRows do
            if not self.rows[i] then
                local r = CreateFrame("Button", nil, parent)
                -- Force rows to sit above the backdrop (ScrollFrame level + 1)
                r:SetFrameLevel(self.scroll:GetFrameLevel() + 1)
                
                r:SetHeight(20); 
                r:SetPoint("LEFT", 41, 0); 
                r:SetPoint("RIGHT", -25, 0)
                if i==1 then r:SetPoint("TOP", self.scroll, "TOP") else r:SetPoint("TOP", self.rows[i-1], "BOTTOM") end
                
                r.c = CreateFrame("CheckButton", nil, r, "UICheckButtonTemplate"); r.c:SetSize(20,20); r.c:SetPoint("LEFT", -20, 0)
                r.c:SetScript("OnClick", function(b) if r.d then r.d.selected=b:GetChecked() end end)
                
                r.n = r:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall"); r.n:SetPoint("LEFT",10,0); r.n:SetWidth(110); r.n:SetJustifyH("LEFT")
                r.ra = r:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall"); r.ra:SetPoint("LEFT",r.n,"RIGHT"); r.ra:SetWidth(90); r.ra:SetJustifyH("LEFT")
                r.cl = r:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall"); r.cl:SetPoint("LEFT",r.ra,"RIGHT"); r.cl:SetWidth(100); r.cl:SetJustifyH("LEFT")
                
                r.lvl = r:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall"); r.lvl:SetPoint("LEFT",r.cl,"RIGHT"); r.lvl:SetWidth(40); r.lvl:SetJustifyH("LEFT")
                r.mk = r:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall"); r.mk:SetPoint("LEFT",r.lvl,"RIGHT"); r.mk:SetWidth(50); r.mk:SetJustifyH("LEFT") 

                r.z = r:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall"); r.z:SetPoint("LEFT",r.mk,"RIGHT", 20, 0); r.z:SetWidth(110); r.z:SetJustifyH("LEFT")
                r.s = r:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall"); r.s:SetPoint("LEFT",r.z,"RIGHT", 10, 0); r.s:SetWidth(70); r.s:SetJustifyH("LEFT")
                r.h = r:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall"); r.h:SetPoint("LEFT",r.s,"RIGHT", 5, 0); r.h:SetWidth(70); r.h:SetJustifyH("LEFT")
                r.m = r:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall"); r.m:SetPoint("LEFT",r.h,"RIGHT", 5, 0); r.m:SetWidth(70); r.m:SetJustifyH("LEFT")
                self.rows[i] = r
            end
        end
        self:UpdateScrollFrame() 
    end
end

function GR:BuildWhisperPane(parent)
    local expandedF = CreateFrame("Frame", nil, parent)
    expandedF:SetAllPoints()
    self.WhisperExpandedFrame = expandedF
    
    local gridH = expandedF:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    gridH:SetPoint("TOPLEFT", 15, -15)
    gridH:SetText("ACTIVE WHISPERS")
    
    local pText = expandedF:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    pText:SetPoint("LEFT", gridH, "RIGHT", 30, 0) 
    pText:SetText("Page 1 / 1")
    self.pageText = pText
    
    local prevBtn = CreateFrame("Button", nil, expandedF)
    prevBtn:SetSize(20, 20)
    prevBtn:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Up")
    prevBtn:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight")
    prevBtn:SetPoint("RIGHT", pText, "LEFT", -5, 0)
    prevBtn:SetScript("OnClick", function() 
        if GR.currentPage > 1 then 
            GR.currentPage = GR.currentPage - 1
            GR:RenderWhisperGrid() 
        end 
    end)
    self.prevBtn = prevBtn
    
    local nextBtn = CreateFrame("Button", nil, expandedF)
    nextBtn:SetSize(20, 20)
    nextBtn:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up")
    nextBtn:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight")
    nextBtn:SetPoint("LEFT", pText, "RIGHT", 5, 0)
    nextBtn:SetScript("OnClick", function() 
        local maxP = math.ceil(#GR.activeChats/(GR.chatPageSize or 4))
        if maxP < 1 then maxP=1 end
        if GR.currentPage < maxP then 
            GR.currentPage = GR.currentPage + 1
            GR:RenderWhisperGrid() 
        end 
    end)
    self.nextBtn = nextBtn

    local pruneBtn = CreateFrame("Button", nil, expandedF, "UIPanelButtonTemplate")
    pruneBtn:SetSize(100, 20)
    pruneBtn:SetPoint("LEFT", nextBtn, "RIGHT", 20, 0)
    pruneBtn:SetText("Prune Inactive")
    pruneBtn:SetScript("OnClick", function() self:PruneInactiveChats() end)
    SkinButton(pruneBtn)
    
    -- [[ REPLIES ONLY CHECKBOX ]]
    local repliesCheck = CreateFrame("CheckButton", nil, expandedF, "UICheckButtonTemplate")
    repliesCheck:SetSize(24, 24)
    repliesCheck:SetPoint("LEFT", pruneBtn, "RIGHT", 10, 0)
    
    repliesCheck.text = repliesCheck:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    repliesCheck.text:SetPoint("LEFT", repliesCheck, "RIGHT", 2, 0)
    repliesCheck.text:SetText("Replies Only")
    
    GR.RepliesOnlyCheck = repliesCheck
    
    self.chatFrames = {}
    local gridBase = CreateFrame("Frame", nil, expandedF)
    gridBase:SetPoint("TOPLEFT", gridH, "BOTTOMLEFT", 0, -10)
    gridBase:SetPoint("BOTTOMRIGHT", -15, 10)
    self.WhisperGridBase = gridBase
    
    function GR:UpdateWhisperLayout(totalHeight)
        self.chatPageSize = 6
        local chatH = 115
        local gap = 10
        
        for i = 1, self.chatPageSize do
            if not self.chatFrames[i] then
                local cf = CreateFrame("Frame", nil, self.WhisperGridBase)
                CreateBg(cf, 0, 0, 0, 0.6)
                CreateBorder(cf, 0.4, 0.4, 0.4, 1)
                cf:SetHeight(chatH); cf:SetPoint("LEFT"); cf:SetPoint("RIGHT")
                
                cf:Hide() 
                
                -- [[ NEW: HEADER WITH UNDERLINE ]]
                cf.headerBtn = CreateFrame("Button", nil, cf); cf.headerBtn:SetPoint("TOPLEFT", 5, -5); cf.headerBtn:SetSize(200, 15)
                cf.headerBtn.text = cf.headerBtn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall"); cf.headerBtn.text:SetPoint("LEFT"); cf.headerBtn.text:SetText("Inactive")
                
                -- Underline Texture
                local ul = cf:CreateTexture(nil, "OVERLAY")
                ul:SetHeight(1)
                ul:SetColorTexture(1, 1, 1, 0.5) -- Semi-transparent white underline
                ul:SetPoint("TOPLEFT", cf.headerBtn.text, "BOTTOMLEFT", 0, -1)
                ul:SetPoint("TOPRIGHT", cf.headerBtn.text, "BOTTOMRIGHT", 20, -1) -- Extend slightly past name
                cf.headerLine = ul
                
                cf.headerBtn:RegisterForClicks("AnyUp") 
                cf.headerBtn:SetScript("OnClick", function(s, button)
                    if not s.playerName then return end
                    if button == "LeftButton" then ChatFrame_SendTell(s.playerName)
                    elseif button == "RightButton" and MenuUtil then
                        MenuUtil.CreateContextMenu(s, function(owner, root)
                            root:CreateTitle(s.playerName)
                            root:CreateButton("Invite to guild", function() C_GuildInfo.Invite(s.playerName) end)
                            -- [[ NEW: Perma-Blacklist ]]
                            root:CreateButton("Perma-Blacklist", function() 
                                if GR.AddToPermaBlacklist then GR:AddToPermaBlacklist(s.playerName) end 
                            end)
                        end)
                    end
                end)
                
                local closeChat = CreateFrame("Button", nil, cf, "UIPanelCloseButton"); closeChat:SetSize(20, 20); closeChat:SetPoint("TOPRIGHT", -2, -2)
                closeChat:SetScript("OnClick", function()
                    local idx = (GR.currentPage - 1) * self.chatPageSize + i
                    if GR.activeChats[idx] then table.remove(GR.activeChats, idx); GR:RenderWhisperGrid() end
                end)
                
                -- [[ MODIFIED SCROLL AREA FOR INPUT BOX ROOM ]]
                cf.scroll = CreateFrame("ScrollFrame", nil, cf, "UIPanelScrollFrameTemplate")
                cf.scroll:SetPoint("TOPLEFT", 5, -25) -- Shifted down for header
                cf.scroll:SetPoint("BOTTOMRIGHT", -25, 28) -- Lifted up for Input Box
                
                -- [[ NEW: 2PX THICK BORDER AROUND TEXT CONTENT ]]
                local borderFrame = CreateFrame("Frame", nil, cf)
                borderFrame:SetPoint("TOPLEFT", cf.scroll, "TOPLEFT", -3, 3)
                borderFrame:SetPoint("BOTTOMRIGHT", cf.scroll, "BOTTOMRIGHT", 23, -3) -- Cover scrollbar area too
                CreateThickBorder(borderFrame, 0.3, 0.3, 0.3, 1, 2)
                
                cf.text = CreateFrame("EditBox", nil, cf.scroll); cf.text:SetMultiLine(true); cf.text:SetFontObject(ChatFontSmall); cf.text:SetWidth(430); cf.text:SetAutoFocus(false); cf.text:EnableMouse(false)
                cf.scroll:SetScrollChild(cf.text)
                
                -- [[ NEW: DIRECT REPLY INPUT BOX ]]
                local replyBox = CreateFrame("EditBox", nil, cf, "InputBoxTemplate")
                replyBox:SetPoint("BOTTOMLEFT", 10, 5)
                replyBox:SetPoint("BOTTOMRIGHT", -10, 5)
                replyBox:SetHeight(20)
                replyBox:SetAutoFocus(false)
                replyBox:SetFontObject("ChatFontSmall")
                
                -- Placeholder text
                replyBox.ph = replyBox:CreateFontString(nil, "ARTWORK", "GameFontDisable")
                replyBox.ph:SetPoint("LEFT", 5, 0)
                replyBox.ph:SetText("Reply...")
                
                replyBox:SetScript("OnEditFocusGained", function(s) s.ph:Hide() end)
                replyBox:SetScript("OnEditFocusLost", function(s) if s:GetText()=="" then s.ph:Show() end end)
                replyBox:SetScript("OnEscapePressed", function(s) s:ClearFocus() end)
                replyBox:SetScript("OnEnterPressed", function(s) 
                    local msg = s:GetText()
                    if msg and msg ~= "" and cf.headerBtn.playerName then
                        SendChatMessage(msg, "WHISPER", nil, cf.headerBtn.playerName)
                        s:SetText("")
                        -- Engine logic handles the update via event loop, but we can optimistically add?
                        -- Better wait for EVENT to prevent dupes, but GRS logic handles that.
                    end
                    s:ClearFocus() 
                end)
                
                cf.replyBox = replyBox
                
                self.chatFrames[i] = cf
            end
            
            if i==1 then 
                self.chatFrames[i]:SetPoint("TOP") 
            else 
                self.chatFrames[i]:SetPoint("TOP", self.chatFrames[i-1], "BOTTOM", 0, -gap) 
            end
        end
        
        for i = self.chatPageSize + 1, #self.chatFrames do
            if self.chatFrames[i] then self.chatFrames[i]:Hide() end
        end
        
        self:RenderWhisperGrid()
    end
end

function GR:UpdateScrollFrame()
    local d = self.foundPlayers
    local rowCount = self.visibleRows or 15
    if rowCount > #self.rows then rowCount = #self.rows end
    
    FauxScrollFrame_Update(self.scroll, #d, rowCount, 20)
    
    local scrollBar = _G["GRS_SScrollBar"]
    if scrollBar then
        scrollBar:Show() 
        
        local _, maxVal = scrollBar:GetMinMaxValues()
        local thumb = scrollBar:GetThumbTexture()
        
        if not maxVal or maxVal == 0 then
             if thumb then thumb:Hide() end
             
             local up = _G["GRS_SScrollBarScrollUpButton"]
             local down = _G["GRS_SScrollBarScrollDownButton"]
             if up then up:Disable() end
             if down then down:Disable() end
        else
             if thumb then thumb:Show() end
             
             local up = _G["GRS_SScrollBarScrollUpButton"]
             local down = _G["GRS_SScrollBarScrollUpButton"]
             if up then up:Enable() end
             if down then down:Enable() end
        end
    end
    
    local offset = FauxScrollFrame_GetOffset(self.scroll)
    
    for i=1, #self.rows do
        local r = self.rows[i]
        if i > rowCount then
            r:Hide()
        else
            local idx = offset + i
            if idx <= #d then
                local p = d[idx]
                r.d = p; r:Show()
                r.n:SetText(p.name); 
                r.lvl:SetText(p.level);
                r.mk:SetText(p.maxKey); 
                
                r.z:SetText(p.zone); r.ra:SetText(p.race or "Unknown")
                local cc = C_ClassColor.GetClassColor(p.classFile or "PRIEST")
                r.cl:SetText(cc and cc:WrapTextInColorCode(p.fullClass) or p.fullClass)
                
                local sc = p.rio or 0; local col = "|cffffffff"
                if sc>=2500 then col="|cffff8000" 
                elseif sc>=2000 then col="|cffa335ee" 
                elseif sc>=1000 then col="|cff0070dd" 
                end
                r.s:SetText(col..sc.."|r")
                
                local function Col(str)
                    if not str or str == "-" then return "|cff808080"..str.."|r" end
                    local k = tonumber(str:match("^(%d+)")) or 0
                    if k >= 8 then return "|cffff8000"..str.."|r"
                    elseif k >= 4 then return "|cffa335ee"..str.."|r"
                    else return "|cff00ff00"..str.."|r" end
                end
                
                r.h:SetText(Col(p.heroic)); r.m:SetText(Col(p.mythic))
                r.c:SetChecked(p.selected)
            else 
                r:Hide() 
            end
        end
    end
end

-- =========================================================================
-- UI: MVP VIEW
-- =========================================================================

function GR:BuildMVPView()
    -- Defined as ID 8 in Constants.lua
    local viewId = 8 
    local parent = CreateFrame("Frame", "GRS_MVPView", self.ViewContainer)
    parent:SetAllPoints()
    parent:Hide()
    self.views[viewId] = parent
    
    -- Main Container Box
    local content = CreateFrame("Frame", nil, parent)
    -- Anchors to stretch horizontally across the parent (Maximum Width)
    content:SetPoint("TOPLEFT", 0, 0)
    content:SetPoint("BOTTOMRIGHT", 0, -1) 
    
    -- [[ BACKGROUND LOGIC ]]
    -- 1. Create Pure Black Backdrop (Sublayer -1)
    local bg = content:CreateTexture(nil, "BACKGROUND", nil, -1)
    bg:SetAllPoints()
    bg:SetColorTexture(0, 0, 0, 0.75) -- Pure Black

    -- 2. Create Logo Texture (Sublayer 1)
    local logo = content:CreateTexture(nil, "BACKGROUND", nil, 1)
    logo:SetPoint("CENTER")
    logo:SetSize(512, 512) -- Standard large icon size to act as wallpaper
    -- Dynamic path using the addonName variable
    logo:SetTexture("Interface\\AddOns\\" .. addonName .. "\\media\\AXIOM_Logo.tga")

    -- Title: MVP's
    local title = content:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    title:SetPoint("TOP", 0, -30)
    title:SetText("MVP's")
    title:SetTextColor(1, 0.82, 0) -- Gold Color
    
    -- Appreciation Note (Re-inserted)
    local subTitle = content:CreateFontString(nil, "OVERLAY", "GameFontHighlightMedium")
    subTitle:SetPoint("TOP", title, "BOTTOM", 0, -15)
    subTitle:SetWidth(600) -- Allow wrapping if necessary
    subTitle:SetText("A special thank you to the legends who helped shape this project.\nYour support has been invaluable.")
    subTitle:SetTextColor(0.9, 0.9, 0.9) -- Soft White
    
    -- The List of MVP Names
    local mvpList = {
        "Malthred",
        "Hahaheehee",
        "Getras",
        "Emaenno",
        "Niels",
        "Blladee",
		"GankerMaster",
		"Messami"
    }
    
    -- [[ CHANGED: HORIZONTAL LIST AT BOTTOM ]]
    -- Concatenate names with a separator
    local namesStr = table.concat(mvpList, "   •   ")
    
    local nameText = content:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    nameText:SetPoint("BOTTOM", 0, 60) -- Positioned at the bottom
    nameText:SetWidth(1000) -- Ensure it has space (though auto-width is default)
    nameText:SetText(namesStr)
    nameText:SetTextColor(0.6, 0.8, 1) -- Aesthetic Light Blue
end