It's called a "toggle" - the basis of the code is that when the button is pushed, if the output was low, set it high else if the output was high, set it low.
The first complication is as mentioned "state change", you only want to do this when the button was released and it has since become pressed.
However in fact, a pushbutton does not behave in the way you would desire - the contacts bounce such that over a period of a few milliseconds, the contact is made, breaks, is made again, breaks again and so on until it finally stays in contact. And it can be similarly uncertain as it breaks, so both the "make" and the "break" must be "de-bounced".
I hope this previous submission of mine might give you some ideas.