FlushStateToDisk() handles block storage directly. It applies BlockManager's prune locks, writes its pruned flag, checks its blocks directory space and runs the flush, index write and file deletion, while BlockManager reads the chainstate to pick files. A pruning API on block storage (#35627) would have to go through validation for all of it.
This moves the storage side into BlockManager, as described in the same issue. Validation decides which heights may be pruned and passes them as limits. BlockManager applies its prune locks, selects the files, flushes, writes the index and deletes the files, in the same order as before. There is no behavior change to my knowledge.
Based on #36735
Thanks to musaHaruna for his review on my fork, which led to grouping and checking the prune limits and to moving the prune bookkeeping into BlockManager.