For complicated entities with lots of animations I end up using what amounts to nested state machines (sort of a poor man's behavior tree), and each frame the entity script checks the status of those state machines and updates the animation if necessary.
On my player sprite, for example, I have a top level state machine for whether the player is running, idle, or in the air. There's another state machine just for airborne states: pushing off, ascending, at the apex, descending, landing. This way, if the player runs off an edge without jumping, for example, the player script logic can realize that and the animation can go from running to airborne_descending smoothly.
There are a lot of conditionals, though - I've got no silver bullets for making convoluted logic go away :(