<?php
/**
 * Authenticator Enrollment Flow.
 *
 * Handles forced enrollment for users who need to set up authenticator
 * before accessing the site. This runs after password verification
 * when user's role requires 2FA but they haven't enrolled yet.
 *
 * @package Polanger_Dashboard_Tools
 */

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

class PDT_Authenticator_Enrollment {

  /**
   * TOTP service.
   *
   * @var PDT_Authenticator_TOTP
   */
  private $totp;

  /**
   * Constructor.
   *
   * @param PDT_Authenticator_TOTP $totp TOTP service.
   */
  public function __construct( $totp ) {
    $this->totp = $totp;
  }

  /**
   * Check if enrollment flow should be triggered.
   * Called from provider when user is not enrolled.
   *
   * @param WP_User $user User object.
   * @param string  $token Session token.
   * @return void
   */
  public function start_enrollment_flow( $user, $token ) {
    global $pdt_settings_page;
    
    $expiry_minutes = 30;
    if ( $pdt_settings_page && method_exists( $pdt_settings_page, 'get_2fa_code_expiry' ) ) {
      $expiry_minutes = (int) $pdt_settings_page->get_2fa_code_expiry();
    }

    $pending_context = array(
      'user_id'    => $user->ID,
      'remember'   => isset( $_POST['rememberme'] ) && 'forever' === sanitize_text_field( wp_unslash( $_POST['rememberme'] ) ),
      'expires_at' => time() + ( $expiry_minutes * MINUTE_IN_SECONDS ),
      'created_at' => time(),
      'factor'     => 'totp_enrollment',
      'attempts'   => 0,
    );
    set_transient( 'pdt_2fa_pending_' . $token, $pending_context, $expiry_minutes * MINUTE_IN_SECONDS );

    wp_safe_redirect(
      add_query_arg(
        array(
          'action' => '2fa_enroll',
          'token'  => $token,
        ),
        wp_login_url()
      )
    );
    exit;
  }

