-- VDS_Rows_Dye
-- ============================================================================
-- Same lazy-build + cross-kind hide pattern as Rows_Herb (donor:
-- VDS_Components.lua:741-916). Chrome built lazily per frame (_vdsDyeBuilt);
-- binder explicitly hides/shows each kind's chrome -- no reliance on Skinner
-- for visibility.

VDS = VDS or {}

local FW                 = VDS.Constants.FLOATING_WIDGET
local C                  = VDS.Constants.COLOR_CODE
local DYE_ROW_SWATCH_TEX = "Interface\\AddOns\\VamoosesDyeStudio\\textures\\vds_swatch_tex"
local WHITE              = "Interface\\Buttons\\WHITE8x8"
local C_GOLD             = C.warn
local C_GREEN            = C.success
local C_DIM              = C.dim

local attachHover  -- fwd-decl; body after lazyBuildDyeRowChrome

local function lazyBuildHeaderChrome(row)
    if row._vdsDyeHeaderBuilt then return end
    row._vdsDyeHeaderBuilt = true

    -- Full-row subtle dark background.
    local bg = row:CreateTexture(nil, "BACKGROUND", nil, 2)
    bg:SetAllPoints()
    bg:SetTexture(WHITE)
    VDS.Theme:Register(bg, "RowHeaderBg")
    bg:Hide()
    row._headerBg = bg

    -- Label (left, scheme-tinted gold via Skinner)
    local label = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    label:SetPoint("LEFT",  row, "LEFT",  8, 0)
    label:SetJustifyH("LEFT")
    VDS.Theme:Register(label, "TextRowHeader")
    label:Hide()
    row._headerLabel = label

    -- Count (right, dim grey via Skinner: "7 dyes")
    local count = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    count:SetPoint("RIGHT", row, "RIGHT", -8, 0)
    count:SetJustifyH("RIGHT")
    VDS.Theme:Register(count, "TextRowMeta")
    count:Hide()
    row._headerCount = count

    -- Header bg routes through Skinner so scheme switches repaint.
    if row._headerBg then VDS.Theme:Register(row._headerBg, "RowBg") end
end

