#05AB1E, 38 3737 32 31 bytes
25L.ržf12Qže₂‹*iε…[ ]…[@])yžežeD₂‹žf12QP'@ú€…[ÿ]Dg25Ÿ«¦.SÌè]5ô»r5ô»
Try it online-5 bytes thanks to @Grimmy.
Try it online or try it online with own specified month / daytry it online with own specified month / day.
25L že # Push a list in the rangecurrent [1,25]day
.r D # Duplicate it
# Randomly shuffle₂‹ it
žf # Check if it's smaller than 26
žf # Push the current month
12Q # Check if it's equal to 12 (thus December)
že P # Take the #product Pushof the current day
and both checks,
₂‹ # which result in either the day, #or Check0 if it'seither smallercheck thanwas 26falsey
'@ *i '# Push character "@"
ú # And if both are truthy:
# Pad it with the earlier number amount εof spaces
€ # Map each valueover ineach theof listthese tocharacters:
…[@] …[ÿ] # Push string "[@]"
…[ ] "[ÿ]", where the #`ÿ` is automatically Pushfilled stringwith "[the ]"character
Dg ) # Wrap all three intoDuplicate athe list: [value,"[@]","[ ]"]
y # and pop Pushand thepush valueits `y`length
25Ÿ že # Create a Pushlist in the currentrange day[length, again25]
« .S # Compare the two values (-1 ifAnd y<day;merge 0it ifto y==day;the 1earlier ifcreated y>day)list
¦ Ì # Then Increaseremove itthe byfirst 2item (1either ifa y<day;"[ 2]", ifor y==day;the 3"[@]" if y>day)
the checks
è # Use it to (0-based) index into the list (with wraparound,
# so the 3 results in the firstwere itemfalsey)
] .r # Close theRandomly mapshuffle andthe if-statementlist
5ô # Split the list into sublists of size 5
» # Join each inner list by spaces, and these strings by newlines
# (after which the result is output implicitly)