-- VDS_Selectors_CanvasScope
-- ============================================================================
-- Canvas-only "dye source" scope. User picks a curated theme or a custom
-- palette; the dye browser narrows to those dyes and Random picks from the
-- same set. Scope is what-if only -- no ownership filter applies in canvas.
--
-- State lives at session.ui.byView.canvas.scope (per ADR-008):
--   nil                                = "All Dyes" (default)
--   { kind = "theme",  name = "..." }  = themed/class palette by name
--   { kind = "custom", name = "..." }  = account.customThemes entry by name
--
-- Scope is sticky across view switches; the reset button next to the dropdown
-- dispatches CANVAS_SET_SCOPE { value = nil } to clear.

local Selectors = VDS.Selectors

-- Raw scope value. Selectors that just need to know "is scope set" use this.
Selectors:Register("canvas.scope.current", {
    reads = { "session.ui.byView.canvas.scope" },
    fn    = function(state) return state.session.ui.byView.canvas.scope end,
})

-- Boolean for reset-button visibility.
Selectors:Register("canvas.scope.hasScope", {
    reads = { "session.ui.byView.canvas.scope" },
    fn    = function(state) return state.session.ui.byView.canvas.scope ~= nil end,
})

-- Display label for the dropdown button. Selection text on the WowStyle1Dropdown
-- is auto-rendered from the selected MenuUtil radio; this is the fallback shown
-- when nothing is selected.
Selectors:Register("canvas.scope.label", {
    reads = { "session.ui.byView.canvas.scope" },
    fn    = function(state)
        local scope = state.session.ui.byView.canvas.scope
        return scope and scope.name or "All Dyes"  -- exception(nullable): no scope set = All Dyes
    end,
})

-- Random-button text binding. "Random" when unset, "Random: <name>" when scoped.
Selectors:Register("canvas.random.buttonText", {
    reads = { "session.ui.byView.canvas.scope" },
    fn    = function(state)
        local scope = state.session.ui.byView.canvas.scope
        return scope and ("Random: " .. scope.name) or "Random"
    end,
})

-- Resolves the current scope to a SET-shaped dye lookup: { [dyeID] = true, ... }.
-- Returns nil when scope is unset ("All Dyes" = no filter).
-- The set shape lets passes() do O(1) membership tests; iterating an array of
-- ~10-20 dyes per row would be 10x slower at scroll time.
Selectors:Register("canvas.scope.dyeIDs", {
    reads = {
        "session.ui.byView.canvas.scope",
        "session.dyes.catalog",
        "account.customThemes",
    },
    fn = function(state)
        local scope = state.session.ui.byView.canvas.scope
        if not scope then return nil end

        local set = {}
        if scope.kind == "custom" then
            for _, pal in ipairs(state.account.customThemes) do
                if pal.name == scope.name then
                    for _, dyeID in ipairs(pal.dyes or {}) do set[dyeID] = true end
                    break
                end
            end
        elseif scope.kind == "theme" then
            local pal = VDS.StaticData.GetPaletteByName(scope.name)
            if pal then
                -- itemIDToDye is initialized to {} in NewSession's catalog (engine guarantee).
                -- pal.items is shipped palette data; missing items = malformed palette, let it crash.
                local itemIDToDye = state.session.dyes.catalog.itemIDToDye
                for _, itemID in ipairs(pal.items) do
                    local dyeID = itemIDToDye[itemID]
                    if dyeID then set[dyeID] = true end
                end
            end
        end
        return set
    end,
})

-- Menu generator data: arrays of { name, kind } the dropdown's generator iterates.
-- Themed first, then class palettes (matches Theme-tab ordering).
Selectors:Register("canvas.scope.themesList", {
    reads = {},  -- StaticData is shipped data, not reactive state (ADR-018)
    fn    = function()
        local list = {}
        for _, p in ipairs(VDS.StaticData.GetThemedPalettes()) do
            list[#list + 1] = { name = p.name }
        end
        for _, p in ipairs(VDS.StaticData.GetClassPalettes()) do
            list[#list + 1] = { name = p.name }
        end
        return list
    end,
})

Selectors:Register("canvas.scope.customsList", {
    reads = { "account.customThemes" },
    fn    = function(state)
        local list = {}
        for _, pal in ipairs(state.account.customThemes) do
            list[#list + 1] = { name = pal.name }
        end
        return list
    end,
})
