-- HDG_HT_W_Favorites.lua
-- Scrollable list of favorited decor items. Mouse-wheel only (no scroll bar).
-- Source: HDG.Favorites.GetAll(). Each row [icon] item-name.
-- Left-click → Preview tab + Favorites filter. Right-click → unfavorite.

local _, privateDB = ...
privateDB.HDG_HT = privateDB.HDG_HT or {}
privateDB.HDG_HT.Widgets = privateDB.HDG_HT.Widgets or {}
local W = { id = "favorites", title = "Favorites" }
privateDB.HDG_HT.Widgets.Favorites = W

local ROW_HEIGHT = 22
local ICON_SIZE  = 18

local function GetItemName(itemID)
    if not itemID then return "?" end
    if _G.HDG_Data and _G.HDG_Data.GetLocalizedName then
        local n = _G.HDG_Data.GetLocalizedName(itemID)
        if n then return n end
    end
    local name = C_Item and C_Item.GetItemNameByID and C_Item.GetItemNameByID(itemID)
    return name or ("Item " .. itemID)
end

local function GetItemIcon(itemID)
    if not itemID then return nil end
    if _G.HDG_AllDecorDB and _G.HDG_AllDecorDB[itemID] and _G.HDG_AllDecorDB[itemID].iconTexture then
        return _G.HDG_AllDecorDB[itemID].iconTexture
    end
    return C_Item and C_Item.GetItemIconByID and C_Item.GetItemIconByID(itemID)
end

local function GotoPreviewFavorites()
    if _G.HDG_DecorPreview then
        _G.HDG_DecorPreview.favoritesOnly  = true
        _G.HDG_DecorPreview.showAllDecor   = true
        _G.HDG_DecorPreview.onlyXPEligible = false
    end
    if _G.HDG_UI and _G.HDG_UI.SwitchTab then
        _G.HDG_UI.SwitchTab("preview")
    end
    if _G.HDG_DecorPreview and _G.HDG_DecorPreview.RefreshList then
        _G.HDG_DecorPreview:RefreshList()
        if _G.HDG_DecorPreview.RefreshTagFilters then
            _G.HDG_DecorPreview:RefreshTagFilters()
        end
    end
end

