<?php
/**
 * Ajax handler for login OTP on the two-factor authentication.
 *
 * @since 2.7.0
 *
 * @package Masteriyo\Addons\TwoFactorAuthentication\AjaxHandlers
 */

namespace Masteriyo\Addons\TwoFactorAuthentication\AjaxHandlers;

defined( 'ABSPATH' ) || exit;


use Masteriyo\Abstracts\AjaxHandler;
use Masteriyo\Exceptions\RestException;

/**
 * Class LoginOTPAjaxHandler
 *
 * Handles AJAX requests for OTP during two-factor authentication login.
 *
 * @package Masteriyo\Addons\TwoFactorAuthentication\AjaxHandlers
 */
class LoginOTPAjaxHandler extends AjaxHandler {

	/**
	 * The Ajax action for OTP login.
	 *
	 * @var string
	 *
	 * @since 2.7.0
	 */
	public $action = 'masteriyo_two_factor_authentication_otp_login';

	/**
	 * The Ajax action for OTP resend.
	 *
	 * @since 2.7.0
	 *
	 * @var string
	 */
	public $otp_resend_action = 'masteriyo_two_factor_authentication_otp_login_resend';

	/**
	 * Register the AJAX handlers.
	 *
	 * Registers the OTP login and OTP resend AJAX handlers.
	 *
	 * @since 2.7.0
	 */
	public function register() {
		add_action( "wp_ajax_nopriv_{$this->action}", array( $this, 'process' ) );
		add_action( "wp_ajax_nopriv_{$this->otp_resend_action}", array( $this, 'opt_login_resend_handler' ) );
	}

	/**
	 * Process the OTP Ajax request.
	 *
	 * Handles the OTP login Ajax request, verifies the nonce, validates the OTP, and performs the login.
	 *
	 * @since 2.7.0
	 *
	 * @throws RestException If there is an error processing the request.
	 *
	 * @return void Returns no explicit value. Sends JSON response using wp_send_json_success() or wp_send_json_error().
	 */
	public function process() {

		if ( ! isset( $_POST['_wpnonce'] ) ) {
			wp_send_json_error(
				array(
					'message' => __( 'Nonce is required.', 'learning-management-system' ),
				),
				400
			);
		}

		try {
			if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'masteriyo_login_otp_nonce' ) ) {
				throw new \Exception( __( 'Invalid nonce. Maybe you should reload the page.', 'learning-management-system' ) );
			}

			if ( ! isset( $_POST['user_id'] ) && ! isset( $_POST['login-otp-code'] ) ) {
				throw new RestException( 'masteriyo_invalid_params', __( 'Invalid request parameters!', 'learning-management-system' ) );
			}

			$user_id  = absint( $_POST['user_id'] );
			$otp_code = sanitize_text_field( $_POST['login-otp-code'] );

			$user = get_user_by( 'ID', $user_id );

			if ( ! $user ) {
				throw new \Exception( __( 'No user found with the given email address.', 'learning-management-system' ) );
			}

			$is_verified = masteriyo_login_otp_verification_handler( $user_id, $otp_code );

			if ( $is_verified ) {
				masteriyo_do_login( $user );

				wp_send_json_success(
					array(
						'message'  => __( 'OTP verified successfully.', 'learning-management-system' ),
						'redirect' => $this->get_redirect_url( $user, masteriyo_get_account_url() ),

					)
				);

			}

			throw new \Exception( __( 'Sorry!, invalid OTP. Please, try again.', 'learning-management-system' ) );

		} catch ( \Exception $e ) {
			wp_send_json_error(
				array(
					'message' => $e->getMessage(),
				)
			);
		}
	}

	/**
	 * Handle OTP resend request.
	 *
	 * Handles the OTP resend Ajax request, verifies the nonce, and triggers OTP resend.
	 *
	 * @since 2.7.0
	 *
	 * @throws RestException If there is an error processing the request.
	 *
	 * @return void Returns no explicit value. Sends JSON response using wp_send_json_success() or wp_send_json_error().
	 */
	public function opt_login_resend_handler() {

		if ( ! isset( $_POST['nonce'] ) ) {
			wp_send_json_error(
				array(
					'message' => __( 'Nonce is required.', 'learning-management-system' ),
				),
				400
			);
		}

		try {
			if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['nonce'] ) ), 'masteriyo_login_otp_resend_nonce' ) ) {
				throw new \Exception( __( 'Invalid nonce. Maybe you should reload the page.', 'learning-management-system' ) );
			}

			if ( ! isset( $_POST['user_id'] ) ) {
				throw new RestException( 'masteriyo_invalid_params', __( 'Invalid request parameters!', 'learning-management-system' ) );
			}

			$user_id = absint( $_POST['user_id'] );

			$user = get_user_by( 'ID', $user_id );

			$user = masteriyo_get_user( $user_id );

			if ( is_wp_error( $user ) || is_null( $user ) ) {
				throw new \Exception( __( 'No user found with the given email address.', 'learning-management-system' ) );
			}

			$otp_resend = masteriyo_login_otp_resend_handler( $user );

			if ( is_wp_error( $otp_resend ) ) {

				wp_send_json_error(
					array(
						'message' => $otp_resend->get_error_message(),
					)
				);
			}

			/* translators: %s: email address */
			$translation_template = __( 'A new OTP code has been resent to your registered email address (%s). Please check your email and enter the new OTP code to continue.', 'learning-management-system' );

			$success_message = sprintf( $translation_template, $user->get_email() );

			wp_send_json_success(
				array(
					'message'               => $success_message,
					'resend_count'          => $otp_resend,
					'resend_remaining_time' => masteriyo_get_resend_remaining_time( $user_id ),
				)
			);

		} catch ( \Exception $e ) {
			wp_send_json_error(
				array(
					'message' => $e->getMessage(),
				)
			);
		}
	}

	/**
	 * Return redirection url.
	 *
	 * @since 2.7.0
	 *
	 * @param \WP_User $user User object.
	 * @param string $redirect_to Redirect URL after login.
	 * @return string
	 */
	private function get_redirect_url( $user, $redirect_to ) {
		/**
		 * Filters redirection URL to redirect to after user is logged in.
		 *
		 * @since 2.7.0
		 *
		 * @param string $url Redirection URL.
		 * @param \WP_user $user User object.
		 */

		$redirection_url = apply_filters( 'masteriyo_after_signin_redirect_url', $redirect_to, $user );
		$redirection_url = wp_validate_redirect( $redirection_url, $redirect_to );

		return $redirection_url;
	}
}