  /**
   * Render the enrollment page.
   *
   * @return void
   */
  public function maybe_render_enrollment_page() {
    $action = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : '';
    if ( '2fa_enroll' !== $action ) {
      return;
    }

    $token = isset( $_GET['token'] ) ? sanitize_text_field( wp_unslash( $_GET['token'] ) ) : '';
    $pending = get_transient( 'pdt_2fa_pending_' . $token );
    
    // Allow both enrollment and enrollment_complete factors
    $valid_factors = array( 'totp_enrollment', 'totp_enrollment_complete' );
    if ( ! is_array( $pending ) || empty( $pending['user_id'] ) || ! in_array( $pending['factor'] ?? '', $valid_factors, true ) ) {
      wp_safe_redirect( wp_login_url() );
      exit;
    }

    $user = get_userdata( (int) $pending['user_id'] );
    if ( ! $user ) {
      delete_transient( 'pdt_2fa_pending_' . $token );
      wp_safe_redirect( wp_login_url() );
      exit;
    }

    $user_id = (int) $pending['user_id'];
    
    // Handle "I saved my keys" confirmation FIRST (before lockout check)
    if ( isset( $_POST['pdt_enrollment_complete'] ) && 'totp_enrollment_complete' === ( $pending['factor'] ?? '' ) ) {
      $nonce = isset( $_POST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ) : '';
      if ( wp_verify_nonce( $nonce, 'pdt_authenticator_enrollment_complete' ) ) {
        // Clear pending and log user in
        delete_transient( 'pdt_2fa_pending_' . $token );
        wp_set_auth_cookie( $user_id, ! empty( $pending['remember'] ) );
        wp_set_current_user( $user_id );
        wp_safe_redirect( admin_url() );
        exit;
      }
    }
    
    // Check lockout status
    $lockout_remaining = $this->get_lockout_remaining_seconds( $user_id );
    if ( $lockout_remaining > 0 ) {
      $remaining_minutes = max( 1, (int) ceil( $lockout_remaining / MINUTE_IN_SECONDS ) );
      wp_die(
        sprintf(
          /* translators: %d: Remaining lockout time in minutes. */
          esc_html__( 'Too many failed verification attempts. Please try again in %d minutes.', 'polanger-admin-menu-manager' ),
          $remaining_minutes
        ),
        esc_html__( 'Temporarily Locked', 'polanger-admin-menu-manager' ),
        array( 'response' => 403 )
      );
    }
    
    $secret = $this->totp->get_or_create_secret( $user_id );
    $provisioning_uri = $this->totp->get_provisioning_uri( $user_id );
    $error_message = '';
    $show_recovery_keys = false;
    $recovery_keys = array();

    // Handle form submission
    if ( isset( $_POST['pdt_enrollment_verify'] ) ) {
      $nonce = isset( $_POST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ) : '';
      if ( ! wp_verify_nonce( $nonce, 'pdt_authenticator_enrollment' ) ) {
        $error_message = __( 'Security check failed. Please try again.', 'polanger-admin-menu-manager' );
      } else {
        $submitted_code = isset( $_POST['enrollment_code'] ) ? sanitize_text_field( wp_unslash( $_POST['enrollment_code'] ) ) : '';
        
        if ( $this->totp->verify_code( $user_id, $submitted_code ) ) {
          // Mark user as enrolled
          $this->totp->mark_user_enrolled( $user_id );
          
          // Generate recovery keys
          global $pdt_two_factor;
          if ( $pdt_two_factor && method_exists( $pdt_two_factor, 'generate_recovery_keys' ) ) {
            $recovery_keys = $pdt_two_factor->generate_recovery_keys( $user_id );
            $show_recovery_keys = true;
          }
          
          // Update pending context to show recovery keys
          $pending['factor'] = 'totp_enrollment_complete';
          $pending['recovery_keys'] = $recovery_keys;
          set_transient( 'pdt_2fa_pending_' . $token, $pending, 10 * MINUTE_IN_SECONDS );
        } else {
          $pending['attempts'] = isset( $pending['attempts'] ) ? $pending['attempts'] + 1 : 1;
          set_transient( 'pdt_2fa_pending_' . $token, $pending, 10 * MINUTE_IN_SECONDS );
          
          // Check if max attempts reached
          global $pdt_settings_page;
          $max_attempts = $pdt_settings_page && method_exists( $pdt_settings_page, 'get_2fa_max_attempts' ) 
            ? (int) $pdt_settings_page->get_2fa_max_attempts() 
            : 3;
          
          if ( $pending['attempts'] >= $max_attempts ) {
            $this->set_lockout( $user_id );
            delete_transient( 'pdt_2fa_pending_' . $token );
            wp_safe_redirect( wp_login_url() . '?enrollment_locked=1' );
            exit;
          }
          
          $remaining = $max_attempts - $pending['attempts'];
          $error_message = sprintf(
            /* translators: %d: Remaining attempts. */
            __( 'Invalid code. %d attempts remaining.', 'polanger-admin-menu-manager' ),
            $remaining
          );
        }
      }
    }

    // Check if we're showing recovery keys (enrollment just completed)
    if ( 'totp_enrollment_complete' === ( $pending['factor'] ?? '' ) ) {
      $show_recovery_keys = true;
      $recovery_keys = $pending['recovery_keys'] ?? array();
    }

    // Enqueue styles
    wp_enqueue_style( 'dashicons' );
    wp_enqueue_style(
      'pdt-two-factor-verify',
      plugins_url( 'assets/css/two-factor-verify.css', PDT_PLUGIN_FILE ),
      array( 'dashicons' ),
      PDT_VERSION
    );

    $this->render_enrollment_html( $user, $token, $secret, $provisioning_uri, $error_message, $show_recovery_keys, $recovery_keys );
    exit;
  }

  /**
   * Get lockout remaining seconds.
   *
   * @param int $user_id User ID.
   * @return int
   */
  private function get_lockout_remaining_seconds( $user_id ) {
    global $pdt_settings_page;
    $lockout_started = get_transient( 'pdt_2fa_lockout_' . $user_id );
    if ( false === $lockout_started ) {
      return 0;
    }

    $minutes = $pdt_settings_page && method_exists( $pdt_settings_page, 'get_2fa_lockout_minutes' ) 
      ? (int) $pdt_settings_page->get_2fa_lockout_minutes() 
      : 30;
    $lockout_seconds = $minutes * MINUTE_IN_SECONDS;
    $elapsed = time() - absint( $lockout_started );

    return max( 0, $lockout_seconds - $elapsed );
  }

  /**
   * Set lockout for user.
   *
   * @param int $user_id User ID.
   * @return void
   */
  private function set_lockout( $user_id ) {
    global $pdt_settings_page;
    $minutes = $pdt_settings_page && method_exists( $pdt_settings_page, 'get_2fa_lockout_minutes' ) 
      ? (int) $pdt_settings_page->get_2fa_lockout_minutes() 
      : 30;
    set_transient( 'pdt_2fa_lockout_' . $user_id, time(), $minutes * MINUTE_IN_SECONDS );
  }

