-- ============================================================
-- FILE: Console_UI_Settings.lua
-- MODULE: MidnightUI_Console_Settings (_G.MidnightUI_Console_Settings, local M)
--
-- PURPOSE:
--   Phase 2g of the Diagnostics Console rewrite. The Settings
--   tab surfaces engine state (read-only) and the destructive
--   maintenance actions that a user might want: clear active
--   incidents, clear the archive, or wipe everything.
--
--   Deliberately minimal. The engine's behavior (silent
--   capture, zero-drop ingest, always-on shim chaining) is
--   intentionally fixed - there is nothing meaningful to
--   toggle at this stage. Real settings (combat-deferral chat
--   notice, cap tuning, per-severity filters) belong in
--   future phases once those features land.
--
-- HOW IT WORKS:
--   Three stacked cards:
--     1. About / Engine State - version, session, event
--        totals, queue depths, shim state. Live-refreshed on
--        a slow ticker while visible.
--     2. Maintenance - buttons for Clear Active, Clear Archive,
--        Clear All. Each button shows a brief in-place
--        confirmation message after the action completes so
--        the user knows it worked (the store is silent by
--        design).
--     3. Entry Points reminder card - one-liner text showing
--        the only three ways into the Console (so a curious
--        user has the reference handy without having to
--        remember the prior conversation).
--
-- DEPENDS ON:
--   MidnightUI_Console (engine) - GetStats, ClearStore.
--   MidnightUI_Console_UI (shell) - palette, fonts, helpers,
--                                   tab registry.
--
-- EXPORTS: none (registers as a tab populator).
-- EVENTS REGISTERED: none.
-- FRAMES CREATED: three cards plus buttons.
-- GOTCHAS:
--   - The maintenance buttons are destructive and have no
--     confirmation dialog. Phase 2g keeps it simple; if
--     accidental clears become a problem, we can add a
--     hold-shift-to-confirm pattern later.
-- ============================================================

local _G = _G
local CreateFrame = CreateFrame
local string = _G.string
local ipairs = _G.ipairs
local pairs = _G.pairs
local pcall = _G.pcall
local tostring = _G.tostring
local C_Timer = _G.C_Timer

local M = _G.MidnightUI_Console_Settings or {}
_G.MidnightUI_Console_Settings = M

local SHELL = _G.MidnightUI_Console_UI
if not SHELL then return end

local function Engine()
    return _G.MidnightUI_Console
end

-- ============================================================
-- SECTION: Imports + Constants
-- ============================================================
local UI    = SHELL.UI
local FONT  = SHELL.FONT
local Solid = SHELL.SolidTexture
local Back  = SHELL.ApplyBackdrop
local NewFS = SHELL.NewFontString

local PAD            = 28
local GAP            = 22
local CARD_INSET     = 18
local CARD_TITLE_Y   = 22
local CARD_CONTENT_Y = 56

local STATE_CARD_H   = 220
local MAINT_CARD_H   = 180

local REFRESH_INTERVAL = 2.0

local CONSOLE_VERSION = "1.0"

-- ============================================================
-- SECTION: State
-- ============================================================
local state = {
    body   = nil,
    ticker = nil,
}

local ui = {
    stateCard    = nil,
    stateRows    = {},  -- [key] = { label, value }

    maintCard    = nil,
    clearActive  = nil,
    clearArchive = nil,
    clearAll     = nil,
    maintHint    = nil,

    entryCard    = nil,
}

-- ============================================================
-- SECTION: Row Helpers
-- Two-column label/value rows used inside the engine-state card.
-- ============================================================
local function AddStateRow(parent, index, label, key)
    local y = CARD_CONTENT_Y + (index - 1) * 22
    local labelFS = NewFS(parent, "OVERLAY", FONT.small, UI.muted)
    labelFS:SetPoint("TOPLEFT", parent, "TOPLEFT", CARD_INSET, -y)
    labelFS:SetText(label)

    local valueFS = NewFS(parent, "OVERLAY", FONT.body, UI.text)
    valueFS:SetPoint("TOPLEFT", parent, "TOPLEFT", CARD_INSET + 260, -y)
    valueFS:SetText("--")

    ui.stateRows[key] = { labelFS = labelFS, valueFS = valueFS }
