<?php
  
  namespace Api\Controllers\Auth;
  
  use Api\Core\Controller;
  use PDO;
  use RobThree\Auth\TwoFactorAuth;
  
  class TfaController extends Controller
  {
    public function verify()
    {
      validate([
        'token' => 'required',
        'code' => 'required|numeric|digits_between:6,6',
      ]);
      
			$token = input('token');
			$code = input('code');
			
      $session = db()->prepare("SELECT id, accountID, isTfaVerified FROM AccountSessions WHERE loginToken = ? AND expiryDate > ?");
      $session->execute(array($token, date('Y-m-d H:i:s')));
      $session = $session->fetch(PDO::FETCH_ASSOC);
			
			if (!$session) {
				api()->notFound('SESSION_NOT_FOUND', 'Session not found!');
			}
	  
			// Ignore if TFA is already verified or not required
	    if ($session['isTfaVerified'] != 0) {
		    api()->success();
	    }
			
	    $tfaKey = db()->prepare("SELECT secretKey FROM AccountTfaKeys WHERE accountID = ?");
	    $tfaKey->execute([$session['accountID']]);
	    $tfaKey = $tfaKey->fetch(PDO::FETCH_ASSOC);
	    
			// Ignore if TFA is not enabled for the account
	    // This is useful for accounts that have TFA disabled but still have a session
	    // If TFA is not enabled, we just return success without verifying the code
	    // This allows users to log in without TFA if they have it disabled
			if (!$tfaKey) {
		    api()->success();
	    }
			
			$secretKey = $tfaKey['secretKey'];
	    
	    try {
		    $tfa = new TwoFactorAuth(settings('serverName'));
		    
		    if ($tfa->verifyCode($secretKey, $code) !== true) {
			    api()->unauthorized('WRONG_CODE', 'Wrong code!');
		    }
		    
		    // Mark the session as TFA verified by setting isTfaVerified to 1
		    $verifyTfa = db()->prepare("UPDATE AccountSessions SET isTfaVerified = ? WHERE id = ?");
		    $verifyTfa->execute([1, $session['id']]);
		    
		    api()->success();
	    } catch (\Exception $e) {
		    // Handle any exceptions that may occur during TFA verification
		    api()->error('TFA_VERIFICATION_FAILED', 'TFA verification failed: ' . $e->getMessage());
	    }
    }
  }