--[[
  A very basic library for basic interfacing with App Shelf app. Could be used by scripts without I/O access to offer users to install apps.
  Apps should either be on App Shelf or be properly signed in a certain way to ensure misuse.

  To use, include with `local appShelf = require('shared/utils/appshelf')` and then call `appShelf.offer({id = 'SetupExchange'}, function (err, result) … end)`.
  For a custom app, pass a table instead: `appShelf.offer('SetupExchange', function (err, result) … end)`.

  To prevent spam, secondary calls with the same app ID will be ignored.
]]

local appShelf = {}

local listener

---Offers user to install a certain app. Parameter `reason` is optional. If specified, will be used after a colon in a sentense, so keep it lowercase. 
---@param data {id: string, reason: string?}|{id: string, name: string, downloadURL: string, reason: string?} @Installation parameters.
---@param callback fun(err: string?)? @Result callback.
function appShelf.offer(data, callback)
  if not data or not data.id then error('Data is required', 2) end
  local installKey = math.randomKey()
  if data.reason then
    data.reason = tostring(data.reason)
    if #data.reason > 200 then error('Reason string is too large', 2) end
  end
  if not listener then
    listener = {}
    ac.onSharedEvent('$SmallTweaks.AppShelf.Install.Result', function (data)
      if type(data) ~= 'table' or type(data.installKey) ~= 'number' then return end
      local cb = listener[data.installKey] 
      if cb then
        listener[data.installKey] = nil
        cb(data.err)
      end
    end)
  end
  listener[installKey] = callback
  ac.broadcastSharedEvent('$SmallTweaks.AppShelf.Install', {
    meta = data,
    installKey = installKey
  })
end

return appShelf