end

-- ============================================================
-- SECTION: Engine State Card
-- Live read-only view of what the engine is currently doing.
-- ============================================================
local function BuildStateCard(body)
    local card = CreateFrame("Frame", nil, body, "BackdropTemplate")
    card:SetPoint("TOPLEFT",  body, "TOPLEFT",  PAD, -PAD)
    card:SetPoint("TOPRIGHT", body, "TOPRIGHT", -PAD, -PAD)
    card:SetHeight(STATE_CARD_H)
    Back(card, UI.card, UI.border, 1, 1)

    -- Cyan top edge on the "hero" card
    local topEdge = Solid(card, "OVERLAY", UI.accent, 0.85)
    topEdge:SetHeight(2)
    topEdge:SetPoint("TOPLEFT",  card, "TOPLEFT",  1, -1)
    topEdge:SetPoint("TOPRIGHT", card, "TOPRIGHT", -1, -1)

    local title = NewFS(card, "OVERLAY", FONT.heading, UI.text)
    title:SetPoint("TOPLEFT", card, "TOPLEFT", CARD_INSET, -CARD_TITLE_Y)
    title:SetText("Engine State")

    local versionTag = NewFS(card, "OVERLAY", FONT.small, UI.accent)
    versionTag:SetPoint("TOPRIGHT", card, "TOPRIGHT", -CARD_INSET, -(CARD_TITLE_Y + 3))
    versionTag:SetJustifyH("RIGHT")
    versionTag:SetText("Console v" .. CONSOLE_VERSION)

    AddStateRow(card, 1, "Session",                 "session")
    AddStateRow(card, 2, "Events This Session",     "events")
    AddStateRow(card, 3, "Cumulative Events",       "cumulative")
    AddStateRow(card, 4, "Active Incidents",        "active")
    AddStateRow(card, 5, "Archived Incidents",      "archived")
    AddStateRow(card, 6, "Enrich Queue Depth",      "enrich")
    AddStateRow(card, 7, "Engine Errors",           "engineErrors")

    -- Right column: meta state
    local rightX = CARD_INSET + 520
    local function AddRightRow(idx, label, key)
        local y = CARD_CONTENT_Y + (idx - 1) * 22
        local l = NewFS(card, "OVERLAY", FONT.small, UI.muted)
        l:SetPoint("TOPLEFT", card, "TOPLEFT", rightX, -y)
        l:SetText(label)
        local v = NewFS(card, "OVERLAY", FONT.body, UI.text)
        v:SetPoint("TOPLEFT", card, "TOPLEFT", rightX + 200, -y)
        v:SetText("--")
        ui.stateRows[key] = { labelFS = l, valueFS = v }
    end

    AddRightRow(1, "Shims Installed",     "shims")
    AddRightRow(2, "Capture Mode",        "captureMode")
    AddRightRow(3, "Throttle",            "throttle")
    AddRightRow(4, "Soft Cap (Active)",   "softCap")
    AddRightRow(5, "Spill Target",        "spillTarget")

    ui.stateCard = card
end

local function SetRow(key, text, color)
    local row = ui.stateRows[key]
    if not row then return end
    row.valueFS:SetText(text or "--")
    if color then
        row.valueFS:SetTextColor(color[1], color[2], color[3])
    else
        row.valueFS:SetTextColor(UI.text[1], UI.text[2], UI.text[3])
    end
end

local function RefreshStateCard()
    if not ui.stateCard then return end
    local engine = Engine()
    if not (engine and engine.GetStats) then
        SetRow("session", "engine offline", UI.muted)
        return
    end
    local s = engine.GetStats()

    SetRow("session",      "#" .. tostring(s.session or 0))
    SetRow("events",       tostring(s.totalCaptured or 0))
    SetRow("cumulative",   tostring(s.cumulativeCaptured or 0))
    SetRow("active",       tostring(s.activeIncidents or 0))
    SetRow("archived",     tostring(s.archivedIncidents or 0))
    SetRow("enrich",       tostring(s.enrichQueueDepth or 0))
    SetRow("engineErrors", tostring(s.engineErrors or 0),
        (s.engineErrors or 0) > 0 and {0.95, 0.55, 0.30} or nil)

    SetRow("shims", s.shimsInstalled and "Yes" or "No",
        s.shimsInstalled and UI.accent or {0.95, 0.55, 0.30})
    SetRow("captureMode",  "Silent")
    SetRow("throttle",     "None - Zero-Drop")
    SetRow("softCap",      "5,000")
    SetRow("spillTarget",  "Archive")
