I’ve achieved this using a Finite State Machine. Although mine is a top down game, the concepts can be applied to platformers.
Each enemy has a set of states it can be in, like walking, turning, spotted player, chasing, checking, returning to walk etc. It looks like this (action is the state the enemy is in):

Some of the events (collapsed) that achieve this:
In a nutshell, the enemy walks until they hit a hidden turn block, turn and then repeat the process (Walking & Pausing states).
If during the walk they spot the player, the enemy hastens over to where the player was spotted (Spotted and Chasing states).
Once they reach the point where the player was spotted, they check again for the player (Checking state).
If there’s nothing, they head back to the position they were at when they spotted the player and resume the walk > turn routine (ReturnToWalk state)
If the player is spotted, the enemy speeds up and chases the player relentlessly (RedAlert state).
