I think that this topic is a classic example of people trying to answer the problem at different levels of abstraction. There is a famous clip of an interview with Richard Feynman where he cannot give a simple answer to "Why do magnets repel each other?" [1]. He can't give a simple answer because there is no simple answer -- any answer he could give could be followed by the question "And why does THAT happen?", requiring ever more complex answers that quickly descend into quantum mechanics that only top physicists can understand. He makes a meta-point that a person who asks such a question needs to specify the level of abstraction they expect, or barring that, the answerer needs to try to anticipate the correct level of abstraction that will satisfy and/or educate the questioner.

Now, some answers to why wings work are just plain wrong (like the original wrong answer -- the Bernoulli effect). However, when one person says "Wings work because they push air down, and the air pushes the wing up", and another person yells "No, that's all wrong! It's because of <insert-fancy-effect-here>", they can both be right. They are answering the question at different levels of abstraction. They also can be right in different cases -- the source of lift for wings, and the strength of different effects, can change with wing and flow conditions (at low speeds, one effect dominates, and at high speeds, another does. At supersonic speeds, a totally new effect takes over. and so on...)

Here's my attempt at an answer aimed at an appropriate level of abstraction, though of course it is doomed to failure:
- Air striking a wing is divided by the leading edge into two streams, one that flows over the top, and one that flows under the bottom.

- Assuming the wing has some positive angle-of-attack, the stream under the bottom of the wing will be deflected downward, and therefore pushes back against the bottom surface of the wing. This part is reasonably uncontroversial.

- The stream flowing over the top of the wing tends to follow the surface of the wing, even when the surface is curving down and away from the stream. Why this happens is subject to the multiple levels of abstraction problem that I mention above. If the curvature of the top surface is too severe, the flow cannot follow the surface, and it separates. This is "stall". Again, why this happens is complicated, and there are multiple effects and levels of abstraction at work, and I only understand the basic levels, so I won't try to go any further. The net result for a typical wing in typical flight conditions is that the flow over the top surface is also deflected downward.

- You can get the amount of lift on the wing by integrating the pressures over the surface of the wing or by examining the curvature introduced to the flow by the wing -- both methods will give you the same answer (and they damn well better!). This is if you have modeled the airfoil and flow in a CFD software package with a reasonably tight mesh so that you know the flow conditions at every point in space near the airfoil. Or, you can pick a standard airfoil whose properties have been determined experimentally! There are exhaustive tables of NACA airfoils to pick from. [2]

Still confused? Yeah, so am I. This is about as deep as I'm prepared to learn this topic, considering that I've given up my former life as a thermo/controls specialist in mechanical engineering, and am now trying to stuff as much understanding of software engineering and computer science into my tired brain as I can. :-)

[1] https://www.quora.com/Why-couldnt-Feynman-answer-the-questio...
[2] https://en.wikipedia.org/wiki/NACA_airfoil

* edit for typos