--[=[
	Removes all player data stores, and returns a promise that
	resolves when all pending saves are saved.
	@return Promise
]=]

function PlayerDataStoreManager:PromiseAllSaves()
	for player, _ in pairs(self._datastores) do
		self:_removePlayerDataStore(player)
	end
	return self._maid:GivePromise(PromiseUtils.all(self._pendingSaves:GetAll()))
end

function PlayerDataStoreManager:_createDataStore(player)
	assert(not self._datastores[player], "Bad player")

	local datastore = DataStore.new(self._robloxDataStore, self:_getKey(player))

	self._maid._savingConns[player] = datastore.Saving:Connect(function(promise)
		self._pendingSaves:Add(promise)
	end)

	self._datastores[player] = datastore

	return datastore
end

function PlayerDataStoreManager:_removePlayerDataStore(player)
	assert(typeof(player) == "Instance", "Bad player")
	assert(player:IsA("Player"), "Bad player")

	local datastore = self._datastores[player]
	if not datastore then
		return
	end

	self._removing[player] = true

	local removingPromises = {}
	for _, func in pairs(self._removingCallbacks) do
		local result = func(player)
		if Promise.isPromise(result) then
			table.insert(removingPromises, result)
		end
	end

	PromiseUtils.all(removingPromises)
		:Then(function()
			return datastore:Save()
		end)
		:Finally(function()
			datastore:Destroy()
			self._removing[player] = nil
		end)

	-- Prevent double removal or additional issues
	self._datastores[player] = nil
	self._maid._savingConns[player] = nil
end

function PlayerDataStoreManager:_getKey(player)
	return self._keyGenerator(player)
end

return PlayerDataStoreManager
