-- TOG Tools — Settings panel
-- AceConfig-3.0 options table registered with the Blizzard Interface Options
-- (ESC → Options → Addons → TOG Tools).  Also opened directly via
-- addon:OpenSettings() — called by right-click on the minimap button.

local _, addon = ...
local Ace       = addon.lib

local AceConfig = LibStub("AceConfig-3.0",       true)
local AceDialog = LibStub("AceConfigDialog-3.0", true)

if not AceConfig or not AceDialog then return end

-- ---------------------------------------------------------------------------
-- Options table — two sub-groups rendered as tabs at the top of the panel
-- (`childGroups = "tab"`):
--   General  — minimap button, debug toggle, and other addon-wide settings
--              that don't belong to a specific tab/module.
--   Modules  — one toggle per registered tab/module. Disabling a module
--              hides its tab from the main window AND stops its engine
--              (capture / event hooks short-circuit on the same flag).
--              The Modules group's args are populated dynamically from
--              `addon.modules` at registration time so new modules
--              automatically get a toggle without per-module wiring here.
-- ---------------------------------------------------------------------------
local OPTIONS = {
    name        = "TOG Tools",
    handler     = addon,
    type        = "group",
    childGroups = "tab",
    args        = {

        general = {
            name  = "General",
            type  = "group",
            order = 1,
            args  = {
                minimapHeader = {
                    name  = "Minimap Button",
                    type  = "header",
                    order = 1,
                },
                minimapButton = {
                    name  = "Show minimap button",
                    desc  = "Toggle the minimap button on or off.",
                    type  = "toggle",
                    order = 2,
                    get   = function()
                        return not (addon.DB and addon.DB.char.minimapHide)
                    end,
                    set   = function(_, val)
                        if val then
                            addon:ShowMinimapButton()
                        else
                            addon:HideMinimapButton()
                        end
                    end,
                },

                debugHeader = {
                    name  = "Debug",
                    type  = "header",
                    order = 10,
                },
                debugToggle = {
                    name  = "Verbose debug output",
                    desc  = "When enabled, TOG Tools modules print diagnostic messages to chat (hook install confirmations, event fires, etc.). Off by default.",
                    type  = "toggle",
                    order = 11,
                    get   = function()
                        return addon.DB and addon.DB.global.debug or false
                    end,
                    set   = function(_, val)
                        if addon.DB then addon.DB.global.debug = val end
                    end,
                },
            },
        },

        modules = {
            name  = "Modules",
            type  = "group",
            order = 2,
            args  = {
                desc = {
                    type     = "description",
                    order    = 0,
                    name     = "Enable or disable individual TOG Tools features. A disabled feature is hidden from the main window's tab strip AND its engine stops running — but data already collected (mailbox snapshots, etc.) is preserved and reappears when you re-enable.\n",
                    fontSize = "medium",
                },
                -- Per-module toggle args are filled in at registration time
                -- from `addon.modules`. See the hooksecurefunc block below.
            },
        },
    },
}

