totp is good in theory but not ideal for sending via email. Users might miss the email, or it gets delayed, then they want to resend the email and end up with two codes or more. Which one to use then? and you might want bruteforce protection so you introduce a rate limit, which can lock users out in those scenarios.