function W.Create(parent, dims)
    local self = { rows = {}, items = {} }
    local HDG = _G.HousingDecorGuide

    local rowHeight = (dims and dims.rowHeight) or ROW_HEIGHT
    local iconSize  = (dims and dims.iconSize)  or ICON_SIZE

    local scroll = CreateFrame("ScrollFrame", nil, parent)
    scroll:SetAllPoints(parent)
    scroll:EnableMouseWheel(true)
    self.scroll = scroll

    local content = CreateFrame("Frame", nil, scroll)
    content:SetSize(math.max(1, parent:GetWidth() or 1), 1)
    scroll:SetScrollChild(content)
    self.content = content

    -- ScrollChild width must track the ScrollFrame's width so rows anchored
    -- TOPLEFT/TOPRIGHT to content render at the visible width. Without this
    -- the child is 1px wide and rows render at near-zero width (icons show,
    -- text gets clipped to nothing).
    scroll:SetScript("OnSizeChanged", function(_, w, _) content:SetWidth(math.max(1, w)) end)

    scroll:SetScript("OnMouseWheel", function(_, delta)
        local cur = scroll:GetVerticalScroll()
        local maxS = math.max(0, content:GetHeight() - scroll:GetHeight())
        local step = rowHeight * 2
        local newS = math.max(0, math.min(maxS, cur - delta * step))
        scroll:SetVerticalScroll(newS)
    end)

    local emptyText = content:CreateFontString(nil, "OVERLAY", "GameFontDisableSmall")
    emptyText:SetPoint("TOPLEFT", content, "TOPLEFT", 4, -4)
    emptyText:SetText("No favorites yet. Right-click items in Preview to favorite.")
    emptyText:Hide()
    self.emptyText = emptyText

    local function ensureRow(i)
        if self.rows[i] then return self.rows[i] end
        local row = CreateFrame("Button", nil, content)
        row:SetHeight(rowHeight)
        row:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -((i - 1) * rowHeight))
        row:SetPoint("TOPRIGHT", content, "TOPRIGHT", 0, -((i - 1) * rowHeight))
        row:RegisterForClicks("LeftButtonUp", "RightButtonUp")

        row.bg = row:CreateTexture(nil, "BACKGROUND")
        row.bg:SetAllPoints()
        row.bg:SetColorTexture(0, 0, 0, 0)

        row.star = row:CreateTexture(nil, "OVERLAY", nil, 7)
        row.star:SetAtlas("auctionhouse-icon-favorite")
        row.star:SetSize(12, 12)
        row.star:SetPoint("LEFT", row, "LEFT", 1, 0)

        row.icon = row:CreateTexture(nil, "ARTWORK")
        row.icon:SetSize(iconSize, iconSize)
        row.icon:SetPoint("LEFT", row.star, "RIGHT", 2, 0)
        row.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)

        row.name = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        row.name:SetPoint("LEFT", row.icon, "RIGHT", 6, 0)
        row.name:SetPoint("RIGHT", row, "RIGHT", -2, 0)
        row.name:SetJustifyH("LEFT")
        row.name:SetWordWrap(false)

        row:SetScript("OnEnter", function(s)
            local sch = (HDG and HDG.Theme and HDG.Theme.GetCurrentScheme()) or {}
            if sch.button_hover then
                s.bg:SetColorTexture(sch.button_hover.r, sch.button_hover.g, sch.button_hover.b, 0.5)
            else
                s.bg:SetColorTexture(0.2, 0.2, 0.3, 0.5)
            end
            if s._itemID then
                GameTooltip:SetOwner(s, "ANCHOR_RIGHT")
                GameTooltip:SetItemByID(s._itemID)
                GameTooltip:Show()
            end
        end)
        row:SetScript("OnLeave", function(s)
            s.bg:SetColorTexture(0, 0, 0, 0)
            GameTooltip:Hide()
        end)
        row:SetScript("OnClick", function(s, button)
            if button == "RightButton" and s._itemID and HDG.Favorites then
                HDG.Favorites.Set(s._itemID, false)
                if HDG.Store and HDG.Store.QueueSave then HDG.Store:QueueSave() end
                return
            end
            GotoPreviewFavorites()
        end)
        row:Hide()
        self.rows[i] = row
        return row
    end

    function self:_render()
        local list = {}
        if HDG.Favorites and HDG.Favorites.GetAll then
            for itemID in pairs(HDG.Favorites.GetAll()) do
                list[#list + 1] = { itemID = itemID, name = GetItemName(itemID) }
            end
        end
        table.sort(list, function(a, b) return (a.name or "") < (b.name or "") end)
        self.items = list

        if #list == 0 then
            for _, r in ipairs(self.rows) do r:Hide() end
            content:SetHeight(rowHeight)
            self.emptyText:Show()
            return
        end
        self.emptyText:Hide()

        for i, it in ipairs(list) do
            local row = ensureRow(i)
            row._itemID = it.itemID
            row.icon:SetTexture(GetItemIcon(it.itemID) or "Interface\\Icons\\INV_Misc_QuestionMark")
            local sch = (HDG and HDG.Theme and HDG.Theme.GetCurrentScheme()) or {}
            local txtPrefix = (sch.text and string.format("|cFF%02x%02x%02x",
                math.floor(sch.text.r * 255 + 0.5),
                math.floor(sch.text.g * 255 + 0.5),
                math.floor(sch.text.b * 255 + 0.5))) or ""
            row.name:SetText(txtPrefix .. (it.name or "?") .. (txtPrefix ~= "" and "|r" or ""))
            row:Show()
        end
        for i = #list + 1, #self.rows do self.rows[i]:Hide() end
        content:SetHeight(math.max(rowHeight, #list * rowHeight))
    end

    function self:Refresh(_)
        self:_render()
    end

    function self:Resize(_, _)
        -- ScrollFrame uses parent SetAllPoints; re-anchor only if needed
    end

    -- Re-render when favorites change so the widget stays live without
    -- waiting for the next Aggregator rebuild.
    if HDG.Favorites and HDG.Favorites.Subscribe then
        HDG.Favorites.Subscribe(function()
            if scroll:IsVisible() then self:_render() end
        end)
    end

    return self
end

return W