-- ---------------------------------------------------------------------------
-- Registration — hook OnInitialize so the DB is ready when we register.
-- Capture BOTH return values from AddToBlizOptions. The first is the panel
-- frame (unreliable as an open target — older Ace builds set categoryID on
-- it but Midnight builds don't). The second is the opaque numeric category
-- ID, which is what Settings.OpenToCategory wants. Pattern lifted from
-- FastGuildInvite / Grouper after extensive debugging — see FGI's
-- GUI/SettingsPanel.lua for the full backstory.
-- ---------------------------------------------------------------------------
local _blizPanel  = nil
local _categoryID = nil
hooksecurefunc(Ace, "OnInitialize", function()
    -- Build per-module toggles into OPTIONS.args.modules.args. Modules
    -- register themselves in `addon.modules` before OnInitialize fires
    -- (file-load-time registration), so the list is complete here. Order
    -- by `label` so the toggles appear in the same order tabs appear in
    -- the main window's strip. Multiply by 10 to leave room for an inline
    -- sub-group right after the Logs toggle (Log categories — Mail /
    -- Trade / Guild sub-toggles).
    local modulesArgs = OPTIONS.args.modules.args
    local sorted = {}
    for _, mod in pairs(addon.modules) do
        if mod.label and mod.configKey and mod.tabKey then
            sorted[#sorted + 1] = mod
        end
    end
    table.sort(sorted, function(a, b) return a.label < b.label end)
    local logsOrder = nil
    for i, mod in ipairs(sorted) do
        modulesArgs[mod.tabKey] = {
            name  = mod.label,
            desc  = "Show the " .. mod.label .. " tab and run its background engine. When off, the tab is hidden from the main window and its capture / event hooks short-circuit — re-enabling restores both.",
            type  = "toggle",
            width = "full",
            order = i * 10,
            get   = function()
                local s = addon.DB and addon.DB.global and addon.DB.global[mod.configKey]
                return s and s.enabled ~= false
            end,
            set   = function(_, val)
                local s = addon.DB and addon.DB.global and addon.DB.global[mod.configKey]
                if s then s.enabled = val and true or false end
                if addon.MainWindow and addon.MainWindow.Rebuild then
                    addon.MainWindow:Rebuild()
                end
            end,
        }
        if mod.tabKey == "logs" then logsOrder = i * 10 end
    end

    -- Inline sub-group of per-log-type toggles. Greys out when the Logs
    -- master toggle is off so users see the relationship at a glance.
    -- Each sub-engine (MailLog / future TradeLog / GuildLog) reads its
    -- own enabled flag via addon:IsLogCategoryEnabled(subKey), which
    -- ANDs the per-category flag with the Logs master flag — so disabling
    -- the master here doesn't require flipping every sub-category flag.
    if logsOrder then
        local function buildSubToggle(label, configKey, desc, order)
            return {
                type  = "toggle",
                name  = label,
                desc  = desc,
                order = order,
                width = "full",
                get   = function()
                    local s = addon.DB and addon.DB.global and addon.DB.global[configKey]
                    return s and s.enabled ~= false
                end,
                set   = function(_, val)
                    local s = addon.DB and addon.DB.global and addon.DB.global[configKey]
                    if s then s.enabled = val and true or false end
                    if addon.MainWindow and addon.MainWindow.Refresh then
                        addon.MainWindow:Refresh()
                    end
                end,
            }
        end
        modulesArgs.logCategoriesGroup = {
            type     = "group",
            inline   = true,
            name     = "Log categories",
            order    = logsOrder + 5,
            disabled = function() return not addon:IsModuleEnabled("logs") end,
            args = {
                mailLog = buildSubToggle(
                    "Mail Log",
                    "mailLog",
                    "Capture every mail received (inbox takes) and sent (composed via SendMail). When off, the Mail sub-tab is hidden and the capture hooks short-circuit. Existing entries are preserved and reappear on re-enable.",
                    10),
                tradeLog = buildSubToggle(
                    "Trade Log",
                    "tradeLog",
                    "Capture every completed player-to-player trade — both sides' items, money, and slot 7 enchants. Arena/BG trades are skipped. When off, the Trade sub-tab is hidden and the capture short-circuits. Existing entries are preserved and reappear on re-enable.",
                    20),
                guildLog = buildSubToggle(
                    "Guild Log",
                    "guildLog",
                    "Snapshot Blizzard's in-game guild event log (joins / leaves / kicks / promotes / demotes) and persist entries beyond the ~100-entry cap Blizzard keeps. Per-guild buckets so alts in different guilds keep independent histories. When off, the Guild sub-tab is hidden and the periodic query stops. Existing entries are preserved and reappear on re-enable.",
                    30),
                guildBankLog = buildSubToggle(
                    "Guild Bank Log",
                    "guildBankLog",
                    "Snapshot Blizzard's in-game guild bank transaction log every time you open the guild bank, and persist entries beyond the small rolling window Blizzard keeps. Per-guild buckets so alts in different guilds keep independent histories. Each entry carries a stable cross-viewer identifier reserved for future sync with TOGBankClassic and other TOG suite addons. When off, the Guild Bank sub-tab is hidden and capture short-circuits. Existing entries are preserved and reappear on re-enable. Classic Era has no guild banks; the tab stays present for a future TOGBankClassic integration.",
                    40),
            },
        }
    end

    AceConfig:RegisterOptionsTable("TOGTools", OPTIONS)
    _blizPanel, _categoryID = AceDialog:AddToBlizOptions("TOGTools", "TOG Tools")
end)

-- ---------------------------------------------------------------------------
-- Direct open — navigates the native Blizzard Interface Options panel to
-- the TOG Tools page. Called by the gear icon and by RMB on the minimap.
--
-- Detection order (API presence, not version flag):
--   1. Settings.OpenToCategory(categoryID)  — Retail 10.0+ AND Classic
--      Era 1.15+. Pass the OPAQUE NUMERIC ID returned by AddToBlizOptions;
--      passing the string "TOG Tools" crashes on Retail Midnight because
--      C_SettingsUtil.OpenSettingsPanel validates the arg as an integer
--      and the string fails the type check. Called twice so the panel
--      reliably navigates past the Settings landing page into our
--      sub-category (calling once sometimes only opens the root).
--   2. InterfaceOptionsFrame_OpenToCategory(panel)  — older Classic
--      (TBC / Wrath / Cata / Mists pre-1.15) — takes the panel frame,
--      not the ID. Also called twice for the same navigation reason.
-- ---------------------------------------------------------------------------
function addon:OpenSettings()
    -- Set the inhibit flag BEFORE Settings actually opens — the call
    -- below triggers CloseSpecialWindows synchronously, which would
    -- otherwise fire the proxy OnHide and close the main window. The
    -- one-time SettingsPanel:OnHide hook is also installed here so the
    -- flag gets cleared (deferred a frame) whenever Settings closes.
    if addon.MainWindow then
        addon.MainWindow._settingsOpen = true
        if addon.MainWindow._HookSettingsClose then
            addon.MainWindow:_HookSettingsClose()
        end
    end
    if Settings and Settings.OpenToCategory and _categoryID then
        Settings.OpenToCategory(_categoryID)
        Settings.OpenToCategory(_categoryID)
    elseif InterfaceOptionsFrame_OpenToCategory and _blizPanel then
        InterfaceOptionsFrame_OpenToCategory(_blizPanel)
        InterfaceOptionsFrame_OpenToCategory(_blizPanel)
    end
end