local function lazyBuildDyeRowChrome(row)
    if row._vdsDyeBuilt then return end
    row._vdsDyeBuilt = true

    local swatch = row:CreateTexture(nil, "ARTWORK", nil, 0)
    swatch:SetAllPoints()
    swatch:SetTexture(DYE_ROW_SWATCH_TEX)
    row._swatch = swatch

    local gloss = row:CreateTexture(nil, "ARTWORK", nil, 1)
    gloss:SetAllPoints()
    gloss:SetTexture(WHITE)
    gloss:SetBlendMode("ADD")
    gloss:SetGradient("VERTICAL",
        _G.CreateColor(1, 1, 1, 0), _G.CreateColor(1, 1, 1, 0.15))
    row._gloss = gloss

    -- Gold overlay (Palette.accent.gold) reads over any dye swatch without competing.
    local selectedBg = row:CreateTexture(nil, "BACKGROUND", nil, 1)
    selectedBg:SetAllPoints()
    selectedBg:SetTexture(WHITE)
    VDS.Theme:Register(selectedBg, "RowSelectedBg")
    selectedBg:Hide()
    row._selectedBg = selectedBg

    local hl = row:CreateTexture(nil, "HIGHLIGHT")
    hl:SetAllPoints()
    hl:SetTexture(WHITE)
    VDS.Theme:Register(hl, "RowHoverHl")
    row._hl = hl

    -- 3px left bar (quest log / spellbook convention); Palette.accent.gold.
    local selAccent = row:CreateTexture(nil, "OVERLAY")
    selAccent:SetPoint("TOPLEFT",    0, 0)
    selAccent:SetPoint("BOTTOMLEFT", 0, 0)
    selAccent:SetWidth(3)
    selAccent:SetTexture(WHITE)
    VDS.Theme:Register(selAccent, "RowSelAccent")
    selAccent:Hide()
    row._selAccent = selAccent

    local nameText = row:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    nameText:SetJustifyH("LEFT")
    nameText:SetWordWrap(false)
    row._nameText = nameText

    -- 56px accommodates "x999 x999".
    local countText = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    countText:SetJustifyH("RIGHT")
    countText:SetPoint("RIGHT", -4, 0)
    countText:SetWidth(56)
    row._countText = countText

    -- AH price (crafting tab only, donor Image #10). Hidden unless data.price set.
    local priceText = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    priceText:SetJustifyH("RIGHT")
    priceText:SetPoint("RIGHT", countText, "LEFT", -6, 0)
    priceText:SetWidth(50)
    priceText:Hide()
    row._priceText = priceText

    function row._applyDyeLayout(self)
        local w = self:GetWidth()
        if w < 1 then w = FW.DYE_PANEL_WIDTH end
        local textW = math.floor(w * (1 - FW.DYE_SWATCH_RATIO))
        -- Name right edge clears countText (56) + margins (4+4) = 64px from right.
        self._nameText:ClearAllPoints()
        self._nameText:SetPoint("RIGHT", self, "RIGHT", -64, 0)
        self._nameText:SetWidth(math.max(textW - 64, 1))
        self._nameText:SetJustifyH("LEFT")
    end

    row:RegisterForClicks("AnyUp")
    row:SetScript("OnClick", function(self, button)
        if not VDS.Controller_Browse then return end
        if self._lsRowKind == "herb" then
            VDS.Controller_Browse:OnHerbRowClick(self, button)
        else
            VDS.Controller_Browse:OnDyeRowClick(self, button)
        end
    end)

    attachHover(row)  -- shared with Rows_Herb; see VDS.Rows_Dye_attachHover
end

-- Shared tooltip attach (dye + herb). Selection is CLICK-only: hovering no
-- longer bumps the selected dye/herb. The old hover-preview made the selection
-- chase the cursor, so moving down toward the detail panel / harmony band stole
-- the selection from the row you wanted. Click selects (OnDyeRowClick); hover
-- just renders the tooltip.
local function _attachHover_inner(target)
    VDS.TooltipEngine:Attach(target, VDS.TooltipRecipes.DyeOrHerbRow)
end

attachHover = _attachHover_inner          -- fwd-decl assignment
VDS.Rows_Dye_attachHover = _attachHover_inner  -- shared with Rows_Herb

local function bindDyeRow(row, data)
    lazyBuildDyeRowChrome(row)
    lazyBuildHeaderChrome(row)

    -- (cross-pool hide block removed: dye and herb tabs now use separate
    -- scrollBoxes, so this Button can only ever be a dyeRow.)

    if data.kind == "header" then
        row._lsRowKind = "header"
        row._dyeID     = nil
        row._herbID    = nil

        -- Hide all dye-row chrome; show header bg + label + count.
        row._swatch:Hide(); row._gloss:Hide(); row._nameText:Hide(); row._countText:Hide()
        row._selectedBg:Hide(); row._selAccent:Hide()
        if row._priceText then row._priceText:Hide() end  -- leaked when prior bind was a herbs-category dye row
        row._headerBg:Show()
        row._headerLabel:SetText(data.label or "")
        row._headerLabel:Show()
        row._headerCount:SetText(data.count and (tostring(data.count) .. " dyes") or "")
        row._headerCount:Show()
        return
    end

    row._lsRowKind = "dye"
    row._dyeID     = data.dyeID
    row._herbID    = nil

    -- Hide header chrome if previously bound as header.
    row._headerBg:Hide()
    row._headerLabel:Hide()
    row._headerCount:Hide()

    row:SetHeight(FW.DYE_ROW_HEIGHT)
    row._applyDyeLayout(row)

    -- Swatch every bind -- absence causes transparent rows.
    local c = data.dyeColor
    if c then
        row._swatch:SetVertexColor(c.r, c.g, c.b, 1)
    else
        row._swatch:SetVertexColor(0.3, 0.3, 0.3, 1)
    end
    row._swatch:Show()
    row._gloss:Show()
    row._nameText:Show()
    row._countText:Show()

    row._nameText:SetText(data.name or ("Dye " .. tostring(data.dyeID or "?")))
    if not row._nameText._lsRegistered then
        VDS.Theme:Register(row._nameText, "TextRowName")
        row._nameText._lsRegistered = true
    else
        VDS.Theme:Apply(row._nameText, "TextRowName")
    end

    -- Cart-count column removed; Stock tab is the sole cart workflow.
    local ownedN = data.ownedCount or 0  -- exception(nullable): first paint pushes empty data
    if ownedN > 0 then
        row._countText:SetText(C_GREEN .. "x" .. ownedN .. "|r")
    else
        row._countText:SetText(C_DIM .. "--|r")
    end

    if data.price then
        local pretty = VDS.StaticData.FormatGold(data.price)
        if pretty then
            row._priceText:SetText(C_GOLD .. pretty .. "|r")
            row._priceText:Show()
        else
            row._priceText:Hide()
        end
    else
        row._priceText:Hide()
    end

    local ui = VDS.Store:GetState().session.ui  -- top-level only: selection paint
    local selected = ui.selectedDyeID == data.dyeID
    if selected then
        row._selectedBg:Show()
        row._selAccent:Show()
    else
        row._selectedBg:Hide()
        row._selAccent:Hide()
    end
end

local function resetDyeRow(row)
    row._dyeID = nil
    if row._nameText  then row._nameText:SetText("")  end
    if row._countText then row._countText:SetText("") end
end

VDS.RowRegistry:Register("dyeRow", {
    init  = bindDyeRow,
    reset = resetDyeRow,
})