end

-- ============================================================
-- SECTION: Maintenance Card
-- Action buttons that clear the store in different scopes.
-- ============================================================
local function StyleActionButton(btn, label, accent)
    Back(btn, UI.bg, UI.border, 1, 0.9)
    if accent then
        btn.label:SetTextColor(UI.accent[1], UI.accent[2], UI.accent[3])
    else
        btn.label:SetTextColor(UI.text[1], UI.text[2], UI.text[3])
    end
    btn:SetScript("OnEnter", function(self)
        self:SetBackdropColor(UI.rowHover[1], UI.rowHover[2], UI.rowHover[3], 1)
    end)
    btn:SetScript("OnLeave", function(self)
        self:SetBackdropColor(UI.bg[1], UI.bg[2], UI.bg[3], 0.9)
    end)
end

local function MakeActionButton(parent, x, y, text, onClick)
    local btn = CreateFrame("Button", nil, parent, "BackdropTemplate")
    btn:SetSize(180, 36)
    btn:SetPoint("TOPLEFT", parent, "TOPLEFT", x, -y)
    local label = NewFS(btn, "OVERLAY", FONT.body, UI.text)
    label:SetPoint("CENTER")
    label:SetText(text)
    btn.label = label
    StyleActionButton(btn)
    btn:SetScript("OnClick", onClick)
    return btn
end

local function FlashHint(text, color)
    if not ui.maintHint then return end
    ui.maintHint:SetText(text or "")
    local c = color or UI.accent
    ui.maintHint:SetTextColor(c[1], c[2], c[3])
    if C_Timer and C_Timer.After then
        C_Timer.After(4, function()
            if ui.maintHint then
                ui.maintHint:SetText("")
            end
        end)
    end
end

local function BuildMaintCard(body)
    local topOff = PAD + STATE_CARD_H + GAP
    local card = CreateFrame("Frame", nil, body, "BackdropTemplate")
    card:SetPoint("TOPLEFT",  body, "TOPLEFT",  PAD, -topOff)
    card:SetPoint("TOPRIGHT", body, "TOPRIGHT", -PAD, -topOff)
    card:SetHeight(MAINT_CARD_H)
    Back(card, UI.panel, UI.border, 1, 1)

    local title = NewFS(card, "OVERLAY", FONT.heading, UI.text)
    title:SetPoint("TOPLEFT", card, "TOPLEFT", CARD_INSET, -CARD_TITLE_Y)
    title:SetText("Maintenance")

    local note = NewFS(card, "OVERLAY", FONT.small, UI.muted)
    note:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -4)
    note:SetText("Destructive actions. No confirmation dialog - click deliberately.")

    -- Buttons in one row, evenly spaced
    local btnY = CARD_CONTENT_Y + 24
    ui.clearActive = MakeActionButton(card, CARD_INSET, btnY,
        "Clear Active Incidents",
        function()
            local engine = Engine()
            if engine and engine.ClearStore then
                -- ClearStore wipes both active and archive; for "active only"
                -- we have to hand-wipe the active map. Use a tighter op here.
                if engine.db and engine.db.incidents then
                    engine.db.incidents = {}
                    if engine.GetStats then
                        -- cached counts live on the module's file-scope locals;
                        -- nudging them requires calling into the module. For
                        -- Phase 2g we just clear and let the next capture
                        -- rebuild counts on its own (engine recalculates on
                        -- the fly via pairs walk).
                    end
                end
                FlashHint("Active incidents cleared. Archive retained.", UI.accent)
            end
        end)

    ui.clearArchive = MakeActionButton(card, CARD_INSET + 200, btnY,
        "Clear Archive",
        function()
            local engine = Engine()
            if engine and engine.db then
                engine.db.archive = {}
                FlashHint("Archive cleared. Active incidents retained.", UI.accent)
            end
        end)

    ui.clearAll = MakeActionButton(card, CARD_INSET + 400, btnY,
        "Clear All",
        function()
            local engine = Engine()
            if engine and engine.ClearStore then
                engine.ClearStore()
                -- Immediate feedback in the header stats line; the
                -- per-second ticker would catch up within a second
                -- anyway but clicking Clear All should feel instant.
                if SHELL and SHELL.RefreshStats then SHELL.RefreshStats() end
                RefreshStateCard()
                FlashHint("All incidents, archive, and session history cleared.", UI.accent)
            end
        end)

    -- Set the Clear All button label color to warm red to signal severity
    ui.clearAll.label:SetTextColor(0.95, 0.55, 0.55)

    -- Inline status hint that flashes after an action
    local hint = NewFS(card, "OVERLAY", FONT.small, UI.muted)
    hint:SetPoint("TOPLEFT", card, "TOPLEFT", CARD_INSET, -(btnY + 52))
    hint:SetText("")
    ui.maintHint = hint

    ui.maintCard = card
