-- HDG_HT_Resolver.lua
-- Merge LAYOUT_CONFIG defaults with user overrides (via LayoutStore).
-- Returns an ordered list of effective widget specs ready for Layout.Compute().

local _, privateDB = ...
privateDB.HDG_HT = privateDB.HDG_HT or {}
local Resolver = {}
privateDB.HDG_HT.Resolver = Resolver

local LayoutStore = privateDB.HDG_HT.LayoutStore

-- Internal: build default order from config widgets' `order` field.
local function defaultOrderIDs(layoutConfig)
    local list = {}
    for id, spec in pairs(layoutConfig.widgets) do
        list[#list + 1] = { id = id, order = spec.order or 999 }
    end
    table.sort(list, function(a, b)
        if a.order ~= b.order then return a.order < b.order end
        return a.id < b.id
    end)
    local ids = {}
    for i, e in ipairs(list) do ids[i] = e.id end
    return ids
end

function Resolver.Resolve(layoutConfig, savedOverrides)
    savedOverrides = savedOverrides or {}
    local enabled = savedOverrides.enabled or {}
    local order   = savedOverrides.order
    local widthOv = savedOverrides.width or {}
    local dimOv   = savedOverrides.layoutOverrides or {}

    local idList
    if order and #order > 0 then
        idList = {}
        local seen = {}
        for i, id in ipairs(order) do
            idList[i] = id
            seen[id] = true
        end
        -- Append any widgets that exist in layoutConfig but aren't in the
        -- saved order (i.e. widgets added since the user last edited their
        -- layout). Insert in natural order so they cluster sensibly.
        for _, id in ipairs(defaultOrderIDs(layoutConfig)) do
            if not seen[id] then idList[#idList + 1] = id end
        end
    else
        idList = defaultOrderIDs(layoutConfig)
    end

    local effective = {}
    for _, id in ipairs(idList) do
        local spec = layoutConfig.widgets[id]
        -- Three-state visibility:
        --   sv.enabled[id] = true   → explicitly on (overrides defaultEnabled = false)
        --   sv.enabled[id] = false  → explicitly off
        --   sv.enabled[id] = nil    → fall back to spec.defaultEnabled (default true)
        local sv = enabled[id]
        local visible
        if sv ~= nil then
            visible = sv ~= false
        else
            visible = spec and spec.defaultEnabled ~= false
        end
        if spec and visible then
            local widgetDimOv = dimOv[id] or {}
            local merged = {}
            -- Copy all spec fields, applying per-field overrides
            for k, v in pairs(spec) do
                if k ~= "order" then  -- order is layout metadata, not a tunable
                    merged[k] = widgetDimOv[k] ~= nil and widgetDimOv[k] or v
                end
            end
            merged.id = id
            -- Width override (separate table)
            if widthOv[id] then merged.width = widthOv[id] end
            effective[#effective + 1] = merged
        end
    end
    return effective
end
