-- HDG_HT_W_CloseCards.lua  (EXISTING)
-- "Closest to Complete" — three mini-cards (full width) showing the
-- subcategories you're closest to finishing. Custom layout (not MiniCardStrip)
-- to match v2.37 styling: yellow titles with " > " separator, smooth slim
-- green StatusBar, and "X / Y  -  N to go (P%)" stat format.

local _, privateDB = ...
privateDB.HDG_HT = privateDB.HDG_HT or {}
privateDB.HDG_HT.Widgets = privateDB.HDG_HT.Widgets or {}
local W = { id = "closeCards", title = "Closest to Complete" }
privateDB.HDG_HT.Widgets.CloseCards = W

local CARD_COUNT = 3
local CARD_GAP   = 6

-- /run HDG_DebugCloseCard("Windows")  →  prints every item in the matching
-- subcategory from HDG_AllDecorDB, with collected status + whether the
-- live catalog has it (to spot Aggregator-vs-Preview data-source mismatches).
function _G.HDG_DebugCloseCard(searchSubName)
    if not (_G.HDG_AllDecorDB and _G.HDG_Data and _G.HDG_Data.GetCatalogByItem) then
        print("HDG: data not loaded"); return
    end
    local CHC = _G.C_HousingCatalog
    local seenSub = {}    -- subcatID → name
    local rows = {}
    for itemID, entry in pairs(_G.HDG_AllDecorDB) do
        local row = HDG_Data.GetCatalogByItem(itemID)
        if row and row.subcategoryID then
            local name = seenSub[row.subcategoryID]
            if not name then
                local info = CHC and CHC.GetCatalogSubcategoryInfo
                          and CHC.GetCatalogSubcategoryInfo(row.subcategoryID)
                name = info and info.name or "?"
                seenSub[row.subcategoryID] = name
            end
            if not searchSubName or name:lower():find(searchSubName:lower(), 1, true) then
                local collected = HDG_Data.IsItemCollected and HDG_Data.IsItemCollected(itemID) or false
                rows[#rows + 1] = {
                    itemID = itemID, subID = row.subcategoryID, subName = name,
                    name = row.name or entry.name or "?",
                    collected = collected,
                    ver = entry.ver, hasCatalogRow = (row ~= nil),
                }
            end
        end
    end
    table.sort(rows, function(a, b)
        if a.subName ~= b.subName then return a.subName < b.subName end
        return (a.name or "") < (b.name or "")
    end)
    print("|cFFfcd34d[HDG CloseCard debug]|r " .. #rows .. " row(s)" ..
        (searchSubName and (" matching '" .. searchSubName .. "'") or ""))
    for _, r in ipairs(rows) do
        print(string.format("  [%s] %d  %s  (id=%d ver=%s)  %s",
            r.collected and "x" or " ",
            r.itemID, r.name, r.subID, tostring(r.ver),
            "[" .. r.subName .. "]"))
    end
end

