Using awk not only makes dealing with a variable number of columns easier, but will also be much faster:
awk -F, '{ for(i=NF; i>=2; --i) printf "%s ", $i; print $1 }' "$input" > output.csv
-F, tells awk to split the input into fields by commas
for(i=NF; i>= 2; --i) loops over all fields indices, counting down from NF (the number of input fields) to the 2nd field.
$i references field (column) whose (1-based) index is i.
printf "%s " is the (implicit) loop body (you may enclose it in { ... } for clarity), and it prints the field at hand with a trailing space, as in your question's code.
Note that printf, unlike print does not automatically append a newline by default.
Finally, after the loop, print $1 prints the first field, followed by a newline (\n) to complete the output line (\n is the default value for ORS, the output record separator).
If you need a pure Bash solution (much slower):
Arrays combined with read -a are the solution:
while IFS= read -r line; do # read input line by line
# Split line into fields and read into array.
IFS=, read -ra fields <<<"$line"
# Loop over fields from the back, down to the 2nd.
for (( i = ${#fields[@]} - 1; i >= 1; --i )); do
printf '%s ' "${fields[i]}"
done
# Print 1st field and complete line (append line).
printf '%s\n' "${fields[0]}"
done < "$input" > output.csv
Note:
A single output redirection, > output.csv, is applied to the entire loop (just like the input redirection, < "$input"), which is both simpler and more efficient than using >> output.csv inside the loop (in the latter case, you'd also have to truncate output.csv beforehand in order to ensure that no preexisting content is appended to).
bash arrays are 0-based, whereas awk-based arrays start at index 1.
>> output.csvoutside the while loop.