local dnf = require("dnf")
assert(dnf.api_version == "dnf/v1", "requires dnf/v1")
assert(dnf.hooks.catalog()["commerce.shop_purchase"], "shop purchase Hook is unavailable")

local function id_set(value, name)
    local result = value or {}
    assert(type(result) == "table", name .. " must be a string-key set")
    for id, enabled in pairs(result) do
        assert(type(id) == "string" and string.match(id, "^%d+$")
            and type(enabled) == "boolean", name .. " requires decimal string keys and boolean values")
    end
    return result
end

local blocked_items = id_set(dnf.config.blocked_item_ids, "blocked_item_ids")
local blocked_commodities = id_set(dnf.config.blocked_commodity_ids, "blocked_commodity_ids")

dnf.hooks.before("commerce.shop_purchase", function(ctx, plan, event)
    -- Bare request snapshot. Cera rows carry commodity_id, not the delivered product list.
    for _, item in ipairs(event.items) do
        if event.source == "cera" then
            local key = string.format("%.0f", item.commodity_id)
            if blocked_commodities[key] == true then return false end
        else
            local key = string.format("%.0f", item.item_id)
            if blocked_items[key] == true then return false end
        end
    end
    return true
end)