function W.Create(parent, dims)
    local self = { miniFrames = {}, latestData = nil }
    local Theme   = privateDB.HDG_HT.Theme
    local scheme  = Theme.GetCurrentScheme()
    local applyFont = Theme.ApplyFont
    local success = scheme.success or scheme.accent

    -- Vertical accent bar + inline section header (matches v2.37)
    self.accent = parent:CreateTexture(nil, "ARTWORK")
    self.accent:SetTexture("Interface\\Buttons\\WHITE8x8")
    self.accent:SetSize(2, 14)
    self.accent:SetPoint("TOPLEFT", parent, "TOPLEFT", 2, -3)
    self.accent:SetVertexColor(scheme.accent.r, scheme.accent.g, scheme.accent.b, 0.8)

    self.header = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    self.header:SetPoint("LEFT", self.accent, "RIGHT", 6, 0)
    self.header:SetTextColor(scheme.accent.r, scheme.accent.g, scheme.accent.b)
    self.header:SetText("Closest to complete")
    applyFont(self.header, scheme, "header")

    -- Mini cards live in a frame below the header.
    self.frame = CreateFrame("Frame", nil, parent)
    self.frame:SetPoint("TOPLEFT", parent, "TOPLEFT", 2, -22)
    self.frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", 0, 0)

    local function ensureMini(i)
        if self.miniFrames[i] then return self.miniFrames[i] end

        -- Button so we can wire OnClick → switch to Preview tab + filter
        local mini = CreateFrame("Button", nil, self.frame, "BackdropTemplate")
        mini:SetBackdrop({
            bgFile   = "Interface\\Buttons\\WHITE8x8",
            edgeFile = "Interface\\Buttons\\WHITE8x8",
            edgeSize = 1,
        })
        mini:SetBackdropColor(scheme.panel.r, scheme.panel.g, scheme.panel.b, 0.6)
        mini:SetBackdropBorderColor(scheme.border.r, scheme.border.g, scheme.border.b, 0.3)
        mini:RegisterForClicks("LeftButtonUp")
        -- Hover: brighten border to accent. Click handler bound in Update().
        mini:SetScript("OnEnter", function(slf)
            slf:SetBackdropBorderColor(scheme.accent.r, scheme.accent.g, scheme.accent.b, 1)
        end)
        mini:SetScript("OnLeave", function(slf)
            slf:SetBackdropBorderColor(scheme.border.r, scheme.border.g, scheme.border.b, 0.3)
        end)

        -- Title (top-left, accent)
        mini.title = mini:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        mini.title:SetPoint("TOPLEFT",  mini, "TOPLEFT",  6, -6)
        mini.title:SetPoint("TOPRIGHT", mini, "TOPRIGHT", -6, -6)
        mini.title:SetJustifyH("LEFT")
        mini.title:SetTextColor(scheme.accent.r, scheme.accent.g, scheme.accent.b)
        mini.title:SetWordWrap(false)
        applyFont(mini.title, scheme, "small")

        -- Smooth slim StatusBar (success-tinted fill)
        mini.bar = CreateFrame("StatusBar", nil, mini)
        mini.bar:SetHeight((dims and dims.barHeight) or 6)
        mini.bar:SetPoint("LEFT",  mini, "LEFT",  6, 0)
        mini.bar:SetPoint("RIGHT", mini, "RIGHT", -6, 0)
        mini.bar:SetPoint("CENTER", mini, "CENTER", 0, 0)
        mini.bar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
        mini.bar:SetStatusBarColor(success.r, success.g, success.b, 1)
        mini.barBg = mini.bar:CreateTexture(nil, "BACKGROUND")
        mini.barBg:SetAllPoints()
        mini.barBg:SetTexture("Interface\\Buttons\\WHITE8x8")
        mini.barBg:SetVertexColor(scheme.panel.r, scheme.panel.g, scheme.panel.b, 0.85)

        -- Stat line (bottom-left)
        mini.stat = mini:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        mini.stat:SetPoint("BOTTOMLEFT",  mini, "BOTTOMLEFT",  6, 6)
        mini.stat:SetPoint("BOTTOMRIGHT", mini, "BOTTOMRIGHT", -6, 6)
        mini.stat:SetJustifyH("LEFT")
        mini.stat:SetTextColor(scheme.text_dim.r, scheme.text_dim.g, scheme.text_dim.b)
        applyFont(mini.stat, scheme, "small")

        mini:Hide()
        self.miniFrames[i] = mini
        return mini
    end

    function self:Update(close)
        for i = 1, CARD_COUNT do
            local g = close[i]
            local mini = ensureMini(i)
            if g then
                local label = g.parentName and g.parentName ~= ""
                    and (g.parentName .. " > " .. (g.name or "?"))
                    or  (g.name or "?")
                mini.title:SetText(label)
                local pct = g.pct or 0
                mini.bar:SetMinMaxValues(0, 1)
                mini.bar:SetValue(pct)
                mini.stat:SetText(string.format(
                    "%d / %d  -  %d to go (%d%%)",
                    g.collected or 0, g.total or 0, g.gap or 0,
                    math.floor(pct * 100 + 0.5)))

                -- Click → switch to Preview tab + filter to this subcategory
                -- (uncollected only). Captures parentName/name from this g.
                local parentName, subName  = g.parentName, g.name
                local subID, catID         = g.subcategoryID, g.categoryID
                mini:SetScript("OnClick", function()
                    local HDG = _G.HousingDecorGuide
                    if HDG and HDG.Store and HDG.Store.Dispatch then
                        HDG.Store:Dispatch("SET_ACTIVE_TAB", { tab = "preview" })
                    end
                    if _G.HDG_UI and _G.HDG_UI.UpdateTabs then
                        _G.HDG_UI.UpdateTabs()
                    end
                    local prev = _G.HDG_DecorPreview
                    if prev and prev.SetSubcategoryFilter then
                        -- (categoryID, subcategoryID) — composite is needed
                        -- because subcategories aren't unique across categories.
                        prev:SetSubcategoryFilter(subID, subName, parentName, true, catID)
                    end
                end)

                mini:Show()
            else
                mini:SetScript("OnClick", nil)
                mini:Hide()
            end
        end
    end

    function self:Refresh(snap)
        local close = (snap and snap.closestToComplete) or {}
        self.latestData = close
        self:Update(close)
    end

    function self:Resize(w, h)
        local n = CARD_COUNT
        local innerH = math.max(20, (h or 0) - 22)  -- minus header + gap
        local cardW  = math.max(80, math.floor((w - CARD_GAP * (n - 1)) / n))
        for i = 1, n do
            local mini = ensureMini(i)
            mini:SetSize(cardW, innerH)
            mini:ClearAllPoints()
            mini:SetPoint("TOPLEFT", self.frame, "TOPLEFT", (i - 1) * (cardW + CARD_GAP), 0)
        end
        if self.latestData then self:Update(self.latestData) end
    end

    return self
end

return W
