The callback solutions via the Unity's animation system is kinda tricky and as you said expansive to maintain. I found out to discard that solution for my concerns.
The global monitor solution requires a bit of effort but should give some handlable ed effective solution to the problem. But it wraps up the concept of Coroutine. A Coroutine can handle your WaitForAnimation step on its own.
I use Coroutines. When the anymation starts, you can Sstart a Coroutine which calls a function that do things. You can code roughly every kind of situation.
I apologize since I'm not on my dev post now so I'll write some pseudocode to give an idea. I could update later if you think this is of eny help.
private IEnumerator HandleAction(GameObject entity){
Animator anim = entity.GetComponent<Animator>();
float duration = anim.GetCurrentState().GetClip().duration;//not sure of this syntax. will update later
while(duration > 0){
//do stuff or wait
duration -= Time.deltaTime;
yield return null;
}
//code to execute when animation ends
}