  /**
   * Render enrollment HTML.
   *
   * @param WP_User $user User object.
   * @param string  $token Session token.
   * @param string  $secret TOTP secret.
   * @param string  $provisioning_uri Provisioning URI.
   * @param string  $error_message Error message.
   * @param bool    $show_recovery_keys Whether to show recovery keys.
   * @param array   $recovery_keys Recovery keys array.
   * @return void
   */
  private function render_enrollment_html( $user, $token, $secret, $provisioning_uri, $error_message, $show_recovery_keys, $recovery_keys ) {
    ?>
    <!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 esc_html_e( 'Set Up Authenticator', 'polanger-admin-menu-manager' ); ?> - <?php bloginfo( 'name' ); ?></title>
      <?php wp_head(); ?>
      <style>
        .pdt-enrollment-container {
          max-width: 500px;
          margin: 40px auto;
          padding: 40px;
          background: #fff;
          border-radius: 12px;
          box-shadow: 0 4px 24px rgba(0,0,0,0.1);
        }
        .pdt-enrollment-header {
          text-align: center;
          margin-bottom: 30px;
        }
        .pdt-enrollment-icon {
          width: 64px;
          height: 64px;
          background: linear-gradient(135deg, #6366f1, #8b5cf6);
          border-radius: 16px;
          display: flex;
          align-items: center;
          justify-content: center;
          margin: 0 auto 16px;
        }
        .pdt-enrollment-icon .dashicons {
          font-size: 32px;
          width: 32px;
          height: 32px;
          color: #fff;
        }
        .pdt-enrollment-title {
          font-size: 24px;
          font-weight: 600;
          color: #1e293b;
          margin: 0 0 8px;
        }
        .pdt-enrollment-subtitle {
          color: #64748b;
          font-size: 14px;
          margin: 0;
        }
        .pdt-enrollment-notice {
          background: #fef3c7;
          border: 1px solid #fcd34d;
          border-radius: 8px;
          padding: 12px 16px;
          margin-bottom: 24px;
          display: flex;
          gap: 12px;
          align-items: flex-start;
        }
        .pdt-enrollment-notice .dashicons {
          color: #d97706;
          flex-shrink: 0;
        }
        .pdt-enrollment-notice p {
          margin: 0;
          font-size: 13px;
          color: #92400e;
        }
        .pdt-enrollment-step {
          margin-bottom: 24px;
        }
        .pdt-enrollment-step-header {
          display: flex;
          align-items: center;
          gap: 12px;
          margin-bottom: 12px;
        }
        .pdt-enrollment-step-number {
          width: 28px;
          height: 28px;
          background: #6366f1;
          color: #fff;
          border-radius: 50%;
          display: flex;
          align-items: center;
          justify-content: center;
          font-weight: 600;
          font-size: 14px;
        }
        .pdt-enrollment-step-title {
          font-weight: 600;
          color: #1e293b;
        }
        .pdt-secret-box {
          background: #f8fafc;
          border: 1px solid #e2e8f0;
          border-radius: 8px;
          padding: 16px;
          margin-bottom: 8px;
        }
        .pdt-secret-value {
          display: flex;
          align-items: center;
          gap: 12px;
        }
        .pdt-secret-value code {
          flex: 1;
          font-family: 'SF Mono', Monaco, monospace;
          font-size: 14px;
          letter-spacing: 2px;
          color: #1e293b;
          word-break: break-all;
        }
        .pdt-secret-copy {
          padding: 8px 12px;
          background: #fff;
          border: 1px solid #e2e8f0;
          border-radius: 6px;
          cursor: pointer;
          display: flex;
          align-items: center;
          gap: 6px;
          font-size: 13px;
          color: #64748b;
          transition: all 0.2s;
        }
        .pdt-secret-copy:hover {
          background: #f1f5f9;
          color: #1e293b;
        }
        .pdt-secret-help {
          font-size: 12px;
          color: #64748b;
          margin: 8px 0 0;
        }
        .pdt-enrollment-form {
          margin-top: 16px;
        }
        .pdt-code-input {
          width: 100%;
          padding: 14px 16px;
          font-size: 24px;
          letter-spacing: 8px;
          text-align: center;
          border: 2px solid #e2e8f0;
          border-radius: 8px;
          margin-bottom: 16px;
          transition: border-color 0.2s;
        }
        .pdt-code-input:focus {
          outline: none;
          border-color: #6366f1;
        }
        .pdt-enrollment-submit {
          width: 100%;
          padding: 14px;
          background: linear-gradient(135deg, #6366f1, #8b5cf6);
          color: #fff;
          border: none;
          border-radius: 8px;
          font-size: 16px;
          font-weight: 600;
          cursor: pointer;
          transition: transform 0.2s, box-shadow 0.2s;
        }
        .pdt-enrollment-submit:hover {
          transform: translateY(-1px);
          box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);
        }
        .pdt-enrollment-error {
          background: #fef2f2;
          border: 1px solid #fecaca;
          color: #dc2626;
          padding: 12px 16px;
          border-radius: 8px;
          margin-bottom: 16px;
          font-size: 14px;
        }
        .pdt-recovery-section {
          text-align: center;
        }
        .pdt-recovery-icon {
          width: 64px;
          height: 64px;
          background: linear-gradient(135deg, #10b981, #059669);
          border-radius: 16px;
          display: flex;
          align-items: center;
          justify-content: center;
          margin: 0 auto 16px;
        }
        .pdt-recovery-icon .dashicons {
          font-size: 32px;
          width: 32px;
          height: 32px;
          color: #fff;
        }
        .pdt-recovery-title {
          font-size: 20px;
          font-weight: 600;
          color: #1e293b;
          margin: 0 0 8px;
        }
        .pdt-recovery-warning {
          color: #64748b;
          font-size: 14px;
          margin-bottom: 20px;
        }
        .pdt-recovery-warning strong {
          color: #dc2626;
        }
        .pdt-recovery-keys {
          display: grid;
          grid-template-columns: repeat(2, 1fr);
          gap: 8px;
          margin-bottom: 20px;
        }
        .pdt-recovery-keys code {
          background: #f8fafc;
          border: 1px solid #e2e8f0;
          padding: 10px;
          border-radius: 6px;
          font-family: 'SF Mono', Monaco, monospace;
          font-size: 13px;
          letter-spacing: 1px;
        }
        .pdt-recovery-actions {
          display: flex;
          gap: 12px;
          justify-content: center;
        }
        .pdt-copy-keys {
          padding: 10px 20px;
          background: #fff;
          border: 1px solid #e2e8f0;
          border-radius: 8px;
          cursor: pointer;
          display: flex;
          align-items: center;
          gap: 8px;
          font-size: 14px;
          color: #1e293b;
        }
        .pdt-copy-keys:hover {
          background: #f8fafc;
        }
        .pdt-copy-keys .dashicons {
          color: #64748b;
        }
      </style>
    </head>
    <body style="background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); min-height: 100vh;">
      <div class="pdt-enrollment-container">
        <?php if ( $show_recovery_keys && ! empty( $recovery_keys ) ) : ?>
          <!-- Recovery Keys Screen -->
          <div class="pdt-recovery-section">
            <div class="pdt-recovery-icon">
              <span class="dashicons dashicons-yes-alt"></span>
            </div>
            <h1 class="pdt-recovery-title"><?php esc_html_e( 'Authenticator Setup Complete!', 'polanger-admin-menu-manager' ); ?></h1>
            <p class="pdt-recovery-warning">
              <?php esc_html_e( 'Save these recovery keys now. They can be used to access your account if you lose your phone.', 'polanger-admin-menu-manager' ); ?>
              <br><strong><?php esc_html_e( 'These keys will not be shown again!', 'polanger-admin-menu-manager' ); ?></strong>
            </p>
            
            <div class="pdt-recovery-keys">
              <?php foreach ( $recovery_keys as $key ) : ?>
                <code><?php echo esc_html( $key ); ?></code>
              <?php endforeach; ?>
            </div>
            
            <div class="pdt-recovery-actions">
              <button type="button" class="pdt-copy-keys" onclick="copyRecoveryKeys()">
                <span class="dashicons dashicons-clipboard"></span>
                <?php esc_html_e( 'Copy All', 'polanger-admin-menu-manager' ); ?>
              </button>
            </div>
            
            <form method="post" style="margin-top: 24px;">
              <?php wp_nonce_field( 'pdt_authenticator_enrollment_complete' ); ?>
              <input type="hidden" name="token" value="<?php echo esc_attr( $token ); ?>" />
              <button type="submit" name="pdt_enrollment_complete" class="pdt-enrollment-submit">
                <?php esc_html_e( 'I have saved my keys - Continue', 'polanger-admin-menu-manager' ); ?>
              </button>
            </form>
          </div>
          
          <script>
          function copyRecoveryKeys() {
            var keys = <?php echo wp_json_encode( implode( "\n", $recovery_keys ) ); ?>;
            navigator.clipboard.writeText(keys).then(function() {
              alert('<?php echo esc_js( __( 'Recovery keys copied to clipboard!', 'polanger-admin-menu-manager' ) ); ?>');
            });
          }
          </script>
        <?php else : ?>
          <!-- Setup Screen -->
          <div class="pdt-enrollment-header">
            <div class="pdt-enrollment-icon">
              <span class="dashicons dashicons-smartphone"></span>
            </div>
            <h1 class="pdt-enrollment-title"><?php esc_html_e( 'Set Up Authenticator', 'polanger-admin-menu-manager' ); ?></h1>
            <p class="pdt-enrollment-subtitle">
              <?php 
              printf(
                /* translators: %s: User display name */
                esc_html__( 'Welcome %s! Your account requires two-factor authentication.', 'polanger-admin-menu-manager' ),
                esc_html( $user->display_name )
              );
              ?>
            </p>
          </div>

          <div class="pdt-enrollment-notice">
            <span class="dashicons dashicons-info"></span>
            <p><?php esc_html_e( 'You must complete this setup before you can access the site. This only needs to be done once.', 'polanger-admin-menu-manager' ); ?></p>
          </div>

          <?php if ( ! empty( $error_message ) ) : ?>
            <div class="pdt-enrollment-error"><?php echo esc_html( $error_message ); ?></div>
          <?php endif; ?>

          <!-- Step 1: Add to App -->
          <div class="pdt-enrollment-step">
            <div class="pdt-enrollment-step-header">
              <div class="pdt-enrollment-step-number">1</div>
              <div class="pdt-enrollment-step-title"><?php esc_html_e( 'Add to Your Authenticator App', 'polanger-admin-menu-manager' ); ?></div>
            </div>
            <p style="color: #64748b; font-size: 14px; margin: 0 0 12px 40px;">
              <?php esc_html_e( 'Open Google Authenticator or Microsoft Authenticator and add a new account using this secret key:', 'polanger-admin-menu-manager' ); ?>
            </p>
            <div class="pdt-secret-box" style="margin-left: 40px;">
              <div class="pdt-secret-value">
                <code id="secret-key"><?php echo esc_html( $secret ); ?></code>
                <button type="button" class="pdt-secret-copy" onclick="copySecret()">
                  <span class="dashicons dashicons-clipboard"></span>
                  <?php esc_html_e( 'Copy', 'polanger-admin-menu-manager' ); ?>
                </button>
              </div>
              <p class="pdt-secret-help"><?php esc_html_e( 'Enter this key manually when adding a new account in your authenticator app.', 'polanger-admin-menu-manager' ); ?></p>
            </div>
          </div>

          <!-- Step 2: Verify -->
          <div class="pdt-enrollment-step">
            <div class="pdt-enrollment-step-header">
              <div class="pdt-enrollment-step-number">2</div>
              <div class="pdt-enrollment-step-title"><?php esc_html_e( 'Verify Setup', 'polanger-admin-menu-manager' ); ?></div>
            </div>
            <p style="color: #64748b; font-size: 14px; margin: 0 0 12px 40px;">
              <?php esc_html_e( 'Enter the 6-digit code from your authenticator app:', 'polanger-admin-menu-manager' ); ?>
            </p>
            <form method="post" class="pdt-enrollment-form" style="margin-left: 40px;">
              <?php wp_nonce_field( 'pdt_authenticator_enrollment' ); ?>
              <input type="hidden" name="token" value="<?php echo esc_attr( $token ); ?>" />
              <input 
                type="text" 
                name="enrollment_code" 
                class="pdt-code-input" 
                placeholder="000000"
                maxlength="6" 
                pattern="[0-9]{6}" 
                inputmode="numeric"
                autocomplete="one-time-code"
                autofocus
                required 
              />
              <button type="submit" name="pdt_enrollment_verify" class="pdt-enrollment-submit">
                <?php esc_html_e( 'Verify & Complete Setup', 'polanger-admin-menu-manager' ); ?>
              </button>
            </form>
          </div>

          <script>
          function copySecret() {
            var secret = document.getElementById('secret-key').textContent;
            navigator.clipboard.writeText(secret).then(function() {
              alert('<?php echo esc_js( __( 'Secret key copied!', 'polanger-admin-menu-manager' ) ); ?>');
            });
          }
          </script>
        <?php endif; ?>
      </div>
      <?php wp_footer(); ?>
    </body>
    </html>
    <?php
  }
}