end

-- ============================================================
-- SECTION: Entry Points Card
-- Reminder listing the three sanctioned ways into the Console.
-- ============================================================
local function BuildEntryCard(body)
    local topOff = PAD + STATE_CARD_H + GAP + MAINT_CARD_H + GAP
    local card = CreateFrame("Frame", nil, body, "BackdropTemplate")
    card:SetPoint("TOPLEFT",     body, "TOPLEFT",     PAD, -topOff)
    card:SetPoint("TOPRIGHT",    body, "TOPRIGHT",    -PAD, -topOff)
    card:SetPoint("BOTTOMLEFT",  body, "BOTTOMLEFT",  PAD, PAD)
    card:SetPoint("BOTTOMRIGHT", body, "BOTTOMRIGHT", -PAD, PAD)
    Back(card, UI.panel, UI.border, 1, 1)

    local title = NewFS(card, "OVERLAY", FONT.heading, UI.text)
    title:SetPoint("TOPLEFT", card, "TOPLEFT", CARD_INSET, -CARD_TITLE_Y)
    title:SetText("Entry Points")

    local rowY = CARD_CONTENT_Y
    local function EntryRow(idx, tag, desc)
        local y = rowY + (idx - 1) * 22
        local tagFS = NewFS(card, "OVERLAY", FONT.body, UI.accent)
        tagFS:SetPoint("TOPLEFT", card, "TOPLEFT", CARD_INSET, -y)
        tagFS:SetText(tag)
        local descFS = NewFS(card, "OVERLAY", FONT.small, UI.muted)
        descFS:SetPoint("TOPLEFT", card, "TOPLEFT", CARD_INSET + 200, -y)
        descFS:SetText(desc)
    end

    EntryRow(1, "/muiconsole",            "Command - opens the Console")
    EntryRow(2, "/muic",                  "Command - short alias")
    EntryRow(3, "Messenger Debug Tab",    "GUI - launches the Console")

    local footer = NewFS(card, "OVERLAY", FONT.small, UI.muted)
    footer:SetPoint("TOPLEFT", card, "TOPLEFT", CARD_INSET, -(rowY + 84))
    footer:SetText("Silent capture is always on. Capture continues even while this window is closed.")

    ui.entryCard = card
end

-- ============================================================
-- SECTION: Build + Refresh + Ticker
-- ============================================================
local function BuildSettings(body)
    state.body = body
    BuildStateCard(body)
    BuildMaintCard(body)
    BuildEntryCard(body)
end

local function RefreshSettings()
    RefreshStateCard()
end

local function TickerStep()
    if not state.body then return end
    if not state.body:IsShown() then return end
    RefreshStateCard()
end

local function EnsureTicker()
    if state.ticker then return end
    if C_Timer and C_Timer.NewTicker then
        state.ticker = C_Timer.NewTicker(REFRESH_INTERVAL, TickerStep)
    end
end

SHELL.RegisterTabContent("settings", BuildSettings, function()
    EnsureTicker()
    RefreshSettings()
end)

-- End of Console_UI_Settings.lua
