-- VDS_Controller_Warehouse
-- ============================================================================
-- Mode toggle override + restock + per-group/per-dye bump + reset wiring.
-- BumpDye/BumpGroup/ResetDye are called from row factories (Rows_Warehouse).
-- :Wire(rootFrame) handles free-standing widgets (restock button + mode toggle
-- chip click-override).

VDS = VDS or {}
VDS.Controller_Warehouse = VDS.Controller_Warehouse or {}

local C = VDS.Controller_Warehouse
local A = VDS.Constants.ACTIONS

function C:BumpGroup(row, delta)
    local group = row._group
    if not group then return end
    local mult = _G.IsShiftKeyDown() and 10 or 1
    -- ADR-041: row._targetValue is ed-projected by the groupHead selector.
    VDS.Store:Dispatch({
        type    = A.STOCK_SET_GROUP_TARGET,
        payload = { group = group, value = row._targetValue + delta * mult },
    })
end

function C:BumpDye(row, delta)
    local dyeID, group = row._dyeID, row._group
    if not (dyeID and group) then return end
    local mult = _G.IsShiftKeyDown() and 10 or 1
    -- ADR-041: row._target = resolveTarget(override OR group default), stamped by
    -- the warehouseRow selector. Avoids re-computing the override-vs-default merge.
    VDS.Store:Dispatch({
        type    = A.STOCK_SET_DYE_TARGET,
        payload = { dyeID = dyeID, group = group, value = row._target + delta * mult },
    })
end

function C:ResetDye(row)
    if not row._dyeID then return end
    VDS.Store:Dispatch({
        type    = A.STOCK_RESET_DYE_OVERRIDE,
        payload = { dyeID = row._dyeID },
    })
end

function C:ToggleGroup(group)
    if not group then return end
    VDS.Store:Dispatch({
        type    = A.STOCK_TOGGLE_GROUP,
        payload = { group = group },
    })
end

-- Master +/- bumps every group target. Per-dye overrides preserved (reducer
-- only touches targetGroups). Shift = x10.
local function bumpAllGroups(delta)
    local mult = _G.IsShiftKeyDown() and 10 or 1
    VDS.Store:Dispatch({
        type    = A.STOCK_BUMP_ALL_GROUPS,
        payload = { delta = delta * mult },
    })
end

local function expandAll()
    VDS.Store:Dispatch({ type = A.STOCK_EXPAND_ALL_GROUPS })
end

local function collapseAll()
    VDS.Store:Dispatch({ type = A.STOCK_COLLAPSE_ALL_GROUPS })
end

-- Restock-and-send button OnClick. Pre-warms names from the active deficit
-- selector (cuts SendCart's "N skipped" count), then hands off to the bridge.
-- SendCart re-reads the same selectors and builds the AH list itself -- no
-- intermediate cart state, so every click ships the current deficit.
local function restockCart()
    local state = VDS.Store:GetState()  -- top-level only: button OnClick
    local mode  = state.account.warehouse.fillMode

    if mode == "buy" then
        for _, item in ipairs(VDS.Selectors:Call("stock.buy.cart", state, {})) do
            VDS.ItemNameResolver:Request(item.itemID)
        end
    else
        for _, h in ipairs(VDS.Selectors:Call("stock.herbs.list", state, {})) do
            VDS.ItemNameResolver:Request(h.itemID)
        end
    end

    -- boundary: AuctionatorBridge no-ops when Auctionator isn't loaded.
    -- Handles empty-deficit case with its own "nothing to buy" chat print.
    VDS.AuctionatorBridge:SendCart()
end

function C:Wire(rootFrame)
    if not (rootFrame and rootFrame.widgets) then return end  -- exception(false-positive): Wire-on-empty-rootFrame is a supported no-op (wire smoke contract)

    -- Restock button
    local restock = rootFrame.widgets["stock.restock"]
    if restock then restock:SetScript("OnClick", restockCart) end

    -- Master +/- inlined in the column header (bracketing "Target"). Bumps
    -- every group target at once; Shift-click x10. Per-dye overrides kept.
    local minusAll = rootFrame.widgets["stock.list.header.minusAll"]
    if minusAll then minusAll:SetScript("OnClick", function() bumpAllGroups(-1) end) end
    local plusAll = rootFrame.widgets["stock.list.header.plusAll"]
    if plusAll then plusAll:SetScript("OnClick", function() bumpAllGroups( 1) end) end

    -- Reset-all button. Group targets -> 1, per-dye overrides cleared.
    local resetAllBtn = rootFrame.widgets["stock.list.header.resetAll"]
    if resetAllBtn then
        resetAllBtn:SetScript("OnClick", function()
            VDS.Store:Dispatch({ type = A.STOCK_RESET_ALL_TARGETS })
        end)
    end

    -- Bulk collapse/expand buttons
    local collapseAllBtn = rootFrame.widgets["stock.collapseAllBtn"]
    if collapseAllBtn then collapseAllBtn:SetScript("OnClick", collapseAll) end
    local expandAllBtn = rootFrame.widgets["stock.expandAllBtn"]
    if expandAllBtn then expandAllBtn:SetScript("OnClick", expandAll) end

    -- Buy-gap checkbox (above the Send-to-AH button). Outer widget is a Frame;
    -- the actual CheckButton lives at ._check.
    local buyGapWidget = rootFrame.widgets["stock.buyGap.check"]
    local buyGapBtn    = buyGapWidget and buyGapWidget._check  -- exception(false-positive): Wire tolerates absent widgets (empty-root contract)
    if buyGapBtn then
        buyGapBtn:SetScript("OnClick", function(self)
            VDS.Store:Dispatch({
                type    = A.STOCK_SET_BUY_GAP,
                payload = { value = self:GetChecked() and true or false },
            })
        end)
    end

    -- Mode toggle: the tabBar chip OnClick reads chip.action from the chip
    -- data (set by stock.modeToggle.chips selector to STOCK_SET_FILL_MODE).
    -- No post-build override needed -- the chip data drives the dispatch.
    -- (dispatchTabBar rebuilds chip buttons on every binding tick; any
    -- SetScript override here would be clobbered on the next paint.)
end
