<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class WpironTwoFactorAuth {

	const SECRET_LENGTH = 16;
	const OPTION_NAME = 'iron_security_2fa_settings';
	const USER_SECRET_KEY = 'iron_security_2fa_secret';
	const USER_SECRET_STATUS = 'iron_security_2fa_enabled';
	const USER_2FA_REQUIRED_KEY = 'iron_security_2fa_setup_required';
	const USER_2FA_REMEMBERED_DEVICES_KEY = 'iron_security_2fa_remembered_devices';
	const USER_2FA_VERIFICATION_PENDING_KEY = 'iron_security_2fa_pending';

	private $helpers;

	public function __construct(WpironHelper $helpers) {
		$this->helpers        = $helpers;
	}


	public function get_settings() {
		$default_settings = [
			'enabled'         => false,
			'roles'           => [ 'administrator' ],
			'grace_period'    => 1,
			'remember_device' => 7,
		];

		$settings = get_option( self::OPTION_NAME, $default_settings );

		return wp_parse_args( $settings, $default_settings );
	}

	public function updateSettings( $settings ) {
		return update_option( self::OPTION_NAME, $settings );
	}

	public function is2faEnabledForTheUser( $user ) {
		$settings = $this->get_settings();

		if ( ! $settings['enabled'] ) {
			return false;
		}

		$user = is_a( $user, 'WP_User' ) ? $user : get_userdata( $user );

		if ( ! $user ) {
			return false;
		}

		$required_roles = $settings['roles'];
		foreach ( $user->roles as $role ) {
			if ( in_array( $role, $required_roles ) ) {
				return true;
			}
		}

		return false;
	}

	public function generateSecret() {
		$chars  = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
		$secret = '';

		for ( $i = 0; $i < self::SECRET_LENGTH; $i ++ ) {
			$secret .= $chars[ wp_rand( 0, strlen( $chars ) - 1 ) ];
		}

		return $secret;
	}

	public function getUserSecret( $user_id ) {
		$secret = get_user_meta( $user_id, 'iron_security_2fa_secret', true );

		if ( empty( $secret ) ) {
			$secret = $this->generateSecret();
			update_user_meta( $user_id, self::USER_SECRET_KEY, $secret );
			update_user_meta( $user_id, self::USER_SECRET_STATUS, false );
		}

		return $secret;
	}

	public function is2faSetup( $user_id ) {
		return (bool) get_user_meta( $user_id, self::USER_SECRET_STATUS, true );
	}

	public function enable2fa( $user_id ) {
		return update_user_meta( $user_id, self::USER_SECRET_STATUS, true );
	}

	public function require2faSetup( $user_id ) {
		return update_user_meta( $user_id, self::USER_2FA_REQUIRED_KEY, current_time( 'mysql' ) );
	}

	public function verifyCode( $secret, $code ) {
		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'lib/GoogleAuthenticator.php';
		$ga = new PHPGangsta_GoogleAuthenticator();

		return $ga->verifyCode( $secret, $code, 2 );
	}

	public function getQrCodeUel( $secret, $email ) {
		require_once plugin_dir_path( dirname( __FILE__ ) ) . 'lib/GoogleAuthenticator.php';

		$site_name = get_bloginfo( 'name' );
		$site_name = preg_replace( '/[^a-zA-Z0-9 ]/', '', $site_name );

		$account = $site_name . ':' . $email;
		$title   = $site_name;

		$otpauth_uri = 'otpauth://totp/' . rawurlencode( $account ) . '?secret=' . $secret . '&issuer=' . rawurlencode( $title );

		return 'https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=' . urlencode( $otpauth_uri );
	}

	public function clearSetupRequired( $user_id ) {
		return delete_user_meta( $user_id, self::USER_2FA_REQUIRED_KEY );
	}

	public function isInGracePeriod( $user_id ) {
		$settings       = $this->get_settings();
		$setup_required = get_user_meta( $user_id, self::USER_2FA_REQUIRED_KEY, true );

		if ( ! $setup_required ) {
			return false;
		}

		$grace_period_days   = $settings['grace_period'];
		$setup_required_time = strtotime( $setup_required );
		$grace_period_end    = $setup_required_time + ( $grace_period_days * DAY_IN_SECONDS );

		return time() < $grace_period_end;
	}

	public function rememberDevice( $user_id ) {
		$settings = $this->get_settings();
		$days     = intval( $settings['remember_device'] );

		if ( $days <= 0 ) {
			return;
		}

		$token      = wp_generate_password( 32, false );
		$expiration = time() + ( $days * DAY_IN_SECONDS );

		$remembered_devices = get_user_meta( $user_id, self::USER_2FA_REMEMBERED_DEVICES_KEY, true );

		if ( ! is_array( $remembered_devices ) ) {
			$remembered_devices = [];
		}

		$remembered_devices[] = [
			'token'      => $token,
			'expires'    => $expiration,
			'ip'         => $this->helpers->get_user_ip(),
			'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
		];

		update_user_meta( $user_id, self::USER_2FA_REMEMBERED_DEVICES_KEY, $remembered_devices );

		$cookie_name = 'iron_security_2fa_' . md5( get_home_url() );
		setcookie( $cookie_name, $token, $expiration, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true );
	}

	public function isDeviceRemembered( $user_id ) {
		$cookie_name = 'iron_security_2fa_' . md5( get_home_url() );

		if ( empty( $_COOKIE[ $cookie_name ] ) ) {
			return false;
		}

		$token              = $_COOKIE[ $cookie_name ];
		$remembered_devices = get_user_meta( $user_id, self::USER_2FA_REMEMBERED_DEVICES_KEY, true );

		if ( ! is_array( $remembered_devices ) ) {
			return false;
		}

		$current_time = time();
		$current_ip   = $this->helpers->get_user_ip();

		foreach ( $remembered_devices as $key => $device ) {
			if ( $device['expires'] < $current_time ) {
				unset( $remembered_devices[ $key ] );
				continue;
			}

			if ( $device['token'] === $token && $device['ip'] === $current_ip ) {
				return true;
			}
		}

		update_user_meta( $user_id, self::USER_2FA_REMEMBERED_DEVICES_KEY, array_values( $remembered_devices ) );

		return false;
	}

	public function markVerificationPending( $user_id ) {
		return update_user_meta( $user_id, self::USER_2FA_VERIFICATION_PENDING_KEY, current_time( 'mysql' ) );
	}

	public function isVerificationPending( $user_id ) {
		$pending = get_user_meta( $user_id, self::USER_2FA_VERIFICATION_PENDING_KEY, true );

		return ! empty( $pending );
	}

	public function clearVerificationPending( $user_id ) {
		return delete_user_meta( $user_id, self::USER_2FA_VERIFICATION_PENDING_KEY );
	}

	public function checkAuthStatus( $verify2fa, $setup2fa, $currentPage ) {
		if ( isset( $_GET['iron_security_2fa_verify'] ) ) {
			return;
		}

		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
			return;
		}

		$exempt_scripts = array( 'admin-post.php', 'admin-ajax.php' );
		$script_name    = isset( $_SERVER['SCRIPT_NAME'] ) ? basename( $_SERVER['SCRIPT_NAME'] ) : '';
		if ( in_array( $script_name, $exempt_scripts ) ) {
			return;
		}

		$is_admin      = is_admin();
		$is_login_page = ( strpos( $_SERVER['SCRIPT_NAME'], 'wp-login.php' ) !== false );

		if ( ! $is_admin && ! $is_login_page ) {
			return;
		}

		$is_profile_setup = false;
		if ( $script_name === 'profile.php' && isset( $_GET['iron_security_2fa_setup'] ) && $_GET['iron_security_2fa_setup'] === 'required' ) {
			$is_profile_setup = true;
		}

		if ( $is_profile_setup ) {
			return;
		}

		if ( isset( $_GET['page'] ) && $_GET['page'] === 'iron-security-2fa-setup' ) {
			return;
		}

		$user_id = get_current_user_id();
		if ( ! $user_id ) {
			return;
		}

		if ( ! $this->is2faEnabledForTheUser( $user_id ) ) {
			$this->clearVerificationPending( $user_id );

			return;
		}

		if ( $this->isDeviceRemembered( $user_id ) ) {
			$this->clearVerificationPending( $user_id );

			return;
		}

		if ( ! $this->is2faSetup( $user_id ) ) {
			$this->require2faSetup( $user_id );
			wp_redirect( admin_url( 'profile.php?iron_security_2fa_setup=required' ) );
			exit;
		}


		if ( $is_admin && ! $this->is2faVerificationComplete( $user_id ) ) {
			if ( ! $this->isVerificationPending( $user_id ) ) {
				$this->markVerificationPending( $user_id );
			}

			wp_redirect( home_url( '?iron_security_2fa_verify=1' ) );
			exit;
		}
	}

	public function verify2fa( $verify2fa ) {
		if ( ! isset( $verify2fa ) ) {
			return;
		}

		if ( $verify2fa !== '1' ) {
			return;
		}

		if ( ! is_user_logged_in() ) {
			wp_redirect( wp_login_url( home_url( '?iron_security_2fa_verify=1' ) ) );
			exit;
		}

		$user_id = get_current_user_id();

		if ( ! $this->is2faEnabledForTheUser( $user_id ) ) {
			$this->clearVerificationPending( $user_id );

			return;
		}

		if ( $this->isDeviceRemembered( $user_id ) ) {
			$this->clearVerificationPending( $user_id );
			wp_redirect( admin_url() );
			exit;
		}

		if ( ! $this->is2faSetup( $user_id ) ) {
			$this->require2faSetup( $user_id );
			wp_redirect( admin_url( 'profile.php?iron_security_2fa_setup=required' ) );
			exit;
		}


		if ( $this->is2faVerificationComplete( $user_id ) ) {
			wp_redirect( admin_url() );
			exit;
		}


		if ( ! $this->isVerificationPending( $user_id ) ) {
			$this->markVerificationPending( $user_id );
		}


		if ( isset( $_GET['success'] ) && ( $_GET['success'] === '1' || $_GET['success'] === 1 ) ) {
			$this->clearVerificationPending( $user_id );
			wp_redirect( admin_url() );
			exit;
		}

		$this->load_2fa_template();
		exit;
	}

	private function load_2fa_template() {
		$template_path = plugin_dir_path( dirname( dirname( __FILE__ ) ) ) . 'public/templates/two-factor-auth.php';

		if ( file_exists( $template_path ) ) {
			include_once $template_path;
		} else {
			$this->render_verification_page();
		}
	}

	public function add2faFields() {
		?>
        <p id="iron-security-2fa-field" style="display:none;">
            <label for="iron_security_2fa_code">
				<?php
				esc_html_e( 'Two-Factor Authentication Code', 'iron-security' ); ?><br>
                <input type="text" name="iron_security_2fa_code" id="iron_security_2fa_code" class="input" size="20"
                       pattern="[0-9]*" autocomplete="off">
            </label>
        </p>
		<?php
	}

	public function authRedirect( $user_login, $user ) {
		if ( ! $this->is2faEnabledForTheUser( $user->ID ) ) {
			return;
		}

		if ( $this->isDeviceRemembered( $user->ID ) ) {
			return;
		}

		if ( ! $this->is2faSetup( $user->ID ) ) {
			$this->require2faSetup( $user->ID );
			wp_redirect( admin_url( 'profile.php?iron_security_2fa_setup=required' ) );
			exit;
		}

		$this->markVerificationPending( $user->ID );
		wp_safe_redirect( home_url( '?iron_security_2fa_verify=1' ) );
		exit;
	}

	public function display_2fa_setup_notice() {
		global $pagenow;

		if ( $pagenow !== 'profile.php' ) {
			return;
		}

		$user_id = get_current_user_id();
		if ( ! $this->is2faEnabledForTheUser( $user_id ) ) {
			return;
		}

		if ( $this->is2faSetup( $user_id ) ) {
			if ( isset( $_GET['iron_security_2fa_setup'] ) && $_GET['iron_security_2fa_setup'] === 'complete' ) {
				echo '<div class="notice notice-success is-dismissible">';
				echo '<p><strong>' . esc_attr(__( 'Two-factor authentication successfully set up!',
						'iron-security' )) . '</strong> ' .
				     esc_attr(__( 'Your account is now protected with two-factor authentication.', 'iron-security' )) . '</p>';
				echo '</div>';
			}

			return;
		}

		add_action( 'show_user_profile', array( $this, 'add_2fa_setup_to_profile' ) );

		$setup_required = isset( $_GET['iron_security_2fa_setup'] ) && sanitize_text_field( $_GET['iron_security_2fa_setup'] ) === 'required';
		$in_grace_period   = $this->isInGracePeriod( $user_id );
		$settings          = $this->get_settings();
		$grace_period_days = $settings['grace_period'];
        $notice_class = ( $in_grace_period && ! $setup_required ) ? 'notice-warning' : 'notice-error';
		$message      = $in_grace_period && ! $setup_required
			? sprintf(
			/* translators: %s: Name of a days */
                    __( 'Your account requires two-factor authentication (2FA). Please set it up within %d days.',
				'iron-security' ),
				$grace_period_days )
			: esc_html__( 'Your account requires two-factor authentication (2FA). You must set it up now to continue using the admin area.',
				'iron-security' );

		echo '<div class="notice ' . esc_attr($notice_class) . ' is-dismissible">';
		echo '<p><strong>' . esc_html__( 'Two-Factor Authentication Required', 'iron-security' ) . '</strong></p>';
		echo '<p>' . wp_kses_post($message) . '</p>';
		echo '<p><a href="#iron-security-2fa-setup" class="button button-primary">' . esc_attr(__( 'Set Up Two-Factor Authentication',
				'iron-security' )) . '</a></p>';
		echo '</div>';
	}

	public function saveUserProfileFields( $user_id ) {
		if ( ! current_user_can( 'edit_user', $user_id ) ) {
			return;
		}

		$reset2fairon = sanitize_text_field( $_POST['iron_security_2fa_code'] );

		if ( isset( $reset2fairon ) && $reset2fairon === '1' ) {
			if ( ! wp_verify_nonce( $reset2fairon, 'iron_security_2fa_reset' ) ) {
				return;
			}

			delete_user_meta( $user_id, self::USER_SECRET_KEY );
			delete_user_meta( $user_id, self::USER_SECRET_STATUS );
			delete_user_meta( $user_id, self::USER_2FA_REMEMBERED_DEVICES_KEY );

			$this->require2faSetup( $user_id );

			add_action( 'user_profile_update_errors', function ( $errors ) {
				$errors->add( 'iron_security_2fa_reset',
					__( 'Two-factor authentication has been reset. You\'ll need to set it up again.', 'iron-security' ),
					'updated' );
			} );
		}
	}

	public function addUserProfilefields( $user ) {
		$is_enabled = $this->is2faEnabledForTheUser( $user->ID );
		$is_setup   = $this->is2faSetup( $user->ID );

		if ( ! $is_enabled ) {
			return;
		}
		?>
        <h2><?php
			esc_html_e( 'Two-Factor Authentication', 'iron-security' ); ?></h2>

        <table class="form-table">
            <tr>
                <th><?php
					esc_html_e( 'Status', 'iron-security' ); ?></th>
                <td>
					<?php
					if ( $is_setup ) : ?>
                        <span style="color: green; font-weight: bold;"><?php
							esc_html_e( 'Enabled', 'iron-security' ); ?></span>
                        <p class="description"><?php
							esc_html_e( 'Two-factor authentication is enabled for your account.', 'iron-security' ); ?></p>

                        <button type="button" class="button" id="iron-security-2fa-reset">
							<?php
							esc_html_e( 'Reset Two-Factor Authentication', 'iron-security' ); ?>
                        </button>
                        <p class="description"><?php
							esc_html_e( 'This will remove the current 2FA configuration and allow you to set it up again.',
								'iron-security' ); ?></p>
					<?php
					else : ?>
                        <span style="color: red; font-weight: bold;"><?php
							esc_html_e( 'Not Set Up', 'iron-security' ); ?></span>
                        <p class="description"><?php
							esc_html_e( 'Two-factor authentication is required but not set up for your account.',
								'iron-security' ); ?></p>

                        <a href="<?php
						echo esc_url( admin_url( 'admin.php?page=iron-security-2fa-setup' ) ); ?>"
                           class="button button-primary">
							<?php
							esc_html_e( 'Set Up Two-Factor Authentication', 'iron-security' ); ?>
                        </a>
					<?php
					endif; ?>
                </td>
            </tr>
        </table>

		<?php
		if ( $is_setup ) : ?>
            <div id="iron-security-2fa-reset-confirm"
                 style="display:none; margin-top: 10px; padding: 10px; background: #f8f8f8; border: 1px solid #ddd;">
                <p><?php
					esc_html_e( 'Are you sure you want to reset two-factor authentication? This will remove your current configuration and you\'ll need to set it up again.',
						'iron-security' ); ?></p>

                <form method="post">
					<?php
					wp_nonce_field( 'iron_security_2fa_reset', 'iron_security_2fa_reset_nonce' ); ?>
                    <input type="hidden" name="iron_security_2fa_reset" value="1">

                    <button type="submit" class="button button-secondary"><?php
						esc_html_e( 'Yes, Reset 2FA', 'iron-security' ); ?></button>
                    <button type="button" class="button button-primary" id="iron-security-2fa-reset-cancel"><?php
						esc_html_e( 'Cancel', 'iron-security' ); ?></button>
                </form>
            </div>

            <script>
                document.addEventListener('DOMContentLoaded', function () {
                    const resetButton = document.getElementById('iron-security-2fa-reset');
                    const resetConfirm = document.getElementById('iron-security-2fa-reset-confirm');
                    const cancelButton = document.getElementById('iron-security-2fa-reset-cancel');

                    resetButton.addEventListener('click', function () {
                        resetConfirm.style.display = 'block';
                    });

                    cancelButton.addEventListener('click', function () {
                        resetConfirm.style.display = 'none';
                    });
                });
            </script>
		<?php
		endif; ?>
		<?php
	}

	public function add_2fa_setup_to_profile( $user ) {
		if ( ! is_a( $user, 'WP_User' ) ) {
			$user = wp_get_current_user();
		}

		if ( ! $this->is2faEnabledForTheUser( $user->ID ) || $this->is2faSetup( $user->ID ) ) {
			return;
		}

		$secret      = $this->getUserSecret( $user->ID );
		$qr_code_url = $this->getQrCodeUel( $secret, $user->user_email );

		echo '<style>
            #iron-security-2fa-setup-error {
                background-color: #f8d7da;
                color: #721c24;
                padding: 10px 15px;
                border-radius: 4px;
                margin: 10px 0;
                border-left: 4px solid #dc3545;
            }
            #iron-security-2fa-setup-success {
                background-color: #d4edda;
                color: #155724;
                padding: 10px 15px;
                border-radius: 4px;
                margin: 10px 0;
                border-left: 4px solid #28a745;
            }
            .iron-security-2fa-setup-wrapper {
                max-width: 800px;
                padding: 20px;
                background: #fff;
                border: 1px solid #e5e5e5;
                box-shadow: 0 1px 1px rgba(0,0,0,.04);
                margin-bottom: 20px;
            }
            #iron_security_2fa_setup_code {
                padding: 8px;
                font-size: 16px;
                letter-spacing: 2px;
            }
        </style>';

		echo '<div id="iron-security-2fa-setup" class="iron-security-2fa-setup-wrapper">';
		echo '<h2>' . esc_html__( 'Set Up Two-Factor Authentication', 'iron-security' ) . '</h2>';

		echo '<div class="notice notice-info">';
		echo '<p>' . esc_html__( 'Two-factor authentication adds an extra layer of security to your account. After entering your password, you\'ll need to enter a code from your authenticator app.',
				'iron-security' ) . '</p>';
		echo '</div>';

		echo '<div class="iron-security-2fa-setup-steps">';


		echo '<div class="iron-security-2fa-setup-step">';
		echo '<h3>' . esc_html__( 'Step 1: Install an Authenticator App', 'iron-security' ) . '</h3>';
		echo '<p>' . esc_html__( 'If you don\'t already have one, install an authenticator app on your mobile device:',
				'iron-security' ) . '</p>';
		echo '<ul>';
		echo '<li><a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" target="_blank">' . esc_html__( 'Google Authenticator for Android',
				'iron-security' ) . '</a></li>';
		echo '<li><a href="https://apps.apple.com/app/google-authenticator/id388497605" target="_blank">' . esc_html__( 'Google Authenticator for iOS',
				'iron-security' ) . '</a></li>';
		echo '<li><a href="https://authy.com/download/" target="_blank">' . esc_html__( 'Authy (Android, iOS, Desktop)',
				'iron-security' ) . '</a></li>';
		echo '</ul>';
		echo '</div>';


		echo '<div class="iron-security-2fa-setup-step">';
		echo '<h3>' . esc_html__( 'Step 2: Scan the QR Code', 'iron-security' ) . '</h3>';
		echo '<p>' . esc_html__( 'Open your authenticator app and scan this QR code:', 'iron-security' ) . '</p>';
		echo '<div class="iron-security-2fa-qr-code">';
		echo '<img src="' . esc_url( $qr_code_url ) . '" alt="' . esc_attr__( 'QR Code', 'iron-security' ) . '">';
		echo '</div>';


		$site_name = get_bloginfo( 'name' );
		$site_name = preg_replace( '/[^a-zA-Z0-9 ]/', '', $site_name );
		$account   = $site_name . ':' . $user->user_email;
		$totp_uri  = 'otpauth://totp/' . rawurlencode( $account ) . '?secret=' . $secret . '&issuer=' . rawurlencode( $site_name );

		echo '<p>' . esc_html__( 'If the QR code doesn\'t display properly, try this link:',
				'iron-security' ) . ' <a href="' . esc_attr( $totp_uri ) . '">' . esc_html__( 'Add to Authenticator App',
				'iron-security' ) . '</a></p>';

		echo '<p>' . esc_html__( 'Or enter this code manually:', 'iron-security' ) . '</p>';
		echo '<p class="iron-security-2fa-secret-key">' . esc_html( $secret ) . '</p>';
		echo '</div>';


		echo '<div class="iron-security-2fa-setup-step">';
		echo '<h3>' . esc_html__( 'Step 3: Verify Setup', 'iron-security' ) . '</h3>';
		echo '<p>' . esc_html__( 'Enter the 6-digit code from your authenticator app to verify the setup:',
				'iron-security' ) . '</p>';


		echo '<div id="iron-security-2fa-profile-setup-form">';
		echo '<input type="hidden" id="iron_security_2fa_secret" value="' . esc_attr( $secret ) . '">';
		echo '<input type="hidden" id="iron_security_2fa_setup_nonce" value="' . esc_attr(wp_create_nonce( 'iron_security_2fa_setup' )) . '">';
		echo '<p>';
		echo '<input type="text" id="iron_security_2fa_setup_code" pattern="[0-9]*" autocomplete="off" class="regular-text" placeholder="' . esc_attr__( 'Enter 6-digit code',
				'iron-security' ) . '">';
		echo '</p>';


		echo '<div id="iron-security-2fa-setup-error" style="display:none;"><p></p></div>';

		echo '<p class="submit">';
		echo '<button type="button" class="button button-primary" id="iron_security_2fa_setup_verify">';
		echo esc_html__( 'Verify and Activate', 'iron-security' );
		echo '</button>';
		echo '</p>';
		echo '</div>';

		echo '<div id="iron-security-2fa-setup-success" style="display: none;">';
		echo '<p>' . esc_html__( 'Two-factor authentication has been successfully set up for your account!',
				'iron-security' ) . '</p>';
		echo '<p>' . esc_html__( 'You will now be asked to enter a verification code when you log in.',
				'iron-security' ) . '</p>';
		echo '</div>';

		echo '</div>';

		echo '</div>';
		echo '</div>';


		echo '<script>
            jQuery(document).ready(function($) {
                
                const $verifyBtn = $("#iron_security_2fa_setup_verify");
                const $codeInput = $("#iron_security_2fa_setup_code");
                const $errorDiv = $("#iron-security-2fa-setup-error");
                const $successDiv = $("#iron-security-2fa-setup-success");
                const $setupForm = $("#iron-security-2fa-profile-setup-form");
              
                $errorDiv.hide();
                
                $verifyBtn.on("click", function(e) {
                    
                    e.preventDefault();
                    e.stopPropagation();
                    
                    const code = $codeInput.val().trim();
                    const secret = $("#iron_security_2fa_secret").val();
                    const nonce = $("#iron_security_2fa_setup_nonce").val();
                    
                    if (!code || code.length !== 6 || !/^\\d+$/.test(code)) {
                        $errorDiv.show().find("p").text("' . esc_js( __( 'Please enter a valid 6-digit code.',
				'iron-security' ) ) . '");
                        return false;
                    }
                    
                    $verifyBtn.prop("disabled", true).text("' . esc_js( __( 'Verifying...', 'iron-security' ) ) . '");
                    $errorDiv.hide();
                    
                    $.ajax({
                        url: ajaxurl,
                        type: "POST",
                        dataType: "json",
                        data: {
                            action: "iron_security_verify_2fa_setup",
                            code: code,
                            secret: secret,
                            nonce: nonce
                        }
                    })
                    .done(function(response) {
                        if (response.success) {
                            
                            $errorDiv.hide();
                            $setupForm.hide();
                            $successDiv.show();
                            
                            setTimeout(function() {
                                
                                window.location.replace("' . esc_url( admin_url( 'profile.php?iron_security_2fa_setup=complete#iron-security-2fa-setup' ) ) . '");
                            }, 2000);
                        } else {
                            
                            $verifyBtn.prop("disabled", false).text("' . esc_js( __( 'Verify and Activate',
				'iron-security' ) ) . '");
                            $errorDiv.show().find("p").text(response.data || "' . esc_js( __( 'Invalid verification code. Please try again.',
				'iron-security' ) ) . '");
                        }
                    })
                    .fail(function(jqXHR, textStatus, errorThrown) {
                        
                        $verifyBtn.prop("disabled", false).text("' . esc_js( __( 'Verify and Activate',
				'iron-security' ) ) . '");
                        $errorDiv.show().find("p").text("' . esc_js( __( 'Error connecting to the server. Please try again.',
				'iron-security' ) ) . '");
                        console.error("AJAX Error:", textStatus, errorThrown);
                    });
                    
                    return false;
                });
                
                $codeInput.on("keypress", function(e) {
                    if (e.which === 13) {
                        e.preventDefault();
                        e.stopPropagation();
                        $verifyBtn.click();
                        return false;
                    }
                });
                
                $codeInput.closest("form").on("keypress", "#iron_security_2fa_setup_code", function(e) {
                    if (e.which === 13) {
                        e.preventDefault();
                        e.stopPropagation();
                        return false;
                    }
                });
            });
        </script>';
	}

	private function render_verification_page() {
		$user            = wp_get_current_user();
		$settings        = $this->get_settings();
		$remember_device = (int) $settings['remember_device'] > 0;

		$title              = __( 'Two-Factor Authentication', 'iron-security' );
		$login_header_url   = home_url();
		$login_header_title = get_bloginfo( 'name' );

		ob_start();
		?>
        <!DOCTYPE html>
        <html <?php
		language_attributes(); ?>>
        <head>
            <meta charset="<?php
			bloginfo( 'charset' ); ?>">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title><?php
				echo esc_html( $title ); ?> - <?php
				bloginfo( 'name' ); ?></title>
            <style>
                body {
                    background-color: #f1f1f1;
                    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
                    line-height: 1.5;
                    padding: 0;
                    margin: 0;
                }

                #login {
                    width: 320px;
                    padding: 8% 0 0;
                    margin: auto;
                }

                .iron-security-2fa-form {
                    margin-top: 20px;
                    margin-bottom: 20px;
                    background: #fff;
                    padding: 26px 24px;
                    border-radius: 4px;
                    box-shadow: 0 1px 3px rgba(0, 0, 0, .1);
                }

                .iron-security-2fa-form label {
                    display: block;
                    margin-bottom: 5px;
                    font-weight: 500;
                }

                .iron-security-2fa-remember {
                    margin-top: 15px;
                }

                .iron-security-2fa-actions {
                    margin-top: 20px;
                    display: flex;
                    justify-content: space-between;
                }

                .iron-security-2fa-error {
                    color: #dc3232;
                    margin-bottom: 15px;
                    background-color: #f8d7da;
                    padding: 10px 15px;
                    border-radius: 4px;
                    border-left: 4px solid #dc3545;
                }

                .button {
                    display: inline-block;
                    text-decoration: none;
                    font-size: 13px;
                    line-height: 2.15384615;
                    min-height: 30px;
                    margin: 0;
                    padding: 0 10px;
                    cursor: pointer;
                    border-width: 1px;
                    border-style: solid;
                    -webkit-appearance: none;
                    border-radius: 3px;
                    white-space: nowrap;
                    box-sizing: border-box;
                }

                .button-primary {
                    background: #2271b1;
                    border-color: #2271b1;
                    color: #fff;
                }

                .button-secondary {
                    background: #f6f7f7;
                    border-color: #2271b1;
                    color: #2271b1;
                }

                .button-large {
                    min-height: 32px;
                    line-height: 2.30769231;
                    padding: 0 12px;
                }

                .input {
                    font-size: 24px;
                    line-height: 1.33333333;
                    width: 100%;
                    border: 1px solid #ddd;
                    box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07);
                    background-color: #fff;
                    color: #32373c;
                    padding: 3px 5px;
                    margin: 0;
                    box-sizing: border-box;
                }

                h1 {
                    text-align: center;
                }

                h1 a {
                    background-image: url(<?php echo esc_url(admin_url('images/w-logo-blue.png')); ?>);
                    background-size: 84px;
                    background-position: center top;
                    background-repeat: no-repeat;
                    width: 84px;
                    height: 84px;
                    margin: 0 auto 25px;
                    padding: 0;
                    text-indent: -9999px;
                    outline: 0;
                    overflow: hidden;
                    display: block;
                }

                h2 {
                    margin-top: 0;
                    margin-bottom: 10px;
                }

                a {
                    color: #2271b1;
                    text-decoration: none;
                }

                input[type="checkbox"] {
                    margin-right: 5px;
                }
            </style>
        </head>
        <body class="login wp-core-ui">
        <div id="login">
            <h1><a href="<?php
				echo esc_url( $login_header_url ); ?>" title="<?php
				echo esc_attr( $login_header_title ); ?>" tabindex="-1"><?php
					bloginfo( 'name' ); ?></a></h1>

            <div id="login_error" class="iron-security-2fa-error" style="display: none;"></div>

            <form id="iron-security-2fa-verify-form" class="iron-security-2fa-form">
				<?php
				wp_nonce_field( 'iron_security_2fa_verify', 'iron_security_2fa_verify_nonce' ); ?>

                <h2><?php
				esc_html_e( 'Two-Factor Authentication', 'iron-security' ); ?></h2>
                <p><?php
					printf(
					        /* translators: %s: Name of a name */
                            esc_html__( 'Hi %s, please enter the verification code from your authenticator app.',
						'iron-security' ),
						esc_html($user->display_name) ); ?></p>

                <div class="user-pass-wrap">
                    <label for="iron_security_2fa_verify_code"><?php
						esc_html_e( 'Authentication Code', 'iron-security' ); ?></label>
                    <div class="wp-pwd">
                        <input type="text" name="code" id="iron_security_2fa_verify_code" class="input" size="20"
                               pattern="[0-9]*" autocomplete="off" autofocus/>
                    </div>
                </div>

				<?php
				if ( $remember_device ) : ?>
                    <div class="iron-security-2fa-remember">
                        <label for="iron_security_2fa_remember">
                            <input name="remember" type="checkbox" id="iron_security_2fa_remember" value="1"/>
							<?php
							printf(
							        /* translators: %s: Name of a device */
                                    esc_html__( 'Remember this device for %d days', 'iron-security' ),
								esc_html($settings['remember_device']) ); ?>
                        </label>
                    </div>
				<?php
				endif; ?>

                <div class="iron-security-2fa-actions">
                    <input type="submit" name="wp-submit" id="wp-submit" class="button button-primary button-large"
                           value="<?php
					       esc_attr_e( 'Verify', 'iron-security' ); ?>"/>
                    <a href="<?php
					echo esc_url( wp_logout_url( home_url() ) ); ?>" class="button button-secondary button-large"><?php
						esc_html_e( 'Log Out', 'iron-security' ); ?></a>
                </div>
            </form>
        </div>

        <script>
            document.addEventListener('DOMContentLoaded', function () {
                const form = document.getElementById('iron-security-2fa-verify-form');
                const errorDiv = document.getElementById('login_error');

                form.addEventListener('submit', function (e) {
                    e.preventDefault();

                    errorDiv.style.display = 'none';

                    const code = document.getElementById('iron_security_2fa_verify_code').value;
                    const nonce = document.getElementById('iron_security_2fa_verify_nonce').value;
                    const remember = document.getElementById('iron_security_2fa_remember')?.checked || false;

                    if (!code || code.length !== 6 || !/^\d+$/.test(code)) {
                        errorDiv.textContent = '<?php esc_html_e( 'Please enter a valid 6-digit code.',
							'iron-security' ); ?>';
                        errorDiv.style.display = 'block';
                        return;
                    }

                    const submitButton = document.getElementById('wp-submit');
                    const originalButtonText = submitButton.value;
                    submitButton.value = '<?php esc_html_e( 'Verifying...', 'iron-security' ); ?>';
                    submitButton.disabled = true;

                    const data = new FormData();
                    data.append('action', 'iron_security_verify_2fa_code');
                    data.append('code', code);
                    data.append('remember', remember ? '1' : '0');
                    data.append('nonce', nonce);

                    fetch('<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>', {
                        method: 'POST',
                        credentials: 'same-origin',
                        body: data
                    })
                        .then(response => response.json())
                        .then(response => {
                            if (response.success) {
                                window.location.href = '<?php echo esc_url( admin_url() ); ?>';
                            } else {
                                errorDiv.textContent = response.data || '<?php esc_attr_e( 'Invalid verification code. Please try again.',
									'iron-security' ); ?>';
                                errorDiv.style.display = 'block';
                                submitButton.value = originalButtonText;
                                submitButton.disabled = false;
                                document.getElementById('iron_security_2fa_verify_code').value = '';
                                document.getElementById('iron_security_2fa_verify_code').focus();
                            }
                        })
                        .catch(error => {
                            console.error('Error:', error);
                            errorDiv.textContent = '<?php esc_attr_e( 'An error occurred. Please try again.',
								'iron-security' ); ?>';
                            errorDiv.style.display = 'block';
                            submitButton.value = originalButtonText;
                            submitButton.disabled = false;
                        });
                });
            });
        </script>
        </body>
        </html>
		<?php
		echo wp_kses_post(ob_get_clean());
	}

	public function ajax_verify_2fa_code() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'iron_security_2fa_verify' ) ) {
			wp_send_json_error( __( 'Security check failed.', 'iron-security' ) );

			return;
		}

		if ( ! is_user_logged_in() ) {
			wp_send_json_error( __( 'You must be logged in to verify 2FA.', 'iron-security' ) );

			return;
		}

		$code = isset( $_POST['code'] ) ? preg_replace( '/[^0-9]/', '', $_POST['code'] ) : '';
		if ( empty( $code ) || strlen( $code ) !== 6 ) {
			wp_send_json_error( __( 'Please enter a valid 6-digit code.', 'iron-security' ) );

			return;
		}

		$user_id = get_current_user_id();
		$secret  = $this->getUserSecret( $user_id );

		if ( $this->verifyCode( $secret, $code ) ) {
			$this->clearVerificationPending( $user_id );

			$_SESSION['iron_security_2fa_verified']      = true;
			$_SESSION['iron_security_2fa_verified_time'] = time();

			$expiration = time() + DAY_IN_SECONDS;

			$cookieData = $this->setCookieHash( $user_id );
			setcookie( $cookieData['cookie_name'], $cookieData['cookie_value'], [
				'expires'  => $expiration,
				'path'     => COOKIEPATH,
				'domain'   => COOKIE_DOMAIN,
				'secure'   => is_ssl(),
				'httponly' => true,
				'samesite' => 'Strict',
			] );

			if ( isset( $_POST['remember'] ) && $_POST['remember'] === '1' ) {
				$this->rememberDevice( $user_id );
			}

			wp_send_json_success( [
				'message'  => __( 'Code verified successfully.', 'iron-security' ),
				'redirect' => admin_url()
			] );
		} else {
			wp_send_json_error( __( 'Invalid verification code. Please try again.', 'iron-security' ) );
		}
	}

	private function setCookieHash( $user_id ) {
		$user_hash    = hash_hmac( 'sha256', $user_id . time(), AUTH_SALT );
		$cookie_value = base64_encode( json_encode( [
			'uid' => $user_id,
			'ts'  => time(),
			'sig' => $user_hash
		] ) );
		$cookie_name  = 'iron_security_2fa_verified';

		return [
			'cookie_name'  => $cookie_name,
			'cookie_value' => $cookie_value
		];
	}

	public function ajax_verify_2fa_setup() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'iron_security_2fa_setup' ) ) {
			wp_send_json_error( __( 'Security check failed.', 'iron-security' ) );
		}

		if ( ! is_user_logged_in() ) {
			wp_send_json_error( __( 'You must be logged in to set up 2FA.', 'iron-security' ) );
		}

		$code   = isset( $_POST['code'] ) ? preg_replace( '/[^0-9]/', '', $_POST['code'] ) : '';
		$secret = isset( $_POST['secret'] ) ? sanitize_text_field( $_POST['secret'] ) : '';

		if ( empty( $code ) || strlen( $code ) !== 6 ) {
			wp_send_json_error( __( 'Please enter a valid 6-digit code.', 'iron-security' ) );
		}

		if ( empty( $secret ) ) {
			wp_send_json_error( __( 'Invalid secret key.', 'iron-security' ) );
		}

		if ( $this->verifyCode( $secret, $code ) ) {
			$user_id = get_current_user_id();

			update_user_meta( $user_id, self::USER_SECRET_KEY, $secret );
			$this->enable2fa( $user_id );
			$this->clearSetupRequired( $user_id );

			wp_send_json_success();
		} else {
			wp_send_json_error( __( 'Invalid verification code. Please try again.', 'iron-security' ) );
		}
	}

	public function ajax_save_2fa_settings() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'iron_security_2fa_settings' ) ) {
			wp_send_json_error( __( 'Security check failed.', 'iron-security' ) );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to change these settings.', 'iron-security' ) );
		}

		$enabled         = isset( $_POST['enabled'] ) && sanitize_text_field( $_POST['enabled'] ) === '1';
		$roles           = isset( $_POST['roles'] ) && is_array( $_POST['roles'] ) ? array_map( 'sanitize_text_field',
			$_POST['roles'] ) : [];
		$grace_period    = isset( $_POST['grace_period'] ) ? absint( $_POST['grace_period'] ) : 1;
		$remember_device = isset( $_POST['remember_device'] ) ? absint( $_POST['remember_device'] ) : 7;

		if ( $grace_period > 30 ) {
			$grace_period = 30;
		}

		if ( $remember_device > 90 ) {
			$remember_device = 90;
		}

		$settings = [
			'enabled'         => $enabled,
			'roles'           => $roles,
			'grace_period'    => $grace_period,
			'remember_device' => $remember_device,
		];

		$result = $this->updateSettings( $settings );

		if ( $result ) {
			if ( $enabled ) {
				$this->mark_users_for_setup( $roles );
			}

			wp_send_json_success( [
				'message'  => __( 'Settings saved successfully.', 'iron-security' ),
				'settings' => $settings,
			] );
		} else {
			wp_send_json_error( __( 'Failed to save settings.', 'iron-security' ) );
		}
	}

	public function ajax_toggle_2fa() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'iron_security_nonce' ) ) {
			wp_send_json_error( __( 'Security check failed.', 'iron-security' ) );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to change these settings.', 'iron-security' ) );
		}

		$enabled = isset( $_POST['enabled'] ) && filter_var( $_POST['enabled'], FILTER_VALIDATE_BOOLEAN );

		$login_logout_settings               = get_option( 'wpironis_plugin_settings_loginlogout', array() );
		$login_logout_settings['enable_2fa'] = $enabled ? '1' : '0';

		$updated             = update_option( 'wpironis_plugin_settings_loginlogout', $login_logout_settings );
		$settings            = $this->get_settings();
		$settings['enabled'] = $enabled;
		$this->updateSettings( $settings );

		if ( $updated ) {
			wp_send_json_success( array(
				'message' => $enabled
					? __( 'Two-factor authentication has been enabled.', 'iron-security' )
					: __( 'Two-factor authentication has been disabled.', 'iron-security' ),
				'enabled' => $enabled
			) );
		} else {
			wp_send_json_error( __( 'Failed to update setting.', 'iron-security' ) );
		}
	}

	public function save2faSettingsForLoginLogout() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'iron_security_nonce' ) ) {
			wp_send_json_error( __( 'Security check failed.', 'iron-security' ) );
		}
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( __( 'You do not have permission to change these settings.', 'iron-security' ) );
		}

		$raw_roles = isset( $_POST['required_roles'] ) ? wp_unslash( $_POST['required_roles'] ) : array( 'administrator' );

		if ( is_array( $raw_roles ) ) {
			$required_roles = $raw_roles;
		} else {
			$decoded       = json_decode( $raw_roles, true );
			$required_roles = is_array( $decoded ) ? $decoded : array( 'administrator' );
		}

		$all_roles      = array_keys( wp_roles()->get_names() );
		$required_roles = array_values(
			array_intersect(
				array_map( 'sanitize_key', $required_roles ),
				$all_roles
			)
		);

		if ( empty( $required_roles ) ) {
			$required_roles = array( 'administrator' );
		}

		$grace_period    = isset( $_POST['grace_period'] ) ? absint( $_POST['grace_period'] ) : 1;
		$remember_device = isset( $_POST['remember_device'] ) ? absint( $_POST['remember_device'] ) : 7;

		$grace_period    = min( $grace_period, 30 );
		$remember_device = min( $remember_device, 90 );

		$login_logout_settings                       = $this->helpers->wpironis_getOption( 'wpironis_plugin_settings_loginlogout' );
		$login_logout_settings['required_2fa_roles'] = wp_json_encode( $required_roles );
		$login_logout_settings['grace_period']       = $grace_period;
		$login_logout_settings['remember_device']    = $remember_device;

		$settings                    = $this->get_settings();
		$settings['roles']           = $required_roles;
		$settings['grace_period']    = $grace_period;
		$settings['remember_device'] = $remember_device;
		$this->updateSettings( $settings );

		if ( $this->helpers->wpironis_updateOption( 'wpironis_plugin_settings_loginlogout', $login_logout_settings ) ) {

            if ( ! empty( $settings['enabled'] ) ) {
				$this->mark_users_for_setup( $required_roles );
			}
			wp_send_json_success( array(
				'message'  => __( 'Two-factor authentication settings saved successfully.', 'iron-security' ),
				'settings' => $settings,
			) );
		} else {
			wp_send_json_error( __( 'Failed to save settings!', 'iron-security' ) );
		}
	}

	public function check2faRequired() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'iron_security_2fa_ajax' ) ) {
			wp_send_json_error( __( 'Security check failed.', 'iron-security' ) );
		}

		if ( ! isset( $_POST['username'] ) || empty( $_POST['username'] ) ) {
			wp_send_json_error( __( 'Username is required.', 'iron-security' ) );
		}

		$username = sanitize_user( $_POST['username'] );
		$user     = get_user_by( 'login', $username );

		if ( ! $user ) {
			wp_send_json_success( [ 'required' => false ] );
		}

		$required = $this->is2faEnabledForTheUser( $user->ID );
		$setup    = $required ? $this->is2faSetup( $user->ID ) : false;

		wp_send_json_success( [
			'required' => $required,
			'setup'    => $setup
		] );
	}

	private function mark_users_for_setup( $roles ) {
		if ( empty( $roles ) ) {
			return;
		}

		$args = [
			'role__in' => $roles,
			'fields'   => 'ID',
		];

		$users = get_users( $args );

		foreach ( $users as $user_id ) {
			if ( ! $this->is2faSetup( $user_id ) ) {
				$this->require2faSetup( $user_id );
			}
		}
	}

	public function is2faVerificationComplete( $user_id ) {
		if ( isset( $_SESSION['iron_security_2fa_verified'] ) && $_SESSION['iron_security_2fa_verified'] === true ) {
			if ( isset( $_SESSION['iron_security_2fa_verified_time'] ) &&
			     ( time() - $_SESSION['iron_security_2fa_verified_time'] ) < DAY_IN_SECONDS ) {
				return true;
			}
		}

		$cookie_name = 'iron_security_2fa_verified';
		if ( isset( $_COOKIE[ $cookie_name ] ) ) {
			$cookie_data = json_decode( base64_decode( $_COOKIE[ $cookie_name ] ), true );
			if (
				isset( $cookie_data['uid'], $cookie_data['ts'], $cookie_data['sig'] ) &&
				abs( time() - $cookie_data['ts'] ) < 300 &&
				hash_equals(
					$cookie_data['sig'],
					hash_hmac( 'sha256', $cookie_data['uid'] . '|' . $cookie_data['ts'], AUTH_SALT )
				)
			) {
				$_SESSION['iron_security_2fa_verified']      = true;
				$_SESSION['iron_security_2fa_verified_time'] = time();

				return true;
			}
		}

		$pending = $this->isVerificationPending( $user_id );

		return ! $pending;
	}

	public function clear2faVerificationOnLogout() {
		if ( isset( $_SESSION['iron_security_2fa_verified'] ) ) {
			unset( $_SESSION['iron_security_2fa_verified'] );
		}

		if ( isset( $_SESSION['iron_security_2fa_verified_time'] ) ) {
			unset( $_SESSION['iron_security_2fa_verified_time'] );
		}

		$user_id = get_current_user_id();
		if ( $user_id ) {
			$cookieData = $this->setCookieHash( $user_id );
			if ( isset( $_COOKIE[ $cookieData['cookie_name'] ] ) ) {
				setcookie( $cookieData['cookie_name'], $cookieData['cookie_value'], [
					'expires'  => time() - 3600,
					'path'     => COOKIEPATH,
					'domain'   => COOKIE_DOMAIN,
					'secure'   => is_ssl(),
					'httponly' => true,
					'samesite' => 'Strict',
				] );
			}
		}
	}


	public function check2faOnAdminInit() {
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
			return;
		}

		$script_name = isset( $_SERVER['SCRIPT_NAME'] ) ? basename( $_SERVER['SCRIPT_NAME'] ) : '';
		if ( in_array( $script_name, array( 'admin-ajax.php', 'admin-post.php' ) ) ) {
			return;
		}

		$user_id = get_current_user_id();
		if ( ! $user_id ) {
			return;
		}

		if ( ! $this->is2faEnabledForTheUser( $user_id ) ) {
			return;
		}

		if ( $this->isDeviceRemembered( $user_id ) ) {
			$this->clearVerificationPending( $user_id );

			return;
		}

		if ( ! $this->is2faVerificationComplete( $user_id ) ) {
			if ( ! $this->isVerificationPending( $user_id ) ) {
				$this->markVerificationPending( $user_id );
			}

			wp_redirect( home_url( '?iron_security_2fa_verify=1' ) );
			exit;
		}
	}
}