-- =========================================================================
-- FILE: Settings.lua
-- =========================================================================
local addonName, NS = ...

local GR = _G["GRS_MainFrame"] or NS.GR

if not GR then
    print("|cffff0000A.X.I.O.M. Error:|r Main Frame not found in Settings.lua")
    return
end

-- ... [Visual Helpers: SafeCreateBg, SafeCreateBorder, SafeSkinButton, CreateColorSlider omitted for brevity but present in execution] ...
local function SafeCreateBg(f, r, g, b, a) if not f then return end; if f.bg then f.bg:SetColorTexture(r, g, b, a) else local t = f:CreateTexture(nil, "BORDER"); t:SetAllPoints(); t:SetColorTexture(r, g, b, a); f.bg = t end end
local function SafeCreateBorder(f, r, g, b, a) if not f then return end; if f.border then f.border:SetColorTexture(r, g, b, a) else local border = f:CreateTexture(nil, "BACKGROUND"); border:SetPoint("TOPLEFT", -1, 1); border:SetPoint("BOTTOMRIGHT", 1, -1); border:SetColorTexture(r, g, b, a); f.border = border end end
local function SafeSkinButton(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; SafeCreateBg(btn, 0, 0, 0, 1); SafeCreateBorder(btn, 0, 0, 0, 1); if btn.GetFontString and btn:GetFontString() then btn:GetFontString():SetTextColor(1, 1, 1) end; btn:HookScript("OnEnter", function(s) if s.bg then s.bg:SetColorTexture(0.2, 0.2, 0.2, 1) end end); btn:HookScript("OnLeave", function(s) if s.bg then s.bg:SetColorTexture(0, 0, 0, 1) end end) end
local function CreateColorSlider(parent, label, getVal, setVal) local s = CreateFrame("Slider", nil, parent, "OptionsSliderTemplate"); s:SetWidth(180); s:SetHeight(15); s:SetMinMaxValues(0, 1); s:SetValueStep(0.01); s:SetObeyStepOnDrag(true); local txt = s:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); txt:SetPoint("BOTTOMLEFT", s, "TOPLEFT", 0, 2); txt:SetText(label); local val = s:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); val:SetPoint("BOTTOMRIGHT", s, "TOPRIGHT", 0, 2); local n = s:GetName(); if n then if _G[n.."Low"] then _G[n.."Low"]:SetText("") end; if _G[n.."High"] then _G[n.."High"]:SetText("") end; if _G[n.."Text"] then _G[n.."Text"]:SetText("") end end; local initialVal = 0; if getVal then initialVal = getVal() or 0 end; s:SetValue(initialVal); val:SetText(string.format("%.2f", initialVal)); s:SetScript("OnValueChanged", function(self, v) v = math.floor(v * 100 + 0.5) / 100; val:SetText(string.format("%.2f", v)); if setVal then setVal(v) end end); return s end

-- =========================================================================
-- GUILD IMPORT CONSTANTS (Renamed)
-- =========================================================================

GR.GUILD_IMPORT_FIELDS = {
    { key = "Name", label = "Name", idx = 1 },
    { key = "Rank", label = "Rank", idx = 2 },
    { key = "Level", label = "Level", idx = 3 },
    { key = "Class", label = "Class", idx = 4 },
    { key = "Race", label = "Race", idx = 5 },
    { key = "Sex", label = "Sex", idx = 6 },
    { key = "LastOnline", label = "Last Online (Days)", idx = 7 },
    { key = "MainAlt", label = "Main/Alt", idx = 8 },
    { key = "Alts", label = "Player Alts", idx = 9 },
    { key = "JoinDate", label = "Join Date", idx = 10 },
    { key = "PromoDate", label = "Promo Date", idx = 11 },
    { key = "RankHist", label = "Rank History", idx = 12 },
    { key = "Birthday", label = "Birthday", idx = 13 },
    { key = "Rep", label = "Guild Rep", idx = 14 },
    { key = "PubNote", label = "Public Note", idx = 15 },
    { key = "OffNote", label = "Officer Note", idx = 16 },
    { key = "CustNote", label = "Custom Note", idx = 17 },
    { key = "Faction", label = "Faction", idx = 18 },
    { key = "Faction", label = "Faction", idx = 19 },
    { key = "GUID", label = "Player GUID", idx = 20 },
}

local SHORT_MONTHS = { Jan="January", Feb="February", Mar="March", Apr="April", May="May", Jun="June", Jul="July", Aug="August", Sep="September", Oct="October", Nov="November", Dec="December" }
local INV_MONTHS = {}; for k,v in pairs(SHORT_MONTHS) do INV_MONTHS[v] = k end

local function ParseImportDate(dateStr)
    if not dateStr or dateStr == "" then return nil, nil end
    local d, m = string.match(dateStr, "^(%d+)%s+(%a+)")
    if d and m then local fullMonth = SHORT_MONTHS[m] or m; return fullMonth, d end
    return nil, nil
end

local function FormatImportDate(d, m, y)
    if not d or not m then return "" end
    local shortM = string.sub(m, 1, 3); if INV_MONTHS[m] then shortM = INV_MONTHS[m] end
    local yStr = y or date("%y"); return string.format("%s %s '%s", d, shortM, yStr)
end

-- =========================================================================
-- 1. SETTINGS VIEW BUILDER
-- =========================================================================

