--[[
	Add more owned asset ids to the players list. Keep order by checking for duplicates and only
	appending new ones to the list.
]]

return Rodux.createReducer({}, {
	[SetOwnedAssets.name] = function(state, action)
		local checkForDups = {}
		local currentAssets = state[action.assetTypeId] and state[action.assetTypeId] or {}

		for _, assetId in pairs(currentAssets) do
			checkForDups[assetId] = assetId
		end

		for _, assetId in pairs(action.assets) do
			if not checkForDups[assetId] then
				currentAssets[#currentAssets + 1] = assetId
			end
		end

		return Cryo.Dictionary.join(state, {[action.assetTypeId] = currentAssets})
	end,

	[GrantAsset.name] = function(state, action)
		if GetAENewNavigationEnabled() then
			local updatedCategories = {}

			local assetTypeId = tostring(action.assetTypeId)
			local newAssetId = tostring(action.assetId)

			local searchUuids = AssetTypeToSearchUuids[assetTypeId]
			if not searchUuids then
				return state
			end

			for _, searchUuid in ipairs(searchUuids) do
				local currentAssets = state[searchUuid] and state[searchUuid] or {}

				local updatedAssets = { newAssetId }
				local owned = false

				for i, assetId in ipairs(currentAssets) do
					if assetId == newAssetId then
						owned = true
						break
					else
						updatedAssets[i + 1] = assetId
					end
				end

				-- Do nothing if this asset is already owned.
				if not owned then
					updatedCategories[searchUuid] = updatedAssets
				end
			end

			if next(updatedCategories) then
				return Cryo.Dictionary.join(state, updatedCategories)
			end

			return state
		else
			local assetTypeId = tostring(action.assetTypeId)
			local newAssetId = tostring(action.assetId)
			local currentAssets = state[assetTypeId] and state[assetTypeId] or {}

			local updatedAssets = { newAssetId }

			for i, assetId in ipairs(currentAssets) do
				-- Do nothing if this asset is already owned.
				if assetId == newAssetId then
					return state
				else
					updatedAssets[i + 1] = assetId
				end
			end

			return Cryo.Dictionary.join(state, {[assetTypeId] = updatedAssets})
		end
	end,

	[RevokeAsset.name] = function(state, action)
		if GetAENewNavigationEnabled() then
			local updatedCategories = {}

			local assetTypeId = tostring(action.assetTypeId)
			local assetToRevokeId = tostring(action.assetId)

			local searchUuids = AssetTypeToSearchUuids[assetTypeId]
			if not searchUuids then
				return state
			end

			for _, searchUuid in ipairs(searchUuids) do
				local currentAssets = state[searchUuid] and state[searchUuid] or {}
				local updatedAssets = Cryo.List.removeValue(currentAssets, assetToRevokeId)

				-- Do nothing if this asset is not owned.
				if #currentAssets ~= #updatedAssets then
					updatedCategories[searchUuid] = updatedAssets
				end
			end

			if next(updatedCategories) then
				return Cryo.Dictionary.join(state, updatedCategories)
			end

			return state
		else
			local assetTypeId = tostring(action.assetTypeId)
			local assetToRevokeId = tostring(action.assetId)
			local currentAssets = state[assetTypeId] and state[assetTypeId] or {}

			local updatedAssets = Cryo.List.removeValue(currentAssets, assetToRevokeId)

			return Cryo.Dictionary.join(state, {[assetTypeId] = updatedAssets})
		end
	end,

	[GrantOutfit.name] = function(state, action)
		local actionOutfitId = tostring(action.outfitId)
		local currentOutfits = state[AvatarEditorConstants.CharacterKey] or {}

		local updatedOutfits = { actionOutfitId }

		for i, outfitId in ipairs(currentOutfits) do
			-- Do nothing if this costume is already owned.
			if outfitId == actionOutfitId then
				return state
			else
				updatedOutfits[i + 1] = outfitId
			end
		end

		return Cryo.Dictionary.join(state, {[AvatarEditorConstants.CharacterKey] = updatedOutfits})
	end,

	[RevokeOutfit.name] = function(state, action)
		local outfitId = tostring(action.outfitId)
		local currentOutfits = state[AvatarEditorConstants.CharacterKey] or {}
		local costumeList = Cryo.List.removeValue(currentOutfits, outfitId)

		return Cryo.Dictionary.join(state, {[AvatarEditorConstants.CharacterKey] = costumeList})
	end
})