Fill a bowl with alphabet soup We seem to never get tired of alphabet-related challenges...



The recipe

Given


a string of letters S, and
two positive integers M, N,


produce an alphabet soup with the letters of S occupying random positions in a rectangular bowl of size M×N, framed by a non-alphabetic, non-space character to represent the rim of the bowl.

Positions not used by letters should be displayed as spaces. See the examples below.

Aditional rules


The size M×N refers to the interior of the bowl. The size including the rim is M+2×N+2.
Each character from S should appear once in the bowl, in a different position; that is, one character cannot overwrite another.
S may contain duplicates. For instance, if S is the string 'abcc', the soup must contain one a, one b, and two c (all in different positions).
The inputs will satisfy the restrictions M &gt;= 1, N &gt;= 1, 1 &lt;= length(S) &lt;= M*N.
The rim of the bowl can be any non-alphabetic, non-space character, consistent across program runs and input values.
Letter positions in the bowl are random, so the result may differ every time the program is run with the same inputs.
Given the input, every possible set of letter positions should have a non-zero probability. Since this cannot be checked from a few realizations of the program, please explain how your code fulfills this.
Leading or trailing whitespace around the rim is allowed.
S will contain are only uppercase letters. If wou wish, you can choose to take only lowercase letters.
Input and output are flexible as usual. For example, the output can be a string with newlines, a 2D character array, or a list of lines.
Programs or functions are allowed, in any programming language. Standard loopholes are forbidden.
The shortest code in bytes wins.


Examples

Inputs are shown as S, [M N], where M is number of rows and N is number of columns. The character # is used for the rim.

'O', [1 1]:

###
#O#
###

'HEY', [1 3]:

#####
#YHE#
#####


'HELLO', [4 11]:

#############
#  O        #
#         H #
#    LE     #
#   L       #
#############


'ADVNJSGHETILMVXERTYIOJKCVNCSF', [8 12]:

##############
#K  V  L   S #
# A   V  X H #
#T    M C    #
# I       O N#
#  YC        #
# G  I   R SE#
#   J      F #
#JT  D  V EN #
##############


'OOOOOOOOOOXXXXX', [13 31]:

#################################
#    X                          #
#                O              #
#                               #
#                  X            #
#                        O      #
#             X           O     #
#      O                        #
#         X                     #
#                        O      #
#       X                       #
#                    O          #
#  O      O      O              #
#                             O #
#################################


'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ', [11 41]

###########################################
#                                       JU#
#     Q         C M    G     R T U Y  H   #
#  KI          E   H    M   YO            #
#      V BW        I    JC                #
#     SV           D     P   B          U #
#           A     F    RF   J  KP E       #
#            E   N      TH        Z       #
#    N  BM  O     Q   I        AS N  WX   #
#   S     O  K       G L       P       Q  #
#Z     L T         R   L       A      F DD#
#      V   Y           WX   C       G XZ  #
###########################################
05AB1E, 20 18 16 15 14 bytes
*j.rS²ô2Føε8.ø

Takes three inputs in the order: height, width, string. Output as a 2D list of characters.
Uses 8 as border, but could be any digit.
-1 byte thanks to @Grimy.
Try it online or verify all test cases. (TIO contains }}J» in the footer to pretty-print the result; feel free to remove it to see the actual output 2D list of characters instead.)
Explanation:

*               # Multiply the (implicit) width and height inputs
 j              # Pad the (implicit) input-string with up to that amount of leading spaces,
                # so the total string-length is equal to that value
  .r            # Shuffle the characters in the string
    S           # Convert the string to a list of characters
                # (edge-case for the zip below with strings of size 1 with 1x1 dimensions)
     ²          # Push the width input again
      ô         # Split the list of characters into parts of that size
       2F       # Loop 2 times:
         ø      #  Zip/transpose the 2D list; swapping rows/columns
          ε     #  Inner map over each line:
           8.ø  #   And surround this line-list with a leading/trailing &quot;8&quot;
                # (after the loop, the result is output implicitly)