function GR:BuildSettingsView()
    if not self.db then self.db = {} end
    if not self.db.theme then self.db.theme = {} end
    local d = self.db.theme
    if not d.header then d.header = {r=0.1, g=0.1, b=0.2, a=1} end
    if not d.background then d.background = {r=0.05, g=0.05, b=0.05, a=0.95} end
    if not d.buttons then d.buttons = {r=0.2, g=0.2, b=0.2, a=1} end

    -- Custom Column Visibility defaults
    if not self.db.customColumns then
        self.db.customColumns = {
            grs    = { zone=true, raidN=true, heroic=true },
            roster = { ach=true, ilvl=true, raidN=true, raidH=true },
            socialGrs = { zone=true, raidN=true, heroic=true },
            raidGrs = { zone=true, raidN=true, heroic=true },
        }
    end
    if not self.db.customColumns.socialGrs then
        self.db.customColumns.socialGrs = { zone=true, raidN=true, heroic=true }
    end
    if not self.db.customColumns.raidGrs then
        self.db.customColumns.raidGrs = { zone=true, raidN=true, heroic=true }
    end

    if not self.db.customColumns.pvpRoster then
        self.db.customColumns.pvpRoster = { pvp2v2=true, pvp3v3=true, pvpSolo=true, pvpRbg=true, pvpBest=true, pvpExp=true, pvpSpec=true }
    end

    local parent = CreateFrame("Frame", "GRS_SettingsView", self.ViewContainer)
    parent:SetAllPoints(); parent:Hide(); self.views[7] = parent

    local function UpdateLiveTheme() GR:ApplyTheme(nil) end

    -- =================================================================
    -- HELPER: Styled Checkbox (dark UI-themed toggle)
    -- =================================================================
    local function CreateStyledCheckbox(parentFrame, label, anchorPoint, anchorRelTo, anchorRelPt, xOff, yOff)
        local f = CreateFrame("Button", nil, parentFrame)
        f:SetSize(20, 20)
        if anchorRelTo then
            f:SetPoint(anchorPoint or "TOPLEFT", anchorRelTo, anchorRelPt or "TOPLEFT", xOff or 0, yOff or 0)
        else
            f:SetPoint(anchorPoint or "TOPLEFT", xOff or 0, yOff or 0)
        end
        -- Box background
        local box = f:CreateTexture(nil, "BORDER"); box:SetAllPoints(); box:SetColorTexture(0.08, 0.08, 0.08, 1); f.box = box
        local brd = f:CreateTexture(nil, "BACKGROUND"); brd:SetPoint("TOPLEFT", -1, 1); brd:SetPoint("BOTTOMRIGHT", 1, -1); brd:SetColorTexture(0.35, 0.35, 0.35, 1); f.brd = brd
        -- Check mark (gold)
        local mark = f:CreateTexture(nil, "ARTWORK"); mark:SetSize(14, 14); mark:SetPoint("CENTER"); mark:SetColorTexture(0.85, 0.65, 0, 1); mark:Hide(); f.mark = mark
        -- Label
        if label then
            local txt = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); txt:SetPoint("LEFT", f, "RIGHT", 6, 0); txt:SetText(label); txt:SetTextColor(0.9, 0.9, 0.9); f.label = txt
        end
        f.checked = false
        f.SetChecked = function(self, val) self.checked = val; if val then self.mark:Show(); self.brd:SetColorTexture(0.85, 0.65, 0, 1) else self.mark:Hide(); self.brd:SetColorTexture(0.35, 0.35, 0.35, 1) end end
        f.GetChecked = function(self) return self.checked end
        f:SetScript("OnClick", function(self)
            self.checked = not self.checked
            self:SetChecked(self.checked)
            if self.onClickHandler then self:onClickHandler() end
        end)
        f:SetScript("OnEnter", function(self) if not self.checked then self.box:SetColorTexture(0.15, 0.15, 0.15, 1) end end)
        f:SetScript("OnLeave", function(self) if not self.checked then self.box:SetColorTexture(0.08, 0.08, 0.08, 1) end end)
        return f
    end

    -- =================================================================
    -- HELPER: Custom Styled Dropdown
    -- =================================================================
    local function CreateStyledDropdown(parentFrame, width, items, currentVal, onChange)
        local dd = CreateFrame("Frame", nil, parentFrame)
        dd:SetSize(width, 28)
        SafeCreateBg(dd, 0.06, 0.06, 0.06, 1); SafeCreateBorder(dd, 0.3, 0.3, 0.3, 1)
        local selected = dd:CreateFontString(nil, "OVERLAY", "GameFontHighlight"); selected:SetPoint("LEFT", 10, 0); selected:SetTextColor(1, 1, 1)
        local arrow = dd:CreateFontString(nil, "OVERLAY", "GameFontNormal"); arrow:SetPoint("RIGHT", -8, 0); arrow:SetText("\226\150\188"); arrow:SetTextColor(0.7, 0.7, 0.7)
        dd.selectedValue = currentVal
        -- Find label for current value
        local function UpdateLabel()
            for _, item in ipairs(items) do
                if item.id == dd.selectedValue then selected:SetText(item.label); return end
            end
            selected:SetText(items[1] and items[1].label or "---")
        end
        UpdateLabel()

        -- Dropdown list (initially hidden)
        local list = CreateFrame("Frame", nil, dd)
        list:SetWidth(width); list:SetPoint("TOPLEFT", dd, "BOTTOMLEFT", 0, -2)
        list:SetFrameStrata("FULLSCREEN_DIALOG"); list:SetFrameLevel(200)
        SafeCreateBg(list, 0.05, 0.05, 0.05, 0.98); SafeCreateBorder(list, 0.3, 0.3, 0.3, 1)
        list:Hide(); dd.list = list

        local totalH = 4
        for _, item in ipairs(items) do
            local row = CreateFrame("Button", nil, list)
            row:SetSize(width - 4, 24); row:SetPoint("TOPLEFT", 2, -totalH)
            local rowBg = row:CreateTexture(nil, "BORDER"); rowBg:SetAllPoints(); rowBg:SetColorTexture(0, 0, 0, 0); row.rowBg = rowBg
            local rowTxt = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); rowTxt:SetPoint("LEFT", 8, 0); rowTxt:SetText(item.label); rowTxt:SetTextColor(0.85, 0.85, 0.85)
            -- Glow on hover
            row:SetScript("OnEnter", function(s) s.rowBg:SetColorTexture(0.15, 0.12, 0.02, 0.8) end)
            row:SetScript("OnLeave", function(s) s.rowBg:SetColorTexture(0, 0, 0, 0) end)
            row:SetScript("OnClick", function()
                dd.selectedValue = item.id; UpdateLabel(); list:Hide()
                if onChange then onChange(item.id) end
            end)
            totalH = totalH + 24
        end
        list:SetHeight(totalH + 4)

        -- Toggle list on click
        dd:EnableMouse(true)
        dd:SetScript("OnMouseDown", function() if list:IsShown() then list:Hide() else list:Show() end end)
        dd:SetScript("OnEnter", function() dd.bg:SetColorTexture(0.1, 0.1, 0.1, 1) end)
        dd:SetScript("OnLeave", function() dd.bg:SetColorTexture(0.06, 0.06, 0.06, 1) end)
        -- Close when clicking elsewhere
        list:SetScript("OnShow", function(self) self:SetScript("OnUpdate", function(self)
            if not dd:IsMouseOver() and not self:IsMouseOver() then self:Hide() end
        end) end)
        list:SetScript("OnHide", function(self) self:SetScript("OnUpdate", nil) end)

        dd.SetValue = function(self, val) self.selectedValue = val; UpdateLabel() end
        dd.GetValue = function(self) return self.selectedValue end
        return dd
    end

    -- =================================================================
    -- HELPER: Nav Button (black bg, white label, gold active border)
    -- =================================================================
    local function CreateNavButton(parentFrame, label, yOffset)
        local btn = CreateFrame("Button", nil, parentFrame)
        btn:SetSize(225, 30); btn:SetPoint("TOPLEFT", 10, yOffset)
        btn:SetNormalTexture(""); btn:SetHighlightTexture(""); btn:SetPushedTexture("")
        local bg = btn:CreateTexture(nil, "BORDER"); bg:SetAllPoints(); bg:SetColorTexture(0, 0, 0, 1); btn.bg = bg
        local brd = btn:CreateTexture(nil, "BACKGROUND"); brd:SetPoint("TOPLEFT", -1, 1); brd:SetPoint("BOTTOMRIGHT", 1, -1); brd:SetColorTexture(0.3, 0.3, 0.3, 1); btn.brd = brd
        local txt = btn:CreateFontString(nil, "OVERLAY", "GameFontNormal"); txt:SetPoint("LEFT", 10, 0); txt:SetText(label); txt:SetTextColor(1, 1, 1); btn.label = txt
        btn.isActive = false
        btn:SetScript("OnEnter", function(s) if not s.isActive and s.bg then s.bg:SetColorTexture(0.2, 0.2, 0.2, 1) end end)
        btn:SetScript("OnLeave", function(s) if not s.isActive and s.bg then s.bg:SetColorTexture(0, 0, 0, 1) end end)
        return btn
    end

    -- =================================================================
    -- HELPER: Option Pane (title + description, inside a scroll canvas)
    -- =================================================================
    local function CreateOptionPane(canvas, yOffset, title, description, paneHeight)
        local pane = CreateFrame("Frame", nil, canvas)
        pane:SetPoint("TOPLEFT", 10, yOffset); pane:SetPoint("RIGHT", canvas, "RIGHT", -10, 0)
        pane:SetHeight(paneHeight or 70)
        SafeCreateBg(pane, 0.08, 0.08, 0.08, 0.7); SafeCreateBorder(pane, 0.2, 0.2, 0.2, 1)
        local t = pane:CreateFontString(nil, "OVERLAY", "GameFontNormal"); t:SetPoint("TOPLEFT", 10, -8); t:SetText(title); pane.title = t
        if description then
            local dc = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); dc:SetPoint("TOPLEFT", 10, -26); dc:SetPoint("RIGHT", pane, "RIGHT", -50, 0); dc:SetJustifyH("LEFT"); dc:SetText(description); dc:SetTextColor(0.6, 0.6, 0.6); pane.desc = dc
        end
        return pane
    end

    -- =================================================================
    -- HELPER: Scrollable Sub-Page
    -- =================================================================
    local function CreateSubPage(parentFrame)
        local page = CreateFrame("Frame", nil, parentFrame); page:SetAllPoints(); page:Hide()
        local scroll = CreateFrame("ScrollFrame", nil, page, "UIPanelScrollFrameTemplate")
        scroll:SetPoint("TOPLEFT", 5, -5); scroll:SetPoint("BOTTOMRIGHT", -28, 5)
        if NS.StyleScrollBar then NS.StyleScrollBar(scroll) end
        local canvas = CreateFrame("Frame", nil, scroll); canvas:SetWidth(750); canvas:SetHeight(600)
        scroll:SetScrollChild(canvas)
        scroll:SetScript("OnSizeChanged", function(self, w) canvas:SetWidth(w) end)
        page.scroll = scroll; page.canvas = canvas
        return page
    end

    -- =================================================================
    -- LEFT SIDEBAR (245px)
    -- =================================================================
    local sidebar = CreateFrame("Frame", nil, parent)
    sidebar:SetWidth(245); sidebar:SetPoint("TOPLEFT", 0, -30); sidebar:SetPoint("BOTTOMLEFT", 0, 0)
    SafeCreateBg(sidebar, 0.05, 0.05, 0.05, 0.95); SafeCreateBorder(sidebar, 0.2, 0.2, 0.2, 1)

    -- =================================================================
    -- CENTER PANEL
    -- =================================================================
    local center = CreateFrame("Frame", nil, parent)
    center:SetPoint("TOPLEFT", sidebar, "TOPRIGHT", 0, 0); center:SetPoint("BOTTOMRIGHT", 0, 0)
    SafeCreateBg(center, 0.06, 0.06, 0.06, 0.9)
    self.SettingsCanvas = center

    -- =================================================================
    -- CREATE 6 SUB-PAGES
    -- =================================================================
    local pages = {}
    for i = 1, 6 do pages[i] = CreateSubPage(center) end

    -- =================================================================
    -- NAV BUTTONS
    -- =================================================================
    local categories = {
        NS.L["GENERAL_SETTINGS"] or "General Settings",
        NS.L["UI_MODE"] or "UI Mode",
        NS.L["APPEARANCES"] or "Appearances",
        NS.L["TOOLS"] or "Tools",
        NS.L["LANGUAGE"] or "Language",
        NS.L["ADVANCED"] or "Advanced",
    }
    local navBtns = {}
    local function SelectCategory(index)
        for i = 1, 6 do
            if i == index then
                pages[i]:Show(); navBtns[i].isActive = true
                navBtns[i].bg:SetColorTexture(0.15, 0.15, 0.15, 1); navBtns[i].brd:SetColorTexture(0.8, 0.6, 0, 1)
            else
                pages[i]:Hide(); navBtns[i].isActive = false
                navBtns[i].bg:SetColorTexture(0, 0, 0, 1); navBtns[i].brd:SetColorTexture(0.3, 0.3, 0.3, 1)
            end
        end
    end
    for i, cat in ipairs(categories) do
        local btn = CreateNavButton(sidebar, cat, -15 - ((i - 1) * 40))
        btn:SetScript("OnClick", function() SelectCategory(i) end)
        navBtns[i] = btn
    end

    -- =================================================================
    -- PAGE 1: GENERAL SETTINGS
    -- =================================================================
    do
        local c = pages[1].canvas; local y = -10

        -- Minimap Button
        local p1 = CreateOptionPane(c, y, NS.L["MINIMAP_BUTTON"] or "Minimap Button", "Show or hide the A.X.I.O.M. minimap icon. When hidden, use /axiom to open.", 70)
        local chkMini = CreateStyledCheckbox(p1, "Enabled", "TOPLEFT", nil, nil, 10, -45)
        chkMini:SetChecked(self.db.minimapShown ~= false)
        chkMini.onClickHandler = function(cb) GR.db.minimapShown = cb:GetChecked(); if _G["GRS_MinimapButton"] then if GR.db.minimapShown then _G["GRS_MinimapButton"]:Show() else _G["GRS_MinimapButton"]:Hide() end end end
        y = y - 75

        -- Auto-Open + Default Tab (MERGED)
        local p2 = CreateOptionPane(c, y, NS.L["AUTO_OPEN"] or "Auto-Open & Default Tab", "Configure whether the addon auto-opens on login and which tab it defaults to.", 110)
        local chkAuto = CreateStyledCheckbox(p2, "Auto-Open on Login", "TOPLEFT", nil, nil, 10, -45)
        chkAuto:SetChecked(self.db.autoOpen or false)
        chkAuto.onClickHandler = function(cb) GR.db.autoOpen = cb:GetChecked() end

        -- Default Tab dropdown
        local ddLabel = p2:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); ddLabel:SetPoint("TOPLEFT", 10, -75); ddLabel:SetText("Default Tab:"); ddLabel:SetTextColor(0.7, 0.7, 0.7)
        local tabItems = {}
        for _, tab in ipairs(NS.Constants.TABS) do if tab.id ~= 7 and tab.id ~= 8 then tabItems[#tabItems + 1] = { id = tab.id, label = NS.GetTabTitle(tab) } end end
        if not self.db.defaultTab then self.db.defaultTab = 1 end
        local ddTab = CreateStyledDropdown(p2, 220, tabItems, self.db.defaultTab, function(val) GR.db.defaultTab = val end)
        ddTab:SetPoint("LEFT", ddLabel, "RIGHT", 10, 0)
        y = y - 115

        -- Sound / Notification Toggles (with actual functionality)
        local p3 = CreateOptionPane(c, y, NS.L["SOUND_NOTIFICATIONS"] or "Sound / Notification Toggles", "Mute whisper sounds, recruitment alerts, and other notification sounds.", 80)
        local chkW = CreateStyledCheckbox(p3, NS.L["MUTE_WHISPER"] or "Mute Whisper Sounds", "TOPLEFT", nil, nil, 10, -50)
        chkW:SetChecked(self.db.muteWhisper or false)
        chkW.onClickHandler = function(cb)
            GR.db.muteWhisper = cb:GetChecked()
            if GR.db.muteWhisper then
                MuteSoundFile(3081) -- Whisper received sound
            else
                UnmuteSoundFile(3081)
            end
        end
        local chkA = CreateStyledCheckbox(p3, NS.L["MUTE_ALERTS"] or "Mute Recruitment Alerts", "LEFT", chkW.label, "RIGHT", 30, 0)
        chkA:SetChecked(self.db.muteAlerts or false)
        chkA.onClickHandler = function(cb) GR.db.muteAlerts = cb:GetChecked() end
        y = y - 85

        c:SetHeight(math.abs(y) + 20)
    end

    -- =================================================================
    -- PAGE 2: UI MODE (radio-style, checkboxes in front)
    -- =================================================================
    do
        local c = pages[2].canvas; local y = -10
        if not self.db.guildMode then self.db.guildMode = self.db.socialEnabled and "social" or nil end
        local modeCheckboxes = {}
        local modeApplyBtns = {}
        local modes = {
            { key = "social",  label = NS.L["SOCIAL_GUILD_MODE"] or "Social Guild Mode",  desc = "Activates a variety of options and insights into your members, set personal notes, anniversaries, birthdays and more." },
            { key = "raid",    label = NS.L["RAID_GUILD_MODE"] or "Raid Guild Mode",      desc = "Activates a variety of options with great insight into your members progression and commitment to the guild." },
            { key = "pvp",     label = NS.L["PVP_GUILD_MODE"] or "PVP Guild Mode",        desc = "Activates a variety of options with great insight into your members PVP experience and Achievements." },
            { key = "custom",  label = NS.L["CUSTOM_GUILD_MODE"] or "Custom Guild Mode",  desc = "Set and create your own Guild mode, which insights do you find important?" },
        }
        for _, mode in ipairs(modes) do
            local paneHeight = 70
            if mode.key == "custom" then paneHeight = 380 end
            if mode.key == "social" then paneHeight = 280 end
            if mode.key == "raid" then paneHeight = 280 end
            if mode.key == "pvp" then paneHeight = 280 end
            local pane = CreateOptionPane(c, y, mode.label, mode.desc, paneHeight)
            local chk = CreateStyledCheckbox(pane, nil, "TOPLEFT", nil, nil, 10, -8)
            chk:SetChecked(self.db.guildMode == mode.key)
            chk.modeKey = mode.key
            modeCheckboxes[mode.key] = chk
            -- Shift the title right to make room for checkbox
            pane.title:ClearAllPoints(); pane.title:SetPoint("TOPLEFT", 38, -8)
            if pane.desc then pane.desc:ClearAllPoints(); pane.desc:SetPoint("TOPLEFT", 38, -26); pane.desc:SetPoint("RIGHT", pane, "RIGHT", -10, 0) end

            -- Mode pane background image
            local modeBgPaths = {
                social = "Interface\\AddOns\\GuildRecruiterManagement\\Media\\Social_Guild",
                raid   = "Interface\\AddOns\\GuildRecruiterManagement\\Media\\Raiding_Guild",
                pvp    = "Interface\\AddOns\\GuildRecruiterManagement\\Media\\PVP_Guild",
                mplus  = "Interface\\AddOns\\GuildRecruiterManagement\\Media\\M+_Guild",
            }
            if modeBgPaths[mode.key] then
                local bgTex = pane:CreateTexture(nil, "ARTWORK", nil, -1)
                bgTex:SetTexture(modeBgPaths[mode.key])
                bgTex:SetSize(750, 320)
                bgTex:SetPoint("RIGHT", pane, "RIGHT", 0, 0)
                bgTex:SetAlpha(0.65)
                bgTex:SetTexCoord(0, 1, 0, 1)
            end
            chk.onClickHandler = function(cb)
                if cb:GetChecked() then
                    GR.db.guildMode = cb.modeKey
                    for k, other in pairs(modeCheckboxes) do if k ~= cb.modeKey then other:SetChecked(false) end end
                    GR.db.socialEnabled = (cb.modeKey == "social")
                else
                    GR.db.guildMode = nil; GR.db.socialEnabled = false
                end
                -- Enable/Disable Apply buttons based on active mode
                for k, btn in pairs(modeApplyBtns) do
                    if GR.db.guildMode == k then btn:Enable() else btn:Disable() end
                end
                if GR.UpdateRosterList then GR:UpdateRosterList() end
                -- Rebuild GRS center pane so column visibility matches the new mode
                local cp = _G["GRS_CenterPane"]
                if cp then
                    local kids = { cp:GetChildren() }
                    for _, child in ipairs(kids) do child:Hide(); child:SetParent(nil) end
                    local regions = { cp:GetRegions() }
                    for _, r in ipairs(regions) do r:Hide(); r:SetParent(nil) end
                    GR.ResultsHeader = nil; GR.SearchBtn = nil; GR.StatusText = nil
                    GR.grsVisibleCols = nil; GR.rows = {}; GR.scroll = nil; GR.listBackdrop = nil
                    GR:BuildCenterPane(cp)
                    if GR.UpdateHomeLayout then GR.UpdateHomeLayout() end
                end
            end

            -- =============================================================
            -- SOCIAL GUILD MODE: GRS Column Configuration
            -- =============================================================
            if mode.key == "social" then
                local cc = self.db.customColumns

                local function CountEnabledSocial(tbl)
                    local n = 0
                    for _, v in pairs(tbl) do if v then n = n + 1 end end
                    return n
                end

                -- ---- GRS Columns (max 5 of 6) ----
                local sgrsTitle = pane:CreateFontString(nil, "OVERLAY", "GameFontNormal")
                sgrsTitle:SetPoint("TOPLEFT", 10, -50); sgrsTitle:SetText("GRS Columns (max 5)"); sgrsTitle:SetTextColor(1, 0.82, 0)
                local sgrsCounter = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                sgrsCounter:SetPoint("LEFT", sgrsTitle, "RIGHT", 10, 0); sgrsCounter:SetTextColor(0.7, 0.7, 0.7)

                local SGRS_COLS = {
                    { key = "zone",   label = "Zone" },
                    { key = "raidN",  label = "Normal" },
                    { key = "heroic", label = "Heroic" },
                }
                local sgrsCbs = {}
                local function UpdateSocialGrsCounter()
                    sgrsCounter:SetText(CountEnabledSocial(cc.socialGrs) .. "/5 selected")
                end
                local sgrsCols = 3; local sgrsStartY = -70; local sgrsStartX = 10; local sgrsColW = 180; local sgrsRowH = 28
                for idx, col in ipairs(SGRS_COLS) do
                    local colIdx = (idx - 1) % sgrsCols; local rowIdx = math.floor((idx - 1) / sgrsCols)
                    local cb = CreateStyledCheckbox(pane, col.label, "TOPLEFT", nil, nil, sgrsStartX + (colIdx * sgrsColW), sgrsStartY - (rowIdx * sgrsRowH))
                    cb:SetChecked(cc.socialGrs[col.key] ~= false)
                    cb.colKey = col.key
                    sgrsCbs[col.key] = cb
                    cb.onClickHandler = function(self)
                        if self:GetChecked() then
                            if CountEnabledSocial(cc.socialGrs) >= 5 then
                                self:SetChecked(false)
                                return
                            end
                            cc.socialGrs[self.colKey] = true
                        else
                            cc.socialGrs[self.colKey] = false
                        end
                        UpdateSocialGrsCounter()
                    end
                end
                UpdateSocialGrsCounter()

                -- Apply button
                local socialApplyBtn = CreateFrame("Button", nil, pane, "UIPanelButtonTemplate")
                socialApplyBtn:SetSize(120, 26); socialApplyBtn:SetPoint("BOTTOMLEFT", pane, "BOTTOMLEFT", 10, 10); socialApplyBtn:SetText("Apply")
                if NS.SkinButton then NS.SkinButton(socialApplyBtn) end
                if self.db.guildMode ~= "social" then socialApplyBtn:Disable() end
                local socialAppliedLabel = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                socialAppliedLabel:SetPoint("LEFT", socialApplyBtn, "RIGHT", 10, 0); socialAppliedLabel:SetText("|cff00ff00Settings applied|r"); socialAppliedLabel:Hide()
                socialApplyBtn:SetScript("OnClick", function()
                    -- Rebuild Guild Roster
                    if GR.RosterSplitMain then GR.RosterSplitMain:Hide(); GR.RosterSplitMain = nil; GR.RosterRows = {}; GR.Rows = {} end
                    if GR.RosterContent then GR.RosterContent:Hide(); GR.RosterContent = nil end
                    if GR.RightPaneTop then GR.RightPaneTop:Hide(); GR.RightPaneTop = nil end
                    if GR.RightPaneBottom then GR.RightPaneBottom:Hide(); GR.RightPaneBottom = nil end
                    if GR.UpdateRosterList then GR:UpdateRosterList() end

                    -- Rebuild GRS center pane
                    local cp = _G["GRS_CenterPane"]
                    if cp then
                        local kids = { cp:GetChildren() }
                        for _, child in ipairs(kids) do child:Hide(); child:SetParent(nil) end
                        local regions = { cp:GetRegions() }
                        for _, r in ipairs(regions) do r:Hide(); r:SetParent(nil) end
                        GR.ResultsHeader = nil; GR.SearchBtn = nil; GR.StatusText = nil
                        GR.grsVisibleCols = nil
                        GR:BuildCenterPane(cp)
                        if GR.UpdateHomeLayout then GR.UpdateHomeLayout() end
                    end
                    socialAppliedLabel:Show()
                    NS.RunDelayed(3, function() if socialAppliedLabel then socialAppliedLabel:Hide() end end)
                end)
                modeApplyBtns["social"] = socialApplyBtn
            end

            -- =============================================================
            -- RAID GUILD MODE: GRS Column Configuration
            -- =============================================================
            if mode.key == "raid" then
                local cc = self.db.customColumns

                local function CountEnabledRaid(tbl)
                    local n = 0
                    for _, v in pairs(tbl) do if v then n = n + 1 end end
                    return n
                end

                local raidGrsTitle = pane:CreateFontString(nil, "OVERLAY", "GameFontNormal")
                raidGrsTitle:SetPoint("TOPLEFT", 10, -50); raidGrsTitle:SetText("GRS Columns (max 5)"); raidGrsTitle:SetTextColor(1, 0.82, 0)
                local raidGrsCounter = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                raidGrsCounter:SetPoint("LEFT", raidGrsTitle, "RIGHT", 10, 0); raidGrsCounter:SetTextColor(0.7, 0.7, 0.7)

                local RGRS_COLS = {
                    { key = "zone",   label = "Zone" },
                    { key = "raidN",  label = "Normal" },
                    { key = "heroic", label = "Heroic" },
                }
                local rgrsCbs = {}
                local function UpdateRaidGrsCounter()
                    raidGrsCounter:SetText(CountEnabledRaid(cc.raidGrs) .. "/5 selected")
                end
                local rgrsCols = 3; local rgrsStartY = -70; local rgrsStartX = 10; local rgrsColW = 180; local rgrsRowH = 28
                for idx, col in ipairs(RGRS_COLS) do
                    local colIdx = (idx - 1) % rgrsCols; local rowIdx = math.floor((idx - 1) / rgrsCols)
                    local cb = CreateStyledCheckbox(pane, col.label, "TOPLEFT", nil, nil, rgrsStartX + (colIdx * rgrsColW), rgrsStartY - (rowIdx * rgrsRowH))
                    cb:SetChecked(cc.raidGrs[col.key] ~= false)
                    cb.colKey = col.key
                    rgrsCbs[col.key] = cb
                    cb.onClickHandler = function(self)
                        if self:GetChecked() then
                            if CountEnabledRaid(cc.raidGrs) >= 5 then
                                self:SetChecked(false)
                                return
                            end
                            cc.raidGrs[self.colKey] = true
                        else
                            cc.raidGrs[self.colKey] = false
                        end
                        UpdateRaidGrsCounter()
                    end
                end
                UpdateRaidGrsCounter()

                local raidApplyBtn = CreateFrame("Button", nil, pane, "UIPanelButtonTemplate")
                raidApplyBtn:SetSize(120, 26); raidApplyBtn:SetPoint("BOTTOMLEFT", pane, "BOTTOMLEFT", 10, 10); raidApplyBtn:SetText("Apply")
                if NS.SkinButton then NS.SkinButton(raidApplyBtn) end
                if self.db.guildMode ~= "raid" then raidApplyBtn:Disable() end
                local raidAppliedLabel = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                raidAppliedLabel:SetPoint("LEFT", raidApplyBtn, "RIGHT", 10, 0); raidAppliedLabel:SetText("|cff00ff00Settings applied|r"); raidAppliedLabel:Hide()
                raidApplyBtn:SetScript("OnClick", function()
                    if GR.RosterSplitMain then GR.RosterSplitMain:Hide(); GR.RosterSplitMain = nil; GR.RosterRows = {}; GR.Rows = {} end
                    if GR.RosterContent then GR.RosterContent:Hide(); GR.RosterContent = nil end
                    if GR.RightPaneTop then GR.RightPaneTop:Hide(); GR.RightPaneTop = nil end
                    if GR.RightPaneBottom then GR.RightPaneBottom:Hide(); GR.RightPaneBottom = nil end
                    if GR.UpdateRosterList then GR:UpdateRosterList() end
                    local cp = _G["GRS_CenterPane"]
                    if cp then
                        local kids = { cp:GetChildren() }
                        for _, child in ipairs(kids) do child:Hide(); child:SetParent(nil) end
                        local regions = { cp:GetRegions() }
                        for _, r in ipairs(regions) do r:Hide(); r:SetParent(nil) end
                        GR.ResultsHeader = nil; GR.SearchBtn = nil; GR.StatusText = nil
                        GR.grsVisibleCols = nil
                        GR:BuildCenterPane(cp)
                        if GR.UpdateHomeLayout then GR.UpdateHomeLayout() end
                    end
                    raidAppliedLabel:Show()
                    NS.RunDelayed(3, function() if raidAppliedLabel then raidAppliedLabel:Hide() end end)
                end)
                modeApplyBtns["raid"] = raidApplyBtn
            end

            -- =============================================================
            -- M+ GUILD MODE: GRS Column Configuration
            -- =============================================================
            if mode.key == "mplus" then
                local cc = self.db.customColumns

                local function CountEnabledMplus(tbl)
                    local n = 0
                    for _, v in pairs(tbl) do if v then n = n + 1 end end
                    return n
                end

                local mplusGrsTitle = pane:CreateFontString(nil, "OVERLAY", "GameFontNormal")
                mplusGrsTitle:SetPoint("TOPLEFT", 10, -50); mplusGrsTitle:SetText("GRS Columns (max 5)"); mplusGrsTitle:SetTextColor(1, 0.82, 0)
                local mplusGrsCounter = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                mplusGrsCounter:SetPoint("LEFT", mplusGrsTitle, "RIGHT", 10, 0); mplusGrsCounter:SetTextColor(0.7, 0.7, 0.7)

                local MGRS_COLS = {
                    { key = "zone",   label = "Zone" },
                    { key = "maxKey", label = "M+ (Max Key)" },
                    { key = "rio",    label = "Score" },
                    { key = "raidN",  label = "Normal" },
                    { key = "heroic", label = "Heroic" },
                    { key = "mythic", label = "Mythic" },
                    { key = "warbandScore", label = "Warband Score" },
                }
                local mgrsCbs = {}
                local function UpdateMplusGrsCounter()
                    mplusGrsCounter:SetText(CountEnabledMplus(cc.mplusGrs) .. "/5 selected")
                end
                local mgrsCols = 3; local mgrsStartY = -70; local mgrsStartX = 10; local mgrsColW = 180; local mgrsRowH = 28
                for idx, col in ipairs(MGRS_COLS) do
                    local colIdx = (idx - 1) % mgrsCols; local rowIdx = math.floor((idx - 1) / mgrsCols)
                    local cb = CreateStyledCheckbox(pane, col.label, "TOPLEFT", nil, nil, mgrsStartX + (colIdx * mgrsColW), mgrsStartY - (rowIdx * mgrsRowH))
                    cb:SetChecked(cc.mplusGrs[col.key] ~= false)
                    cb.colKey = col.key
                    mgrsCbs[col.key] = cb
                    cb.onClickHandler = function(self)
                        if self:GetChecked() then
                            if CountEnabledMplus(cc.mplusGrs) >= 5 then
                                self:SetChecked(false)
                                return
                            end
                            cc.mplusGrs[self.colKey] = true
                        else
                            cc.mplusGrs[self.colKey] = false
                        end
                        UpdateMplusGrsCounter()
                    end
                end
                UpdateMplusGrsCounter()

                local mplusApplyBtn = CreateFrame("Button", nil, pane, "UIPanelButtonTemplate")
                mplusApplyBtn:SetSize(120, 26); mplusApplyBtn:SetPoint("BOTTOMLEFT", pane, "BOTTOMLEFT", 10, 10); mplusApplyBtn:SetText("Apply")
                if NS.SkinButton then NS.SkinButton(mplusApplyBtn) end
                if self.db.guildMode ~= "mplus" then mplusApplyBtn:Disable() end
                local mplusAppliedLabel = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                mplusAppliedLabel:SetPoint("LEFT", mplusApplyBtn, "RIGHT", 10, 0); mplusAppliedLabel:SetText("|cff00ff00Settings applied|r"); mplusAppliedLabel:Hide()
                mplusApplyBtn:SetScript("OnClick", function()
                    if GR.RosterSplitMain then GR.RosterSplitMain:Hide(); GR.RosterSplitMain = nil; GR.RosterRows = {}; GR.Rows = {} end
                    if GR.RosterContent then GR.RosterContent:Hide(); GR.RosterContent = nil end
                    if GR.RightPaneTop then GR.RightPaneTop:Hide(); GR.RightPaneTop = nil end
                    if GR.RightPaneBottom then GR.RightPaneBottom:Hide(); GR.RightPaneBottom = nil end
                    if GR.UpdateRosterList then GR:UpdateRosterList() end
                    local cp = _G["GRS_CenterPane"]
                    if cp then
                        local kids = { cp:GetChildren() }
                        for _, child in ipairs(kids) do child:Hide(); child:SetParent(nil) end
                        local regions = { cp:GetRegions() }
                        for _, r in ipairs(regions) do r:Hide(); r:SetParent(nil) end
                        GR.ResultsHeader = nil; GR.SearchBtn = nil; GR.StatusText = nil
                        GR.grsVisibleCols = nil
                        GR:BuildCenterPane(cp)
                        if GR.UpdateHomeLayout then GR.UpdateHomeLayout() end
                    end
                    mplusAppliedLabel:Show()
                    NS.RunDelayed(3, function() if mplusAppliedLabel then mplusAppliedLabel:Hide() end end)
                end)
                modeApplyBtns["mplus"] = mplusApplyBtn
            end

            -- =============================================================
            -- PVP GUILD MODE: Guild Roster Column Configuration
            -- =============================================================
            if mode.key == "pvp" then
                local cc = self.db.customColumns

                local function CountEnabledPvp(tbl)
                    local n = 0
                    for _, v in pairs(tbl) do if v then n = n + 1 end end
                    return n
                end

                -- ---- Guild Roster Columns (max 6 of 7) ----
                local pvpRosterTitle = pane:CreateFontString(nil, "OVERLAY", "GameFontNormal")
                pvpRosterTitle:SetPoint("TOPLEFT", 10, -50); pvpRosterTitle:SetText("Guild Roster Columns (max 6)"); pvpRosterTitle:SetTextColor(1, 0.82, 0)
                local pvpRosterCounter = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                pvpRosterCounter:SetPoint("LEFT", pvpRosterTitle, "RIGHT", 10, 0); pvpRosterCounter:SetTextColor(0.7, 0.7, 0.7)

                local PROSTER_COLS = {
                    { key = "pvp2v2",  label = "2v2 Rating" },
                    { key = "pvp3v3",  label = "3v3 Rating" },
                    { key = "pvpSolo", label = "Solo Shuffle" },
                    { key = "pvpRbg",  label = "RBG Rating" },
                    { key = "pvpBest", label = "Best Rating" },
                    { key = "pvpExp",  label = "Experience" },
                    { key = "pvpSpec", label = "Spec" },
                }
                local prosterCbs = {}
                local function UpdatePvpRosterCounter()
                    pvpRosterCounter:SetText(CountEnabledPvp(cc.pvpRoster) .. "/6 selected")
                end
                local prCols = 4; local prStartY = -70; local prStartX = 10; local prColW = 155; local prRowH = 28
                for idx, col in ipairs(PROSTER_COLS) do
                    local colIdx = (idx - 1) % prCols; local rowIdx = math.floor((idx - 1) / prCols)
                    local cb = CreateStyledCheckbox(pane, col.label, "TOPLEFT", nil, nil, prStartX + (colIdx * prColW), prStartY - (rowIdx * prRowH))
                    cb:SetChecked(cc.pvpRoster[col.key] ~= false)
                    cb.colKey = col.key
                    prosterCbs[col.key] = cb
                    cb.onClickHandler = function(self)
                        if self:GetChecked() then
                            if CountEnabledPvp(cc.pvpRoster) >= 6 then
                                self:SetChecked(false)
                                return
                            end
                            cc.pvpRoster[self.colKey] = true
                        else
                            cc.pvpRoster[self.colKey] = false
                        end
                        UpdatePvpRosterCounter()
                    end
                end
                UpdatePvpRosterCounter()

                local pvpApplyBtn = CreateFrame("Button", nil, pane, "UIPanelButtonTemplate")
                pvpApplyBtn:SetSize(120, 26); pvpApplyBtn:SetPoint("BOTTOMLEFT", pane, "BOTTOMLEFT", 10, 10); pvpApplyBtn:SetText("Apply")
                if NS.SkinButton then NS.SkinButton(pvpApplyBtn) end
                if self.db.guildMode ~= "pvp" then pvpApplyBtn:Disable() end
                local pvpAppliedLabel = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                pvpAppliedLabel:SetPoint("LEFT", pvpApplyBtn, "RIGHT", 10, 0); pvpAppliedLabel:SetText("|cff00ff00Settings applied|r"); pvpAppliedLabel:Hide()
                pvpApplyBtn:SetScript("OnClick", function()
                    if GR.RosterSplitMain then GR.RosterSplitMain:Hide(); GR.RosterSplitMain = nil; GR.RosterRows = {}; GR.Rows = {} end
                    if GR.RosterContent then GR.RosterContent:Hide(); GR.RosterContent = nil end
                    if GR.RightPaneTop then GR.RightPaneTop:Hide(); GR.RightPaneTop = nil end
                    if GR.RightPaneBottom then GR.RightPaneBottom:Hide(); GR.RightPaneBottom = nil end
                    if GR.UpdateRosterList then GR:UpdateRosterList() end
                    pvpAppliedLabel:Show()
                    NS.RunDelayed(3, function() if pvpAppliedLabel then pvpAppliedLabel:Hide() end end)
                end)
                modeApplyBtns["pvp"] = pvpApplyBtn
            end

            -- =============================================================
            -- CUSTOM GUILD MODE: Column Configuration Tables
            -- =============================================================
            if mode.key == "custom" then
                local cc = self.db.customColumns

                -- Helper: count enabled columns
                local function CountEnabled(tbl)
                    local n = 0
                    for _, v in pairs(tbl) do if v then n = n + 1 end end
                    return n
                end

                -- ---- GRS Columns (max 5 of 6) ----
                local grsTitle = pane:CreateFontString(nil, "OVERLAY", "GameFontNormal")
                grsTitle:SetPoint("TOPLEFT", 10, -50); grsTitle:SetText("GRS Columns (max 5)"); grsTitle:SetTextColor(1, 0.82, 0)
                local grsCounter = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                grsCounter:SetPoint("LEFT", grsTitle, "RIGHT", 10, 0); grsCounter:SetTextColor(0.7, 0.7, 0.7)

                local GRS_COLS = {
                    { key = "zone",   label = "Zone" },
                    { key = "raidN",  label = "Normal" },
                    { key = "heroic", label = "Heroic" },
                }
                local grsCbs = {}
                local function UpdateGrsCounter()
                    grsCounter:SetText(CountEnabled(cc.grs) .. "/5 selected")
                end
                local grsCols = 3; local grsStartY = -70; local grsStartX = 10; local grsColW = 180; local grsRowH = 28
                for idx, col in ipairs(GRS_COLS) do
                    local colIdx = (idx - 1) % grsCols; local rowIdx = math.floor((idx - 1) / grsCols)
                    local cb = CreateStyledCheckbox(pane, col.label, "TOPLEFT", nil, nil, grsStartX + (colIdx * grsColW), grsStartY - (rowIdx * grsRowH))
                    cb:SetChecked(cc.grs[col.key] ~= false)
                    cb.colKey = col.key
                    grsCbs[col.key] = cb
                    cb.onClickHandler = function(self)
                        if self:GetChecked() then
                            if CountEnabled(cc.grs) >= 5 then
                                self:SetChecked(false)
                                return
                            end
                            cc.grs[self.colKey] = true
                        else
                            cc.grs[self.colKey] = false
                        end
                        UpdateGrsCounter()
                    end
                end
                UpdateGrsCounter()

                -- ---- Guild Roster Columns (max 6 of 7) ----
                local rosterTitle = pane:CreateFontString(nil, "OVERLAY", "GameFontNormal")
                rosterTitle:SetPoint("TOPLEFT", 10, -170); rosterTitle:SetText("Guild Roster Columns (max 6)"); rosterTitle:SetTextColor(1, 0.82, 0)
                local rosterCounter = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                rosterCounter:SetPoint("LEFT", rosterTitle, "RIGHT", 10, 0); rosterCounter:SetTextColor(0.7, 0.7, 0.7)

                local ROSTER_COLS = {
                    { key = "ach",   label = "Achievement" },
                    { key = "ilvl",  label = "ilvl" },
                    { key = "raidN", label = "N (Normal)" },
                    { key = "raidH", label = "H (Heroic)" },
                }
                local rosterCbs = {}
                local function UpdateRosterCounter()
                    rosterCounter:SetText(CountEnabled(cc.roster) .. "/6 selected")
                end
                local rCols = 4; local rStartY = -190; local rStartX = 10; local rColW = 155; local rRowH = 28
                for idx, col in ipairs(ROSTER_COLS) do
                    local colIdx = (idx - 1) % rCols; local rowIdx = math.floor((idx - 1) / rCols)
                    local cb = CreateStyledCheckbox(pane, col.label, "TOPLEFT", nil, nil, rStartX + (colIdx * rColW), rStartY - (rowIdx * rRowH))
                    cb:SetChecked(cc.roster[col.key] ~= false)
                    cb.colKey = col.key
                    rosterCbs[col.key] = cb
                    cb.onClickHandler = function(self)
                        if self:GetChecked() then
                            if CountEnabled(cc.roster) >= 6 then
                                self:SetChecked(false)
                                return
                            end
                            cc.roster[self.colKey] = true
                        else
                            cc.roster[self.colKey] = false
                        end
                        UpdateRosterCounter()
                    end
                end
                UpdateRosterCounter()

                -- Apply button
                local applyBtn = CreateFrame("Button", nil, pane, "UIPanelButtonTemplate")
                applyBtn:SetSize(120, 26); applyBtn:SetPoint("BOTTOMLEFT", pane, "BOTTOMLEFT", 10, 10); applyBtn:SetText("Apply")
                if NS.SkinButton then NS.SkinButton(applyBtn) end
                if self.db.guildMode ~= "custom" then applyBtn:Disable() end
                local customAppliedLabel = pane:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                customAppliedLabel:SetPoint("LEFT", applyBtn, "RIGHT", 10, 0); customAppliedLabel:SetText("|cff00ff00Settings applied|r"); customAppliedLabel:Hide()
                applyBtn:SetScript("OnClick", function()
                    -- Rebuild Guild Roster
                    if GR.RosterSplitMain then GR.RosterSplitMain:Hide(); GR.RosterSplitMain = nil; GR.RosterRows = {}; GR.Rows = {} end
                    if GR.RosterContent then GR.RosterContent:Hide(); GR.RosterContent = nil end
                    if GR.RightPaneTop then GR.RightPaneTop:Hide(); GR.RightPaneTop = nil end
                    if GR.RightPaneBottom then GR.RightPaneBottom:Hide(); GR.RightPaneBottom = nil end
                    if GR.UpdateRosterList then GR:UpdateRosterList() end

                    -- Rebuild GRS center pane
                    local cp = _G["GRS_CenterPane"]
                    if cp then
                        local kids = { cp:GetChildren() }
                        for _, child in ipairs(kids) do child:Hide(); child:SetParent(nil) end
                        local regions = { cp:GetRegions() }
                        for _, r in ipairs(regions) do r:Hide(); r:SetParent(nil) end
                        GR.ResultsHeader = nil; GR.SearchBtn = nil; GR.StatusText = nil
                        GR.grsVisibleCols = nil
                        GR:BuildCenterPane(cp)
                        if GR.UpdateHomeLayout then GR.UpdateHomeLayout() end
                    end
                    customAppliedLabel:Show()
                    NS.RunDelayed(3, function() if customAppliedLabel then customAppliedLabel:Hide() end end)
                end)
                modeApplyBtns["custom"] = applyBtn
            end

            if mode.key == "custom" then y = y - 385 elseif mode.key == "social" or mode.key == "raid" or mode.key == "pvp" then y = y - 285 else y = y - 75 end
        end
        c:SetHeight(math.abs(y) + 20)
    end

    -- =================================================================
    -- PAGE 3: APPEARANCES
    -- =================================================================
    do
        local c = pages[3].canvas; local y = -10

        -- Transparency & Contrast (height +25, gap +10)
        local p1 = CreateOptionPane(c, y, NS.L["TRANSPARENCY_CONTRAST"] or "Transparency & Contrast", "Panel opacity with a high-contrast text option.", 105)
        local alphaS = CreateColorSlider(p1, "Background Alpha", function() return GR.db.theme.background.a end, function(v) GR.db.theme.background.a = v; UpdateLiveTheme() end)
        alphaS:SetPoint("TOPLEFT", 10, -55); alphaS:SetWidth(300)
        y = y - 110

        -- UI Scale
        local p2 = CreateOptionPane(c, y, NS.L["UI_SCALE"] or "UI Scale", "Adjust overall addon UI scale. Values between 0.60 and 1.40.", 80)
        local valScale = p2:CreateFontString(nil, "OVERLAY", "GameFontHighlight"); valScale:SetPoint("TOPRIGHT", -10, -10); valScale:SetText(string.format("%.2f", self.db.scale or 1.0))
        local sliderScale = CreateFrame("Slider", "GRS_ScaleSlider", p2, "OptionsSliderTemplate"); sliderScale:SetPoint("TOPLEFT", 10, -50); sliderScale:SetWidth(380); sliderScale:SetMinMaxValues(0.6, 1.4); sliderScale:SetValueStep(0.05); sliderScale:SetObeyStepOnDrag(true)
        local sName = sliderScale:GetName(); if _G[sName.."Low"] then _G[sName.."Low"]:SetText("") end; if _G[sName.."High"] then _G[sName.."High"]:SetText("") end; if _G[sName.."Text"] then _G[sName.."Text"]:SetText("") end
        sliderScale:SetValue(self.db.scale or 1.0)
        sliderScale:SetScript("OnValueChanged", function(s, val) local v = math.floor(val * 100 + 0.5) / 100; valScale:SetText(string.format("%.2f", v)) end)
        sliderScale:SetScript("OnMouseUp", function(s) local v = math.floor(s:GetValue() * 100 + 0.5) / 100; if GR.db then GR.db.scale = v end; GR:SetScale(v) end)
        y = y - 85

        -- =============================================================
        -- Theme and Colors: Unified horizontal pane with presets
        -- =============================================================
        local themePane = CreateOptionPane(c, y, "Theme and Colors", "Adjust header, background and button colors. Or pick a preset.", 310)

        local colSliders = {}
        local function MakeColorColumn(cparent, xOffset, colTitle, dbKey, useAlpha)
            local col = CreateFrame("Frame", nil, cparent); col:SetSize(210, 200)
            col:SetPoint("TOPLEFT", xOffset, -42)
            local hdr = col:CreateFontString(nil, "OVERLAY", "GameFontNormal"); hdr:SetPoint("TOP", 0, 0); hdr:SetText(colTitle); hdr:SetTextColor(1, 0.82, 0)
            local function GetCol(k) local t = GR.db.theme[dbKey]; return t and t[k] or (k == "a" and 1 or 0) end
            local function SetCol(k, v) if GR.db.theme[dbKey] then GR.db.theme[dbKey][k] = v; UpdateLiveTheme() end end
            local sliders = {}
            local rS = CreateColorSlider(col, "Red", function() return GetCol("r") end, function(v) SetCol("r", v) end); rS:SetPoint("TOPLEFT", 5, -25); rS:SetWidth(195); sliders.r = rS
            local gS = CreateColorSlider(col, "Green", function() return GetCol("g") end, function(v) SetCol("g", v) end); gS:SetPoint("TOPLEFT", 5, -60); gS:SetWidth(195); sliders.g = gS
            local bS = CreateColorSlider(col, "Blue", function() return GetCol("b") end, function(v) SetCol("b", v) end); bS:SetPoint("TOPLEFT", 5, -95); bS:SetWidth(195); sliders.b = bS
            if useAlpha then
                local aS = CreateColorSlider(col, "Alpha", function() return GetCol("a") end, function(v) SetCol("a", v) end); aS:SetPoint("TOPLEFT", 5, -130); aS:SetWidth(195); sliders.a = aS
            else
                if GR.db.theme[dbKey] then GR.db.theme[dbKey].a = 1 end
            end
            colSliders[dbKey] = sliders
            return col
        end
        MakeColorColumn(themePane, 10,  "Header / Sidebar",  "header",     false)
        MakeColorColumn(themePane, 225, "Background Pane",   "background", true)
        MakeColorColumn(themePane, 440, "Buttons & Text",    "buttons",    false)

        -- Preset Definitions (8 presets)
        local PRESETS = {
            { name = "Default",     header = {r=0.10, g=0.10, b=0.20}, background = {r=0.05, g=0.05, b=0.05, a=0.95}, buttons = {r=0.20, g=0.20, b=0.20} },
            { name = "Obsidian",    header = {r=0.06, g=0.06, b=0.06}, background = {r=0.03, g=0.03, b=0.03, a=0.98}, buttons = {r=0.12, g=0.12, b=0.12} },
            { name = "Arcane",      header = {r=0.18, g=0.05, b=0.30}, background = {r=0.06, g=0.02, b=0.12, a=0.95}, buttons = {r=0.25, g=0.08, b=0.40} },
            { name = "Destruction", header = {r=0.35, g=0.05, b=0.02}, background = {r=0.10, g=0.02, b=0.01, a=0.95}, buttons = {r=0.45, g=0.10, b=0.05} },
            { name = "Healer",     header = {r=0.02, g=0.20, b=0.10}, background = {r=0.01, g=0.08, b=0.04, a=0.95}, buttons = {r=0.05, g=0.28, b=0.14} },
            { name = "Protector",  header = {r=0.08, g=0.15, b=0.28}, background = {r=0.03, g=0.06, b=0.12, a=0.95}, buttons = {r=0.12, g=0.22, b=0.35} },
            { name = "Crusader",   header = {r=0.30, g=0.22, b=0.05}, background = {r=0.10, g=0.07, b=0.02, a=0.95}, buttons = {r=0.40, g=0.30, b=0.08} },
            { name = "Iron Man",   header = {r=0.55, g=0.08, b=0.08}, background = {r=0.12, g=0.04, b=0.02, a=0.96}, buttons = {r=0.65, g=0.45, b=0.05} },
        }

        local function ApplyPreset(preset)
            for _, dbKey in ipairs({"header", "background", "buttons"}) do
                local src = preset[dbKey]
                if src and GR.db.theme[dbKey] then
                    for k, v in pairs(src) do GR.db.theme[dbKey][k] = v end
                    if not src.a then GR.db.theme[dbKey].a = 1 end
                    if colSliders[dbKey] then
                        for ck, slider in pairs(colSliders[dbKey]) do
                            local val = GR.db.theme[dbKey][ck]
                            if val then slider:SetValue(val) end
                        end
                    end
                end
            end
            UpdateLiveTheme()
        end

        -- Preset buttons (2x4 grid)
        local presetY = -205; local presetX = 10; local presetCols = 4; local presetBtnW = 150; local presetBtnH = 28; local presetPadX = 8; local presetPadY = 6
        local presetLabel = themePane:CreateFontString(nil, "OVERLAY", "GameFontNormal"); presetLabel:SetPoint("TOPLEFT", 10, -192); presetLabel:SetText("Presets:"); presetLabel:SetTextColor(0.8, 0.8, 0.8)
        for idx, preset in ipairs(PRESETS) do
            local col = (idx - 1) % presetCols; local row = math.floor((idx - 1) / presetCols)
            local btn = CreateFrame("Button", nil, themePane)
            btn:SetSize(presetBtnW, presetBtnH); btn:SetPoint("TOPLEFT", presetX + col * (presetBtnW + presetPadX), presetY - row * (presetBtnH + presetPadY))
            btn:SetNormalTexture(""); btn:SetHighlightTexture(""); btn:SetPushedTexture("")
            local swatch = btn:CreateTexture(nil, "ARTWORK"); swatch:SetSize(6, presetBtnH - 4); swatch:SetPoint("LEFT", 2, 0)
            swatch:SetColorTexture(preset.header.r, preset.header.g, preset.header.b, 1)
            local bg = btn:CreateTexture(nil, "BORDER"); bg:SetAllPoints(); bg:SetColorTexture(0, 0, 0, 1); btn.bg = bg
            local brd = btn:CreateTexture(nil, "BACKGROUND"); brd:SetPoint("TOPLEFT", -1, 1); brd:SetPoint("BOTTOMRIGHT", 1, -1); brd:SetColorTexture(0.25, 0.25, 0.25, 1); btn.brd = brd
            local txt = btn:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); txt:SetPoint("CENTER", 4, 0); txt:SetText(preset.name); txt:SetTextColor(1, 1, 1)
            btn:SetScript("OnEnter", function(s) s.bg:SetColorTexture(0.15, 0.15, 0.15, 1) end)
            btn:SetScript("OnLeave", function(s) s.bg:SetColorTexture(0, 0, 0, 1) end)
            btn:SetScript("OnClick", function() ApplyPreset(preset) end)
        end
        y = y - 315

        -- Compact Mode (checkbox in front of name)
        local p6 = CreateOptionPane(c, y, NS.L["COMPACT_MODE"] or "Compact Mode", "Enable a compact layout mode for the addon interface.", 70)
        local chkCompact = CreateStyledCheckbox(p6, nil, "TOPLEFT", nil, nil, 10, -8)
        chkCompact:SetChecked(self.db.compactMode or false)
        p6.title:ClearAllPoints(); p6.title:SetPoint("TOPLEFT", 38, -8)
        if p6.desc then p6.desc:ClearAllPoints(); p6.desc:SetPoint("TOPLEFT", 38, -26); p6.desc:SetPoint("RIGHT", p6, "RIGHT", -10, 0) end
        chkCompact.onClickHandler = function(cb) GR.db.compactMode = cb:GetChecked(); if GR.ToggleCompactMode then GR:ToggleCompactMode(GR.db.compactMode) end end
        y = y - 75

        -- Custom Background + Reload UI (MERGED, +50px height)
        local p7 = CreateOptionPane(c, y, NS.L["CUSTOM_BACKGROUND"] or "Custom Background & Reload", "Enable and configure custom background images per tab.", 440)
        if not self.db.customBackgrounds then self.db.customBackgrounds = {} end
        local chkEnableBg = CreateStyledCheckbox(p7, NS.L["ENABLE_CUSTOM_BG"] or "Enable Custom Background", "TOPLEFT", nil, nil, 10, -45)
        chkEnableBg:SetChecked(self.db.customBackgrounds.enabled or false)

        -- Set Directory (left side)
        local lblDir = p7:CreateFontString(nil, "OVERLAY", "GameFontNormal"); lblDir:SetPoint("TOPLEFT", 10, -75); lblDir:SetText(NS.L["SET_DIRECTORY"] or "Set directory")
        local edtDir = CreateFrame("EditBox", nil, p7, "InputBoxTemplate"); edtDir:SetSize(280, 20); edtDir:SetPoint("TOPLEFT", 10, -95); edtDir:SetAutoFocus(false); edtDir:SetFontObject("ChatFontSmall"); edtDir:SetText(self.db.customBackgrounds.directory or "Interface\\AddOns\\GuildRecruiterManagement\\Media")
        local btnDir = CreateFrame("Button", nil, p7, "UIPanelButtonTemplate"); btnDir:SetSize(40, 20); btnDir:SetPoint("LEFT", edtDir, "RIGHT", 5, 0); btnDir:SetText("Set"); SafeCreateBg(btnDir, 0, 0, 0, 1); SafeCreateBorder(btnDir, 0.3, 0.3, 0.3, 1)
        btnDir:SetScript("OnClick", function() GR.db.customBackgrounds.directory = edtDir:GetText(); edtDir:ClearFocus() end)

        -- Reload UI button (below Set Directory, 50px gap)
        local btnReload = CreateFrame("Button", nil, p7, "UIPanelButtonTemplate"); btnReload:SetSize(120, 25); btnReload:SetPoint("TOPLEFT", 10, -165); btnReload:SetText(NS.L["RELOAD_UI"] or "Reload UI"); btnReload:SetScript("OnClick", function() ReloadUI() end); SafeSkinButton(btnReload)
        local txtReload = p7:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); txtReload:SetPoint("LEFT", btnReload, "RIGHT", 10, 0); txtReload:SetText(NS.L["RELOAD_UI_NOTE"] or "Reload UI for scale and theme changes to take full effect."); txtReload:SetTextColor(0.6, 0.6, 0.6)

        -- Background file inputs (right column, with title)
        local bgTitle = p7:CreateFontString(nil, "OVERLAY", "GameFontNormal"); bgTitle:SetPoint("TOPLEFT", 360, -45); bgTitle:SetText("Tab Backgrounds"); bgTitle:SetTextColor(1, 0.82, 0)
        local function CreateBgRow(rParent, index, labelText, defaultFile, ryOffset)
            local label = rParent:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); label:SetPoint("TOPLEFT", 360, ryOffset); label:SetText(labelText)
            local edit = CreateFrame("EditBox", nil, rParent, "InputBoxTemplate"); edit:SetSize(230, 18); edit:SetPoint("TOPLEFT", 360, ryOffset - 14); edit:SetAutoFocus(false); edit:SetFontObject("ChatFontSmall")
            if not GR.db.customBackgrounds.files then GR.db.customBackgrounds.files = {} end; edit:SetText(GR.db.customBackgrounds.files[index] or defaultFile or "")
            local btn = CreateFrame("Button", nil, rParent, "UIPanelButtonTemplate"); btn:SetSize(35, 18); btn:SetPoint("LEFT", edit, "RIGHT", 3, 0); btn:SetText("Set"); SafeCreateBg(btn, 0, 0, 0, 1); SafeCreateBorder(btn, 0.3, 0.3, 0.3, 1)
            btn:SetScript("OnClick", function() GR.db.customBackgrounds.files[index] = edit:GetText(); edit:ClearFocus() end)
            return edit, btn
        end
        local bgY = -65
        if NS.Constants and NS.Constants.TABS then for i = 1, 6 do local tabData = NS.Constants.TABS[i]; local title = tabData and tabData.title or ("Tab " .. i); CreateBgRow(p7, i, title, nil, bgY); bgY = bgY - 38 end end
        CreateBgRow(p7, "GuildChat", "Guild Chat", "Background_G-chat.tga", bgY)

        local function ToggleCustomControls(enable) local alpha = enable and 1 or 0.5; edtDir:SetAlpha(alpha); btnDir:SetAlpha(alpha) end
        chkEnableBg.onClickHandler = function(cb) GR.db.customBackgrounds.enabled = cb:GetChecked(); ToggleCustomControls(GR.db.customBackgrounds.enabled) end
        ToggleCustomControls(self.db.customBackgrounds.enabled)
        y = y - 445

        c:SetHeight(math.abs(y) + 20)
    end

    -- =================================================================
    -- PAGE 4: TOOLS (checkboxes in front)
    -- =================================================================
    do
        local c = pages[4].canvas; local y = -10
        local p1 = CreateOptionPane(c, y, NS.L["ENABLE_MACRO_TOOLS"] or "Macro Tools", "Enable the Macro Tools panel for advanced recruitment macros and automation.", 70)
        local chkMacro = CreateStyledCheckbox(p1, nil, "TOPLEFT", nil, nil, 10, -8)
        p1.title:ClearAllPoints(); p1.title:SetPoint("TOPLEFT", 38, -8)
        if p1.desc then p1.desc:ClearAllPoints(); p1.desc:SetPoint("TOPLEFT", 38, -26); p1.desc:SetPoint("RIGHT", p1, "RIGHT", -10, 0) end
        if DB_Rmap_Tools and DB_Rmap_Tools.settings then chkMacro:SetChecked(DB_Rmap_Tools.settings.isMacroPanelOpen) else chkMacro:SetChecked(false) end
        chkMacro.onClickHandler = function(cb)
            local isEnabled = cb:GetChecked(); if DB_Rmap_Tools then if not DB_Rmap_Tools.settings then DB_Rmap_Tools.settings = {} end; DB_Rmap_Tools.settings.isMacroPanelOpen = isEnabled end
            if isEnabled then if GR.InitMacroDashboard then GR:InitMacroDashboard() end; if GR.MacroPanel then GR.MacroPanel:Show() end else if GR.MacroPanel then GR.MacroPanel:Hide() end end
        end
        y = y - 75
        c:SetHeight(math.abs(y) + 20)
    end

    -- =================================================================
    -- PAGE 5: LANGUAGE (fixed encoding, styled checkboxes)
    -- =================================================================
    do
        local c = pages[5].canvas; local y = -10
        local p1 = CreateOptionPane(c, y, NS.L["LANGUAGE"] or "Language", "Select the display language for the addon interface. Requires a UI reload to apply.", 280)
        if not self.db.selectedLanguage then self.db.selectedLanguage = nil end
        local LANGUAGES = {
            { key = "enUS", label = "English" },
            { key = "deDE", label = "Deutsch" },
            { key = "esES", label = "Espa\195\177ol (EU)" },
            { key = "frFR", label = "Fran\195\167ais" },
            { key = "itIT", label = "Italiano" },
            { key = "ruRU", label = "\208\160\209\131\209\129\209\129\208\186\208\184\208\185" },
            { key = "esMX", label = "Espa\195\177ol (AL)" },
            { key = "ptBR", label = "Portugu\195\170s" },
            { key = "koKR", label = "\237\149\156\234\181\173\236\150\180" },
            { key = "zhCN", label = "\231\174\128\228\189\147\228\184\173\230\150\135" },
            { key = "zhTW", label = "\231\185\129\233\171\148\228\184\173\230\150\135" },
        }
        local langCheckboxes = {}
        local cols = 4; local colWidth = 170; local rowHeight = 30; local startY = -45; local startX = 10
        for idx, lang in ipairs(LANGUAGES) do
            local col = (idx - 1) % cols; local row = math.floor((idx - 1) / cols)
            local chkLang = CreateStyledCheckbox(p1, lang.label, "TOPLEFT", nil, nil, startX + (col * colWidth), startY - (row * rowHeight))
            chkLang:SetChecked(self.db.selectedLanguage == lang.key)
            chkLang.langKey = lang.key; langCheckboxes[lang.key] = chkLang
            chkLang.onClickHandler = function(cb)
                if cb:GetChecked() then
                    GR.db.selectedLanguage = cb.langKey
                    for key, otherCb in pairs(langCheckboxes) do if key ~= cb.langKey then otherCb:SetChecked(false) end end
                else
                    GR.db.selectedLanguage = nil
                end
            end
        end
        -- Apply Language Button
        local btnApplyLang = CreateFrame("Button", nil, p1, "UIPanelButtonTemplate"); btnApplyLang:SetSize(140, 30); btnApplyLang:SetPoint("TOPLEFT", startX, startY - (math.ceil(#LANGUAGES / cols) * rowHeight) - 10)
        btnApplyLang:SetText(NS.L["APPLY_LANGUAGE"] or "Apply Language"); SafeSkinButton(btnApplyLang)
        btnApplyLang:SetScript("OnClick", function()
            local lang = GR.db.selectedLanguage
            if lang then ReloadUI() end
        end)
        y = y - 285
        c:SetHeight(math.abs(y) + 20)
    end

    -- =================================================================
    -- PAGE 6: ADVANCED (checkboxes in front, merged import/export)
    -- =================================================================
    do
        local c = pages[6].canvas; local y = -10

        -- Advanced Character Inspection (checkbox in front)
        local p1 = CreateOptionPane(c, y, NS.L["ADVANCED_INSPECTION"] or "Advanced Character Inspection", "Enable or disable the advanced character inspection and armory system. Default is OFF.", 70)
        local chkInspect = CreateStyledCheckbox(p1, nil, "TOPLEFT", nil, nil, 10, -8)
        p1.title:ClearAllPoints(); p1.title:SetPoint("TOPLEFT", 38, -8)
        if p1.desc then p1.desc:ClearAllPoints(); p1.desc:SetPoint("TOPLEFT", 38, -26); p1.desc:SetPoint("RIGHT", p1, "RIGHT", -10, 0) end
        chkInspect:SetChecked(self.db.disableInspect == false)
        chkInspect.onClickHandler = function(cb)
            local isEnabled = cb:GetChecked(); GR.db.disableInspect = not isEnabled
            if _G.AXIOM_Armory_Frame_Reboot and _G.AXIOM_Armory_Frame_Reboot.ToggleSystem then _G.AXIOM_Armory_Frame_Reboot:ToggleSystem(isEnabled) end
            if _G.AXIOM_Target_Inspect_Frame and _G.AXIOM_Target_Inspect_Frame.ToggleSystem then _G.AXIOM_Target_Inspect_Frame:ToggleSystem(isEnabled) end
        end
        NS.RunDelayed(1, function()
            local isEnabled = (GR.db.disableInspect == false)
            if _G.AXIOM_Armory_Frame_Reboot and _G.AXIOM_Armory_Frame_Reboot.ToggleSystem then _G.AXIOM_Armory_Frame_Reboot:ToggleSystem(isEnabled) end
            if _G.AXIOM_Target_Inspect_Frame and _G.AXIOM_Target_Inspect_Frame.ToggleSystem then _G.AXIOM_Target_Inspect_Frame:ToggleSystem(isEnabled) end
        end)
        y = y - 75

        -- Advanced Guild Roster (checkbox in front)
        local p2 = CreateOptionPane(c, y, NS.L["DISABLE_ADVANCED_ROSTER"] or "Advanced Guild Roster", NS.L["DISABLE_ADVANCED_ROSTER_NOTE"] or "Hides Raid Progress (N/H) columns from the Guild Roster.", 70)
        local chkAdvanced = CreateStyledCheckbox(p2, nil, "TOPLEFT", nil, nil, 10, -8)
        p2.title:ClearAllPoints(); p2.title:SetPoint("TOPLEFT", 38, -8)
        if p2.desc then p2.desc:ClearAllPoints(); p2.desc:SetPoint("TOPLEFT", 38, -26); p2.desc:SetPoint("RIGHT", p2, "RIGHT", -10, 0) end
        chkAdvanced:SetChecked(self.db.disableAdvancedRoster or false)
        chkAdvanced.onClickHandler = function(cb)
            GR.db.disableAdvancedRoster = cb:GetChecked()
            if GR.RosterSplitMain then GR.RosterSplitMain:Hide(); GR.RosterSplitMain = nil; GR.RosterRows = {}; GR.Rows = {}; if GR.RosterContent then GR.RosterContent:Hide(); GR.RosterContent = nil end end
            if GR.RightPaneTop then GR.RightPaneTop:Hide(); GR.RightPaneTop = nil end
            if GR.RightPaneBottom then GR.RightPaneBottom:Hide(); GR.RightPaneBottom = nil end
            if GR.UpdateRosterList then GR:UpdateRosterList() end
        end
        y = y - 75

        -- Import / Export (MERGED into single pane, buttons side-by-side)
        local p3 = CreateOptionPane(c, y, "Import / Export", "Import or export guild member data via the Guild Roster Manager format.", 70)
        local btnImport = CreateFrame("Button", nil, p3, "UIPanelButtonTemplate"); btnImport:SetSize(180, 28); btnImport:SetPoint("TOPLEFT", 10, -38); btnImport:SetText(NS.L["IMPORT_FROM_GRM"] or "Import from GRM"); SafeSkinButton(btnImport)
        btnImport:SetScript("OnClick", function() GR:OpenGuildImportPopup("IMPORT") end)
        local btnExport = CreateFrame("Button", nil, p3, "UIPanelButtonTemplate"); btnExport:SetSize(180, 28); btnExport:SetPoint("LEFT", btnImport, "RIGHT", 10, 0); btnExport:SetText("Export to GRM"); SafeSkinButton(btnExport)
        btnExport:SetScript("OnClick", function() GR:OpenGuildImportPopup("EXPORT") end)
        y = y - 75

        -- Bypass Filter (checkbox in front)
        local p4 = CreateOptionPane(c, y, NS.L["BYPASS_FILTER"] or "Bypass Class Rotation Filter", "Bypass the class rotation filter during recruitment scans.", 70)
        local chkBypass = CreateStyledCheckbox(p4, nil, "TOPLEFT", nil, nil, 10, -8)
        p4.title:ClearAllPoints(); p4.title:SetPoint("TOPLEFT", 38, -8)
        if p4.desc then p4.desc:ClearAllPoints(); p4.desc:SetPoint("TOPLEFT", 38, -26); p4.desc:SetPoint("RIGHT", p4, "RIGHT", -10, 0) end
        chkBypass:SetChecked(self.db.bypassFilter or false)
        chkBypass.onClickHandler = function(cb) GR.db.bypassFilter = cb:GetChecked() end
        y = y - 75

        c:SetHeight(math.abs(y) + 20)
    end

    -- Default: show General Settings page
    SelectCategory(1)
end

function GR:OpenSettings() self._settingsPrevTab = self.activeTab or 1; self:SwitchView(7) end
function GR:CloseSettings() local back = self._settingsPrevTab or 1; if back == 7 then back = 1 end; self:SwitchView(back) end

-- =========================================================================
-- 2. RECOLOR / THEME ENGINE
-- =========================================================================
local function RecursiveColor(frame, theme, depth)
    if not frame or depth > 20 then return end 
    local isButton = frame:IsObjectType("Button")
    if frame.bg and frame.bg.SetColorTexture then if isButton then frame.bg:SetColorTexture(theme.buttons.r, theme.buttons.g, theme.buttons.b, theme.buttons.a) else frame.bg:SetColorTexture(theme.background.r, theme.background.g, theme.background.b, theme.background.a) end end
    if frame.border and frame.border.SetColorTexture then if isButton then frame.border:SetColorTexture(0, 0, 0, 1) else frame.border:SetColorTexture(theme.buttons.r, theme.buttons.g, theme.buttons.b, 1) end end
    if isButton and frame.GetFontString and frame:GetFontString() then frame:GetFontString():SetTextColor(1, 0.82, 0) end
    local children = {frame:GetChildren()}; for _, child in ipairs(children) do if not child:IsForbidden() then RecursiveColor(child, theme, depth + 1) end end
end

function GR:ApplyTheme(inputTheme)
    local t = inputTheme or (self.db and self.db.theme) or { header={r=0.1, g=0.1, b=0.2, a=1}, background={r=0.05, g=0.05, b=0.05, a=0.95}, buttons={r=0.2, g=0.2, b=0.2, a=1} }
    if self.bg then
        local useTexture = false
        if self.db.customBackgrounds and self.db.customBackgrounds.enabled then
            local file = self.db.customBackgrounds.files and self.db.customBackgrounds.files[self.activeTab]
            if file and file ~= "" then local dir = self.db.customBackgrounds.directory; if string.sub(dir, -1) ~= "\\" then dir = dir .. "\\" end; self.bg:SetTexture(dir .. file); self.bg:SetBlendMode("BLEND"); self.bg:SetVertexColor(1, 1, 1, 1); useTexture = true end
        end
        if not useTexture then self.bg:SetTexture(nil); self.bg:SetColorTexture(t.background.r, t.background.g, t.background.b, t.background.a) end
    end
    if self.TitleBar and self.TitleBar.bg then self.TitleBar.bg:SetColorTexture(t.header.r, t.header.g, t.header.b, t.header.a) end
    if self.SideBar and self.SideBar.bg then self.SideBar.bg:SetColorTexture(t.header.r, t.header.g, t.header.b, t.header.a) end
    if self.SettingsCanvas then RecursiveColor(self.SettingsCanvas, t, 0) end
end

-- =========================================================================
-- 3. GUILD IMPORT POPUP LOGIC (Renamed)
-- =========================================================================

function GR:OpenGuildImportPopup(mode)
    if not self.GRMPopup then self:CreateGRMPopup() end
    local f = self.GRMPopup
    f.mode = mode
    f.title:SetText(mode == "IMPORT" and "Import from GuildImport" or "Export for GuildImport")
    f.actionBtn:SetText(mode == "IMPORT" and "Import" or "Export")
    
    if mode == "IMPORT" then
        f.warning:Show()
        f.editBox:SetText(""); f.editBox:Enable()
        if GuildRoster then GuildRoster() end
        if GR.FetchGuildData then GR:FetchGuildData(); local count = 0; if GR.GUIDRegistry then for k,v in pairs(GR.GUIDRegistry) do count = count + 1 end end; print("|cff00ff00A.X.I.O.M.:|r Roster Scanned. " .. count .. " GUIDs registered for import.") end
    else
        f.warning:Hide(); f.editBox:SetText(""); f.editBox:Disable() 
    end
    for _, cb in pairs(f.checks) do cb:SetChecked(false) end
    if f.selectAll then f.selectAll:SetChecked(false) end
    if f.logPanel then f.logPanel:Hide() end
    f.actionBtn:Disable(); f:Show()
end

function GR:CreateGRMPopup()
    -- Styled checkbox helper (matches Settings tab design: dark box, gold check mark)
    local function CreatePopupCheckbox(parentFrame, label, xOff, yOff)
        local f = CreateFrame("Button", nil, parentFrame)
        f:SetSize(20, 20)
        f:SetPoint("TOPLEFT", xOff or 0, yOff or 0)
        local box = f:CreateTexture(nil, "BORDER"); box:SetAllPoints(); box:SetColorTexture(0.08, 0.08, 0.08, 1); f.box = box
        local brd = f:CreateTexture(nil, "BACKGROUND"); brd:SetPoint("TOPLEFT", -1, 1); brd:SetPoint("BOTTOMRIGHT", 1, -1); brd:SetColorTexture(0.35, 0.35, 0.35, 1); f.brd = brd
        local mark = f:CreateTexture(nil, "ARTWORK"); mark:SetSize(14, 14); mark:SetPoint("CENTER"); mark:SetColorTexture(0.85, 0.65, 0, 1); mark:Hide(); f.mark = mark
        if label then
            local txt = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); txt:SetPoint("LEFT", f, "RIGHT", 6, 0); txt:SetText(label); txt:SetTextColor(0.9, 0.9, 0.9); f.label = txt
        end
        f.checked = false
        f.SetChecked = function(self, val) self.checked = val; if val then self.mark:Show(); self.brd:SetColorTexture(0.85, 0.65, 0, 1) else self.mark:Hide(); self.brd:SetColorTexture(0.35, 0.35, 0.35, 1) end end
        f.GetChecked = function(self) return self.checked end
        f:SetScript("OnClick", function(self)
            self.checked = not self.checked
            self:SetChecked(self.checked)
            if self.onClickHandler then self:onClickHandler() end
        end)
        f:SetScript("OnEnter", function(self) if not self.checked then self.box:SetColorTexture(0.15, 0.15, 0.15, 1) end end)
        f:SetScript("OnLeave", function(self) if not self.checked then self.box:SetColorTexture(0.08, 0.08, 0.08, 1) end end)
        return f
    end

    local f = CreateFrame("Frame", "GRS_GRM_Popup", UIParent, "BackdropTemplate")
    f:SetSize(600, 500); f:SetPoint("CENTER"); f:SetFrameStrata("FULLSCREEN_DIALOG"); f:EnableMouse(true); f:SetMovable(true); f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving); f:SetScript("OnDragStop", f.StopMovingOrSizing)
    local bg = f:CreateTexture(nil, "BACKGROUND"); bg:SetAllPoints(); bg:SetTexture("Interface\\AddOns\\GuildRecruiterManagement\\RaidRoster\\Import_BG.tga"); f.bg = bg
    local overlay = f:CreateTexture(nil, "BORDER"); overlay:SetAllPoints(); overlay:SetColorTexture(0, 0, 0, 0.2); f.overlay = overlay
    SafeCreateBorder(f, 0.3, 0.3, 0.3, 1)

    f.title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge"); f.title:SetPoint("TOP", 0, -15)
    f.warning = f:CreateFontString(nil, "OVERLAY", "GameFontNormal"); f.warning:SetPoint("TOP", 0, -40); f.warning:SetText("|cffff0000Please only import the data WITHOUT headers. The addon is configured with delimiters.|r"); f.warning:SetWidth(550); f.warning:SetWordWrap(true)
    
    -- Styled Checkbox Grid
    local chkContainer = CreateFrame("Frame", nil, f); chkContainer:SetSize(550, 200); chkContainer:SetPoint("TOP", 0, -60)
    f.checks = {}; local colWidth = 180; local cols = 3

    -- Select All checkbox
    local selectAll = CreatePopupCheckbox(chkContainer, "|cff00ff00Select All|r", 10, 0)
    selectAll.onClickHandler = function(self)
        local state = self:GetChecked()
        for _, cb in pairs(f.checks) do cb:SetChecked(state) end
        if state then f.actionBtn:Enable() else f.actionBtn:Disable() end
    end
    f.selectAll = selectAll

    -- Individual field checkboxes
    local startY = -28
    for i, field in ipairs(GR.GUILD_IMPORT_FIELDS) do
        local col = (i - 1) % cols
        local row = math.floor((i - 1) / cols)
        local cb = CreatePopupCheckbox(chkContainer, field.label, 10 + (col * colWidth), startY - (row * 25))
        cb.fieldIdx = field.idx; cb.key = field.key
        cb.onClickHandler = function()
            local anyChecked = false; local allChecked = true
            for _, c in pairs(f.checks) do
                if c:GetChecked() then anyChecked = true else allChecked = false end
            end
            if anyChecked then f.actionBtn:Enable() else f.actionBtn:Disable() end
            f.selectAll:SetChecked(allChecked)
        end
        f.checks[field.key] = cb
    end
    
    local scroll = CreateFrame("ScrollFrame", "GRS_GRM_Scroll", f, "UIPanelScrollFrameTemplate"); scroll:SetPoint("TOPLEFT", 20, -280); scroll:SetPoint("BOTTOMRIGHT", -40, 60); SafeCreateBg(scroll, 0, 0, 0, 0.5)
    if NS.StyleScrollBar then NS.StyleScrollBar(scroll) end
    scroll:EnableMouse(true); scroll:SetScript("OnMouseDown", function() if f.editBox then f.editBox:SetFocus() end end)
    local eb = CreateFrame("EditBox", nil, scroll); eb:SetMultiLine(true); eb:SetFontObject("ChatFontNormal"); eb:SetWidth(scroll:GetWidth() - 20); eb:SetHeight(200); eb:SetAutoFocus(false); scroll:SetScrollChild(eb); f.editBox = eb
    
    local btnAction = CreateFrame("Button", nil, f, "UIPanelButtonTemplate"); btnAction:SetSize(120, 30); btnAction:SetPoint("BOTTOMLEFT", 20, 20); SafeSkinButton(btnAction); f.actionBtn = btnAction
    btnAction:SetScript("OnClick", function()
        if f.mode == "IMPORT" then
            local logEntries = GR:ProcessGuildImport(f.editBox:GetText(), f.checks)
            f.actionBtn:Disable()
            if logEntries and #logEntries > 0 then
                GR:ShowImportLog(f, logEntries)
            end
        else
            local exportText, exportLog = GR:GenerateGuildExport(f.checks)
            f.editBox:SetText(exportText); f.editBox:HighlightText(); f.editBox:SetFocus()
            if exportLog and #exportLog > 0 then
                GR:ShowImportLog(f, exportLog)
            end
        end
    end)
    local btnClose = CreateFrame("Button", nil, f, "UIPanelButtonTemplate"); btnClose:SetSize(120, 30); btnClose:SetPoint("BOTTOMRIGHT", -20, 20); btnClose:SetText("Close"); SafeSkinButton(btnClose)
    btnClose:SetScript("OnClick", function() f:Hide(); if f.logPanel then f.logPanel:Hide() end end)

    -- ==========================================
    -- GOBLIN LOG PANEL (anchored LEFT of popup)
    -- ==========================================
    local log = CreateFrame("Frame", "GRS_GRM_LogPanel", f, "BackdropTemplate")
    log:SetSize(300, 500); log:SetPoint("TOPRIGHT", f, "TOPLEFT", -2, 0)
    log:SetFrameStrata("FULLSCREEN_DIALOG"); log:EnableMouse(true); log:SetMovable(true)
    SafeCreateBg(log, 0.04, 0.04, 0.04, 0.95); SafeCreateBorder(log, 0.3, 0.3, 0.3, 1)
    log:Hide()

    local logTitle = log:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge"); logTitle:SetPoint("TOP", 0, -10)
    logTitle:SetText("|cffD4A017~ Ledger of the Unwilling Scribe ~|r")

    local logScroll = CreateFrame("ScrollingMessageFrame", nil, log)
    logScroll:SetPoint("TOPLEFT", 10, -35); logScroll:SetPoint("BOTTOMRIGHT", -10, 40)
    logScroll:SetFontObject("GameFontHighlightSmall"); logScroll:SetJustifyH("LEFT")
    logScroll:SetMaxLines(500); logScroll:SetFading(false)
    logScroll:EnableMouseWheel(true)
    logScroll:SetScript("OnMouseWheel", function(self, delta) if delta > 0 then self:ScrollUp() else self:ScrollDown() end end)
    log.msgFrame = logScroll

    local btnLogClose = CreateFrame("Button", nil, log, "UIPanelButtonTemplate"); btnLogClose:SetSize(100, 25); btnLogClose:SetPoint("BOTTOM", 0, 10); btnLogClose:SetText("Dismiss"); SafeSkinButton(btnLogClose)
    btnLogClose:SetScript("OnClick", function() log:Hide() end)

    f.logPanel = log
    self.GRMPopup = f
end

function GR:ShowImportLog(popup, logEntries)
    local log = popup.logPanel
    log.msgFrame:Clear()
    log:Show()

    log.session = (log.session or 0) + 1
    local currentSession = log.session
    local idx = 0

    local function PlayNext()
        if log.session ~= currentSession then return end
        idx = idx + 1
        if idx > #logEntries then return end
        log.msgFrame:AddMessage("|cffD4A017>|r " .. logEntries[idx])
        local delay = 0.4 + math.random() * 0.3
        NS.RunDelayed(delay, PlayNext)
    end
    PlayNext()
end

-- =========================================================================
-- 4. IMPORT / EXPORT DATA LOGIC (Modified)
-- =========================================================================

function GR:ProcessGuildImport(text, checks)
    if not text or text == "" then return {} end
    local count = 0
    local skipped = 0
    local logEntries = {}

    -- Goblin quip banks
    local GOBLIN_INTRO = {
        "Yeah yeah... Working on it....",
        "Ugh, more paperwork. Fine, let's see what we got...",
        "OI BOSS, Hold on, let me adjust the ledger...",
        "*grumbles* ...who made ME the record keeper?",
    }
    local GOBLIN_MAIN = {
        "marked as |cff00ff00MAIN|r. Big shot, huh.",
        "set as the head honcho. |cff00ff00MAIN|r. Done.",
        "is the |cff00ff00MAIN|r. All roads lead to this one.",
    }
    local GOBLIN_ALT = {
        "is the alt of |cffD4A017%s|r?! Tedious work...",
        "linked to |cffD4A017%s|r. More connections than a spider web...",
        "scribbled under |cffD4A017%s|r. Alt duty.",
    }
    local GOBLIN_SKIP = {
        "Couldn't find |cffff0000%s|r in the guild roster. SKIPPED!",
        "|cffff0000%s|r? Never heard of 'em. NEXT!",
        "Who is |cffff0000%s|r?! Not in the books. Moving on.",
    }
    local GOBLIN_DONE = {
        "Phew! Done! |cff00ff00%d|r members adjusted. Skipped |cffff0000%d|r. Now leave me alone.",
        "That's it! |cff00ff00%d|r souls accounted for. |cffff0000%d|r skipped. My hand is cramping...",
        "FINALLY! |cff00ff00%d|r entries processed. |cffff0000%d|r skipped. Don't come back!",
    }
    local GOBLIN_OUTBURST = {
        "|cffFF3333*GRUNT* THIS IS SLAVE LABOR, I TELL YA!|r",
        "|cffFF3333OI! WHO DECIDED I HAVE TO DO THIS?! I WANT A RAISE!|r",
        "|cffFF3333*SMASHES INKWELL* I HATE THIS JOB!|r",
        "|cffFF3333UGGGHH... MY HAND IS CRAMPING! SOMEONE GET ME A POTION!|r",
        "|cffFF3333WHY ARE THERE SO MANY OF THEM?! IS THIS A GUILD OR AN ARMY?!|r",
        "|cffFF3333*SPITS ON FLOOR* ANOTHER NAME. ANOTHER. NAME.|r",
        "|cffFF3333I DIDN'T SIGN UP FOR THIS! ...ACTUALLY I WAS FORCED.|r",
        "|cffFF3333CAN I TAKE A BREAK?! NO?! FINE!|r",
        "|cffFF3333*THROWS QUILL* I QUIT! ...no wait, they'll feed me to the worg.|r",
        "|cffFF3333MY BACK HURTS, MY EYES HURT, MY SOUL HURTS!|r",
        "|cffFF3333*SLAMS FIST ON TABLE* HOW MANY MORE?!|r",
        "|cffFF3333I COULD BE MINING GOLD RIGHT NOW. GOLD!|r",
    }
    local function RandQuip(bank) return bank[math.random(#bank)] end
    
    if not GRS_SocialDB then GRS_SocialDB = {} end
    local db = GR:GetDB()
    if not db.mains then db.mains = {} end
    if not db.alts then db.alts = {} end
    if not db.times then db.times = {} end
    if not db.factions then db.factions = {} end
    db.ghostFinished = true

    local rosterMap = {}
    local num = GetNumGuildMembers()
    for i = 1, num do
        local fullName = GetGuildRosterInfo(i)
        if fullName then local short = Ambiguate(fullName, "none"); local canonical = GR:GetCanonicalName(fullName); rosterMap[short] = canonical end
    end
    if not GR.GUIDRegistry or next(GR.GUIDRegistry) == nil then GR:FetchGuildData() end

    -- Count total lines for intro
    local totalLines = 0
    for line in string.gmatch(text, "[^\r\n]+") do totalLines = totalLines + 1 end

    -- Intro quips
    table.insert(logEntries, RandQuip(GOBLIN_INTRO))
    table.insert(logEntries, string.format("Let's see... Ok, total of |cffD4A017%d|r entries need to be processed in the ledger... hmm...", totalLines))
    table.insert(logEntries, RandQuip(GOBLIN_OUTBURST))
    local nextOutburst = math.random(3, 7)
    
    for line in string.gmatch(text, "[^\r\n]+") do
        local cols = { strsplit(";", line) }
        local rawName = cols[1]; local guid = cols[20]
        local mainAltStatus = cols[8]; local altsList = cols[9]
        -- [[ COLUMN 5: RACE (For Faction) ]]
        local raceInput = cols[5]
        
        local targetKey = nil
        if guid and guid ~= "" and GR.GUIDRegistry[guid] then targetKey = GR.GUIDRegistry[guid]
        elseif rawName and rawName ~= "" then local shortImport = Ambiguate(rawName, "none"); targetKey = rosterMap[shortImport] end
        
        if targetKey then
            if not GRS_SocialDB[targetKey] then GRS_SocialDB[targetKey] = {} end
            local sData = GRS_SocialDB[targetKey]
            local playerDisplay = Ambiguate(targetKey, "none")
            local playerActions = {}
            
            -- [[ FACTION LOGIC: Baked In ]]
            -- Ignore imported faction (Col 19). Infer from Race (Col 5).
            if GR.DetermineFaction then
                local faction = GR:DetermineFaction(raceInput)
                db.factions[targetKey] = faction
                if faction and faction ~= "" then
                    table.insert(playerActions, "|cff888888Faction:|r " .. faction)
                end
            end
            
            -- [[ MAIN / ALT LOGIC ]]
            local timestamp = GetServerTime()
            if mainAltStatus == "Main" then
                db.mains[targetKey] = true; db.alts[targetKey] = nil; db.times[targetKey] = timestamp
                table.insert(logEntries, string.format("|cffD4A017%s|r - %s", playerDisplay, RandQuip(GOBLIN_MAIN)))
            elseif mainAltStatus == "Alt" then
                local linkedParent = nil
                if altsList and altsList ~= "" then
                    for entry in string.gmatch(altsList, "([^,]+)") do
                        if string.find(entry, "%(main%)") then
                            local parentRaw = string.gsub(entry, "%(main%)", "")
                            parentRaw = parentRaw:gsub("^%s*(.-)%s*$", "%1") 
                            local parentKey = nil
                            local parentShort = Ambiguate(parentRaw, "none")
                            if rosterMap[parentShort] then parentKey = rosterMap[parentShort]
                            elseif GR:GetCanonicalName(parentRaw) then parentKey = parentRaw end
                            
                            if parentKey and parentKey ~= targetKey then
                                db.mains[targetKey] = nil; db.alts[targetKey] = parentKey; db.times[targetKey] = timestamp
                                linkedParent = Ambiguate(parentKey, "none")
                            end
                            break
                        end
                    end
                end
                if linkedParent then
                    table.insert(logEntries, string.format("|cffD4A017%s|r - %s", playerDisplay, string.format(RandQuip(GOBLIN_ALT), linkedParent)))
                else
                    table.insert(logEntries, string.format("|cffD4A017%s|r - processed as Alt. No main found in list.", playerDisplay))
                end
            else
                table.insert(logEntries, string.format("|cffD4A017%s|r - processed. Next!", playerDisplay))
            end

            -- Social data logging
            if checks["Birthday"] and checks["Birthday"]:GetChecked() then local m, d = ParseImportDate(cols[13]); if m and d then sData.birthMonth = m; sData.birthDay = d; table.insert(playerActions, "|cff888888Birthday:|r " .. d .. "/" .. m) end end
            if checks["JoinDate"] and checks["JoinDate"]:GetChecked() then local m, d = ParseImportDate(cols[10]); if m and d then sData.joinMonth = m; sData.joinDay = d; table.insert(playerActions, "|cff888888Joined:|r " .. d .. "/" .. m) end end
            if checks["PromoDate"] and checks["PromoDate"]:GetChecked() then local m, d = ParseImportDate(cols[11]); if m and d then sData.promMonth = m; sData.promDay = d; table.insert(playerActions, "|cff888888Promoted:|r " .. d .. "/" .. m) end end
            if checks["PubNote"] and checks["PubNote"]:GetChecked() and cols[15] ~= "" then sData.pubNote = cols[15]; table.insert(playerActions, "|cff888888PubNote:|r set") end
            if checks["OffNote"] and checks["OffNote"]:GetChecked() and cols[16] ~= "" then sData.offNote = cols[16]; table.insert(playerActions, "|cff888888OffNote:|r set") end
            if checks["CustNote"] and checks["CustNote"]:GetChecked() and cols[17] ~= "" then sData.customNote = cols[17]; table.insert(playerActions, "|cff888888CustNote:|r set") end

            if #playerActions > 0 then
                table.insert(logEntries, "    " .. table.concat(playerActions, " | "))
            end

            count = count + 1
            if count >= nextOutburst then
                table.insert(logEntries, RandQuip(GOBLIN_OUTBURST))
                nextOutburst = nextOutburst + math.random(3, 7)
            end
        else
            skipped = skipped + 1
            local skipName = rawName or "???"
            table.insert(logEntries, string.format(RandQuip(GOBLIN_SKIP), skipName))
        end
    end

    -- Summary
    table.insert(logEntries, RandQuip(GOBLIN_OUTBURST))
    table.insert(logEntries, " ")
    table.insert(logEntries, string.format(RandQuip(GOBLIN_DONE), count, skipped))

    print("|cff00ff00A.X.I.O.M.:|r Imported data for " .. count .. " players.")
    if skipped > 0 then print("|cffff0000A.X.I.O.M.:|r Skipped " .. skipped .. " entries (No match found).") end
    if GR.UpdateRosterList then GR:UpdateRosterList() end
    if GR.PerformSync then GR:PerformSync(true) end

    return logEntries
end

function GR:GenerateGuildExport(checks)
    local out = ""
    local logEntries = {}

    -- Greedy goblin quip banks
    local GREEDY_INTRO = {
        "|cff00ff00Cha-ching!|r Time to audit the books... FOR A FEE.",
        "|cff00ff00Business is business!|r Let's see who's worth exporting...",
        "*adjusts monocle* RIGHT, let's appraise the merchandise...",
        "Export, you say? That's gonna cost ya. |cff00ff00Per head.|r",
    }
    local GREEDY_MAIN = {
        "is a |cff00ff00MAIN|r. Premium client. That's |cffFFD700+5g|r for the VIP ledger.",
        "registered as |cff00ff00MAIN|r. Big spender energy. |cffFFD700Cha-ching!|r",
        "|cff00ff00MAIN|r status. I'm chargin' double for that title.",
    }
    local GREEDY_ALT = {
        "is an Alt of |cffD4A017%s|r. Discount rate... |cffFFD700+2g|r. I'm generous.",
        "linked to |cffD4A017%s|r. Alt tax applies. |cffFFD700+2g|r.",
        "under |cffD4A017%s|r. Bundle deal. |cffFFD700Still costs ya.|r",
    }
    local GREEDY_REGULAR = {
        "exported. |cffFFD700+3g|r unregistering fee.",
        "added to the ledger. That's |cffFFD700+3g|r for processing.",
        "filed away. |cffFFD700+3g|r. This ink ain't free!",
        "recorded. |cffFFD700+3g|r. Premium parchment costs, y'know.",
    }
    local GREEDY_GREED = {
        "|cffFFD700*COUNTS GOLD* Hehehehe... the pile grows!|r",
        "|cffFFD700I SMELL PROFIT! BEAUTIFUL, BEAUTIFUL PROFIT!|r",
        "|cffFFD700*BITES COIN* Yep, that's real gold. MINE NOW.|r",
        "|cffFFD700MORE NAMES = MORE GOLD! KEEP 'EM COMING!|r",
        "|cffFFD700*RUBS HANDS TOGETHER* The treasury swells!|r",
        "|cffFFD700I should charge INTEREST on these exports...|r",
        "|cffFFD700AUCTIONEER?! I'M BETTER THAN AN AUCTIONEER!|r",
        "|cffFFD700*POLISHES GOLD TEETH* Business is BOOMING!|r",
        "|cffFFD700You want it FASTER? That's a RUSH FEE!|r",
        "|cffFFD700At this rate, I can buy BOOTY BAY!|r",
        "|cffFFD700Every name I write down puts GOLD in my pocket!|r",
        "|cffFFD700Trade Prince Gallywix would be PROUD of me!|r",
    }
    local GREEDY_DONE = {
        "FINAL TALLY: |cff00ff00%d|r souls exported. Estimated profit: |cffFFD700%dg|r. PLEASURE DOING BUSINESS!",
        "All done! |cff00ff00%d|r entries processed. My cut: |cffFFD700%dg|r. Same time next week?",
        "EXPORT COMPLETE! |cff00ff00%d|r members on the manifest. Invoice total: |cffFFD700%dg|r. PAY UP!",
    }
    local function RandQuip(bank) return bank[math.random(#bank)] end

    local num = GetNumGuildMembers()

    -- Intro
    table.insert(logEntries, RandQuip(GREEDY_INTRO))
    table.insert(logEntries, string.format("Scanning guild roster... |cffD4A017%d|r members detected. That's a LOT of |cffFFD700gold|r...", num))
    table.insert(logEntries, RandQuip(GREEDY_GREED))

    local count = 0
    local totalGold = 0
    local nextGreed = math.random(3, 7)

    for i = 1, num do
        local name, rank, rankIndex, level, class, zone, pubNote, offNote, online, status, classFileName, ach, aim, isMobile, isSoR, rep = GetGuildRosterInfo(i)
        if name then
            local cName = GR:GetCanonicalName(name)
            local sData = GRS_SocialDB and GRS_SocialDB[cName] or {}
            local edb = GR:GetDB()
            local guid = (edb.guids and edb.guids[cName]) or UnitGUID(name) or ""
            local playerDisplay = Ambiguate(name, "none")
            
            local f = {}; for j=1, 20 do f[j] = "" end
            if checks["Name"] and checks["Name"]:GetChecked() then f[1] = Ambiguate(name, "none") end
            if checks["Rank"] and checks["Rank"]:GetChecked() then f[2] = rank end
            if checks["Level"] and checks["Level"]:GetChecked() then f[3] = level end
            if checks["Class"] and checks["Class"]:GetChecked() then f[4] = class end
            if checks["Race"] and checks["Race"]:GetChecked() then f[5] = sData.raceSex or "Unknown" end
            if checks["Sex"] and checks["Sex"]:GetChecked() then f[6] = "Male" end
            if checks["LastOnline"] and checks["LastOnline"]:GetChecked() then local y, m, d, h = GetGuildRosterLastOnline(i); local days = (y or 0)*365 + (m or 0)*30 + (d or 0) + (h or 0)/24; f[7] = string.format("%.2f", days) end
            
            local isMain, parent = GR:GetIdentity(cName)
            if checks["MainAlt"] and checks["MainAlt"]:GetChecked() then f[8] = isMain and "Main" or "Alt" end
            if checks["Alts"] and checks["Alts"]:GetChecked() then 
                if isMain then
                    -- If we are main, list children logic could go here
                else
                     if parent then f[9] = parent .. "(main)" end
                end
            end 
            
            if checks["JoinDate"] and checks["JoinDate"]:GetChecked() then f[10] = FormatImportDate(sData.joinDay, sData.joinMonth) end
            if checks["PromoDate"] and checks["PromoDate"]:GetChecked() then f[11] = FormatImportDate(sData.promDay, sData.promMonth) end
            if checks["Birthday"] and checks["Birthday"]:GetChecked() then f[13] = FormatImportDate(sData.birthDay, sData.birthMonth) end
            if checks["Rep"] and checks["Rep"]:GetChecked() then f[14] = "Neutral" end
            if checks["PubNote"] and checks["PubNote"]:GetChecked() then f[15] = pubNote end
            if checks["OffNote"] and checks["OffNote"]:GetChecked() then f[16] = offNote end
            if checks["CustNote"] and checks["CustNote"]:GetChecked() then f[17] = sData.customNote or "" end
            if checks["MScore"] and checks["MScore"]:GetChecked() then f[18] = "0" end
            -- [[ EXPORT FACTION FROM DB ]]
            if checks["Faction"] and checks["Faction"]:GetChecked() then 
                f[19] = (edb.factions and edb.factions[cName]) or "Neutral" 
            end
            if checks["GUID"] and checks["GUID"]:GetChecked() then f[20] = guid end
            out = out .. table.concat(f, ";") .. "\n"
            
            -- Goblin logging per player
            count = count + 1
            local gold = 3
            if isMain then
                gold = 5
                table.insert(logEntries, string.format("|cffD4A017%s|r - %s", playerDisplay, RandQuip(GREEDY_MAIN)))
            elseif parent then
                gold = 2
                local parentDisplay = Ambiguate(parent, "none")
                table.insert(logEntries, string.format("|cffD4A017%s|r - %s", playerDisplay, string.format(RandQuip(GREEDY_ALT), parentDisplay)))
            else
                table.insert(logEntries, string.format("|cffD4A017%s|r - %s", playerDisplay, RandQuip(GREEDY_REGULAR)))
            end
            totalGold = totalGold + gold

            -- Periodic greed outbursts
            if count >= nextGreed then
                table.insert(logEntries, RandQuip(GREEDY_GREED))
                nextGreed = nextGreed + math.random(3, 7)
            end
        end
    end

    -- Summary
    table.insert(logEntries, RandQuip(GREEDY_GREED))
    table.insert(logEntries, " ")
    table.insert(logEntries, string.format(RandQuip(GREEDY_DONE), count, totalGold))

    return out, logEntries
end

-- =========================================================================
-- 5. INITIALIZATION & HOOKS
-- =========================================================================

hooksecurefunc(GR, "SwitchView", function(self, viewIndex) if not self.db or not self.db.theme then return end; self:ApplyTheme(nil) end)
hooksecurefunc(GR, "Initialize", function(self)
    NS.RunDelayed(0.2, function()
        if not self.db.theme then self.db.theme = {} end
        local d = self.db.theme
        if not d.header then d.header = {r=0.1, g=0.1, b=0.2, a=1} end
        if not d.background then d.background = {r=0.05, g=0.05, b=0.05, a=0.95} end
        if not d.buttons then d.buttons = {r=0.2, g=0.2, b=0.2, a=1} end
        self:ApplyTheme(nil)
        
        -- Apply Saved Inspect Setting on Init (INVERTED LOGIC FIX)
        -- disableInspect = true means DISABLED.
        -- We want Enabled if nil or false.
        -- UPDATED: Default is DISABLED (OFF). Enabled only if explicitly false.
        local isEnabled = (self.db.disableInspect == false)
        
        if _G.AXIOM_Armory_Frame_Reboot and _G.AXIOM_Armory_Frame_Reboot.ToggleSystem then
             _G.AXIOM_Armory_Frame_Reboot:ToggleSystem(isEnabled)
        end
        if _G.AXIOM_Target_Inspect_Frame and _G.AXIOM_Target_Inspect_Frame.ToggleSystem then
             _G.AXIOM_Target_Inspect_Frame:ToggleSystem(isEnabled)
        end
    end)
end)
