<?php
/**
 * Authenticator Profile Section.
 *
 * Adds 2FA management section to user profile page.
 * Each user can manage their own authenticator setup here.
 *
 * @package Polanger_Dashboard_Tools
 */

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

class PDT_Authenticator_Profile {

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

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

  /**
   * Register hooks.
   *
   * @return void
   */
  public function init() {
    add_action( 'show_user_profile', array( $this, 'render_profile_section' ) );
    add_action( 'edit_user_profile', array( $this, 'render_profile_section' ) );
    add_action( 'personal_options_update', array( $this, 'handle_profile_update' ) );
    add_action( 'edit_user_profile_update', array( $this, 'handle_profile_update' ) );
    add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_profile_assets' ) );
  }

  /**
   * Check if authenticator 2FA is available.
   *
   * @return bool
   */
  private function is_authenticator_available() {
    global $pdt_settings_page;
    
    if ( ! $pdt_settings_page || ! method_exists( $pdt_settings_page, 'get_settings' ) ) {
      return false;
    }
    
    $settings = $pdt_settings_page->get_settings();
    
    // Check if 2FA is enabled and authenticator method is selected
    if ( empty( $settings['two_factor_enabled'] ) ) {
      return false;
    }
    
    $method = isset( $settings['two_factor_method'] ) ? $settings['two_factor_method'] : 'email';
    return 'authenticator' === $method;
  }

  /**
   * Check if user's role requires 2FA.
   *
   * @param int $user_id User ID.
   * @return bool
   */
  private function user_requires_2fa( $user_id ) {
    global $pdt_settings_page;
    
    if ( ! $pdt_settings_page || ! method_exists( $pdt_settings_page, 'get_settings' ) ) {
      return false;
    }
    
    $settings = $pdt_settings_page->get_settings();
    $user = get_userdata( $user_id );
    
    if ( ! $user || empty( $settings['two_factor_enabled'] ) ) {
      return false;
    }
    
    $required_roles = isset( $settings['two_factor_roles'] ) ? $settings['two_factor_roles'] : array();
    return ! empty( array_intersect( $user->roles, $required_roles ) );
  }

  /**
   * Enqueue profile page assets.
   *
   * @param string $hook Current admin page.
   * @return void
   */
  public function enqueue_profile_assets( $hook ) {
    if ( ! in_array( $hook, array( 'profile.php', 'user-edit.php' ), true ) ) {
      return;
    }

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

    wp_enqueue_style( 'dashicons' );
    
    $inline_css = '
      .pdt-profile-2fa {
        background: #fff;
        border: 1px solid #c3c4c7;
        border-radius: 4px;
        padding: 20px;
        margin: 20px 0;
      }
      .pdt-profile-2fa h2 {
        display: flex;
        align-items: center;
        gap: 8px;
        margin: 0 0 16px;
        padding: 0;
        font-size: 16px;
      }
      .pdt-profile-2fa h2 .dashicons {
        color: #6366f1;
      }
      .pdt-2fa-status {
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 16px;
        border-radius: 6px;
        margin-bottom: 16px;
      }
      .pdt-2fa-status.enrolled {
        background: #ecfdf5;
        border: 1px solid #a7f3d0;
      }
      .pdt-2fa-status.not-enrolled {
        background: #fef3c7;
        border: 1px solid #fcd34d;
      }
      .pdt-2fa-status .dashicons {
        font-size: 24px;
        width: 24px;
        height: 24px;
      }
      .pdt-2fa-status.enrolled .dashicons {
        color: #059669;
      }
      .pdt-2fa-status.not-enrolled .dashicons {
        color: #d97706;
      }
      .pdt-2fa-status-text strong {
        display: block;
        color: #1e293b;
        margin-bottom: 2px;
      }
      .pdt-2fa-status-text span {
        font-size: 13px;
        color: #64748b;
      }
      .pdt-2fa-setup-box {
        background: #f8fafc;
        border: 1px solid #e2e8f0;
        border-radius: 6px;
        padding: 16px;
        margin-bottom: 16px;
      }
      .pdt-2fa-setup-box h3 {
        margin: 0 0 12px;
        font-size: 14px;
        color: #1e293b;
      }
      .pdt-2fa-secret {
        display: flex;
        align-items: center;
        gap: 12px;
        background: #fff;
        border: 1px solid #e2e8f0;
        padding: 12px;
        border-radius: 4px;
        margin-bottom: 12px;
      }
      .pdt-2fa-secret code {
        flex: 1;
        font-family: monospace;
        font-size: 14px;
        letter-spacing: 2px;
        color: #1e293b;
      }
      .pdt-2fa-verify-form {
        display: flex;
        gap: 12px;
        align-items: flex-end;
      }
      .pdt-2fa-verify-form .form-field {
        flex: 1;
      }
      .pdt-2fa-verify-form label {
        display: block;
        font-size: 13px;
        color: #64748b;
        margin-bottom: 4px;
      }
      .pdt-2fa-verify-form input[type="text"] {
        width: 100%;
        padding: 8px 12px;
        font-size: 16px;
        letter-spacing: 4px;
        text-align: center;
      }
      .pdt-2fa-actions {
        display: flex;
        gap: 12px;
        flex-wrap: wrap;
      }
      .pdt-2fa-recovery-info {
        background: #f1f5f9;
        padding: 12px;
        border-radius: 4px;
        margin-top: 16px;
      }
      .pdt-2fa-recovery-info p {
        margin: 0;
        font-size: 13px;
        color: #64748b;
      }
      .pdt-2fa-recovery-info strong {
        color: #1e293b;
      }
      .pdt-profile-notice {
        padding: 12px 16px;
        border-radius: 4px;
        margin-bottom: 16px;
      }
      .pdt-profile-notice.success {
        background: #ecfdf5;
        border: 1px solid #a7f3d0;
        color: #065f46;
      }
      .pdt-profile-notice.error {
        background: #fef2f2;
        border: 1px solid #fecaca;
        color: #dc2626;
      }
    ';
    
    wp_add_inline_style( 'dashicons', $inline_css );
  }

  /**
   * Render 2FA section on profile page.
   *
   * @param WP_User $user User being edited.
   * @return void
   */
  public function render_profile_section( $user ) {
    if ( ! $this->is_authenticator_available() ) {
      return;
    }

    // Check if current user can view this (only own profile or admin)
    $current_user_id = get_current_user_id();
    $is_own_profile = ( $current_user_id === $user->ID );
    $is_admin = current_user_can( 'manage_options' );

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

    $is_enrolled = $this->totp->is_user_enrolled( $user->ID );
    $requires_2fa = $this->user_requires_2fa( $user->ID );
    
    // Get recovery keys count
    global $pdt_two_factor;
    $recovery_count = 0;
    if ( $pdt_two_factor && method_exists( $pdt_two_factor, 'get_recovery_keys_count' ) ) {
      $recovery_count = $pdt_two_factor->get_recovery_keys_count( $user->ID );
    }

    // Check for status messages
    $status_message = '';
    $status_type = '';
    if ( isset( $_GET['pdt_2fa_status'] ) ) {
      $status = sanitize_text_field( wp_unslash( $_GET['pdt_2fa_status'] ) );
      switch ( $status ) {
        case 'enrolled':
          $status_message = __( 'Authenticator setup complete!', 'polanger-admin-menu-manager' );
          $status_type = 'success';
          break;
        case 'disabled':
          $status_message = __( 'Authenticator has been disabled.', 'polanger-admin-menu-manager' );
          $status_type = 'success';
          break;
        case 'invalid_code':
          $status_message = __( 'Invalid verification code. Please try again.', 'polanger-admin-menu-manager' );
          $status_type = 'error';
          break;
        case 'pending_setup':
          $status_message = __( 'New secret generated. Verify it below to activate. Your old authenticator will continue working until you verify the new one.', 'polanger-admin-menu-manager' );
          $status_type = 'success';
          break;
        case 'pending_verified':
          $status_message = __( 'New secret activated successfully! New recovery keys have been generated.', 'polanger-admin-menu-manager' );
          $status_type = 'success';
          break;
        case 'pending_cancelled':
          $status_message = __( 'Secret rotation cancelled. Your existing authenticator remains active.', 'polanger-admin-menu-manager' );
          $status_type = 'success';
          break;
        case 'invalid_pending_code':
          $status_message = __( 'Invalid code for new secret. Please check your authenticator app and try again.', 'polanger-admin-menu-manager' );
          $status_type = 'error';
          break;
      }
    }
    ?>
    <div class="pdt-profile-2fa">
      <h2>
        <span class="dashicons dashicons-smartphone"></span>
        <?php esc_html_e( 'Two-Factor Authentication (Authenticator App)', 'polanger-admin-menu-manager' ); ?>
      </h2>

      <?php if ( ! empty( $status_message ) ) : ?>
        <div class="pdt-profile-notice <?php echo esc_attr( $status_type ); ?>">
          <?php echo esc_html( $status_message ); ?>
        </div>
      <?php endif; ?>

      <?php if ( ! $is_own_profile && $is_admin ) : ?>
        <!-- Admin viewing another user's profile - show status only -->
        <div class="pdt-2fa-status <?php echo $is_enrolled ? 'enrolled' : 'not-enrolled'; ?>">
          <span class="dashicons <?php echo $is_enrolled ? 'dashicons-yes-alt' : 'dashicons-warning'; ?>"></span>
          <div class="pdt-2fa-status-text">
            <?php if ( $is_enrolled ) : ?>
              <strong><?php esc_html_e( 'Authenticator Active', 'polanger-admin-menu-manager' ); ?></strong>
              <span><?php esc_html_e( 'This user has set up their authenticator app.', 'polanger-admin-menu-manager' ); ?></span>
            <?php else : ?>
              <strong><?php esc_html_e( 'Not Configured', 'polanger-admin-menu-manager' ); ?></strong>
              <span>
                <?php 
                if ( $requires_2fa ) {
                  esc_html_e( 'This user needs to set up their authenticator on next login.', 'polanger-admin-menu-manager' );
                } else {
                  esc_html_e( 'This user has not configured authenticator.', 'polanger-admin-menu-manager' );
                }
                ?>
              </span>
            <?php endif; ?>
          </div>
        </div>

        <?php if ( $is_enrolled && $recovery_count > 0 ) : ?>
          <div class="pdt-2fa-recovery-info">
            <p>
              <strong><?php esc_html_e( 'Recovery Keys:', 'polanger-admin-menu-manager' ); ?></strong>
              <?php
              printf(
                /* translators: %d: Number of remaining recovery keys */
                esc_html__( '%d keys remaining', 'polanger-admin-menu-manager' ),
                $recovery_count
              );
              ?>
            </p>
          </div>
        <?php endif; ?>

      <?php else : ?>
        <!-- User's own profile - full management -->
        
        <div class="pdt-2fa-status <?php echo $is_enrolled ? 'enrolled' : 'not-enrolled'; ?>">
          <span class="dashicons <?php echo $is_enrolled ? 'dashicons-yes-alt' : 'dashicons-warning'; ?>"></span>
          <div class="pdt-2fa-status-text">
            <?php if ( $is_enrolled ) : ?>
              <strong><?php esc_html_e( 'Authenticator Active', 'polanger-admin-menu-manager' ); ?></strong>
              <span><?php esc_html_e( 'Your authenticator app is configured and ready.', 'polanger-admin-menu-manager' ); ?></span>
            <?php else : ?>
              <strong><?php esc_html_e( 'Setup Required', 'polanger-admin-menu-manager' ); ?></strong>
              <span>
                <?php 
                if ( $requires_2fa ) {
                  esc_html_e( 'Your role requires 2FA. Complete the setup below.', 'polanger-admin-menu-manager' );
                } else {
                  esc_html_e( 'Enhance your account security by setting up authenticator.', 'polanger-admin-menu-manager' );
                }
                ?>
              </span>
            <?php endif; ?>
          </div>
        </div>

        <?php if ( ! $is_enrolled ) : ?>
          <!-- Setup Form -->
          <?php
          $secret = $this->totp->get_or_create_secret( $user->ID );
          ?>
          <div class="pdt-2fa-setup-box">
            <h3><?php esc_html_e( 'Step 1: Add to Your Authenticator App', 'polanger-admin-menu-manager' ); ?></h3>
            <p style="margin: 0 0 12px; color: #64748b; font-size: 13px;">
              <?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-2fa-secret">
              <code id="pdt-profile-secret"><?php echo esc_html( $secret ); ?></code>
              <button type="button" class="button" onclick="navigator.clipboard.writeText(document.getElementById('pdt-profile-secret').textContent).then(function(){alert('<?php echo esc_js( __( 'Copied!', 'polanger-admin-menu-manager' ) ); ?>')})">
                <?php esc_html_e( 'Copy', 'polanger-admin-menu-manager' ); ?>
              </button>
            </div>
            
            <h3><?php esc_html_e( 'Step 2: Verify Setup', 'polanger-admin-menu-manager' ); ?></h3>
            <div class="pdt-2fa-verify-form">
              <div class="form-field">
                <label for="pdt_profile_verify_code"><?php esc_html_e( 'Enter 6-digit code from your app', 'polanger-admin-menu-manager' ); ?></label>
                <input type="text" id="pdt_profile_verify_code" name="pdt_profile_verify_code" maxlength="6" pattern="[0-9]{6}" inputmode="numeric" placeholder="000000" />
              </div>
              <button type="submit" name="pdt_profile_verify_authenticator" class="button button-primary">
                <?php esc_html_e( 'Verify & Activate', 'polanger-admin-menu-manager' ); ?>
              </button>
            </div>
          </div>
        <?php else : ?>
          <?php 
          $has_pending = $this->totp->has_pending_secret( $user->ID );
          ?>
          
          <?php if ( $has_pending ) : ?>
            <!-- Pending Secret Verification -->
            <?php $pending_secret = $this->totp->get_pending_secret( $user->ID ); ?>
            <div class="pdt-2fa-setup-box" style="border-color: #fcd34d; background: #fffbeb;">
              <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 12px;">
                <span class="dashicons dashicons-warning" style="color: #d97706;"></span>
                <strong style="color: #92400e;"><?php esc_html_e( 'Pending Secret Rotation', 'polanger-admin-menu-manager' ); ?></strong>
              </div>
              <p style="margin: 0 0 12px; color: #78350f; font-size: 13px;">
                <?php esc_html_e( 'A new secret is waiting to be verified. Your old authenticator will continue working until you verify the new one.', 'polanger-admin-menu-manager' ); ?>
              </p>
              
              <h3><?php esc_html_e( 'New Secret Key', 'polanger-admin-menu-manager' ); ?></h3>
              <div class="pdt-2fa-secret">
                <code id="pdt-pending-secret"><?php echo esc_html( $pending_secret ); ?></code>
                <button type="button" class="button" onclick="navigator.clipboard.writeText(document.getElementById('pdt-pending-secret').textContent).then(function(){alert('<?php echo esc_js( __( 'Copied!', 'polanger-admin-menu-manager' ) ); ?>')})">
                  <?php esc_html_e( 'Copy', 'polanger-admin-menu-manager' ); ?>
                </button>
              </div>
              
              <h3><?php esc_html_e( 'Verify New Secret', 'polanger-admin-menu-manager' ); ?></h3>
              <p style="margin: 0 0 8px; color: #64748b; font-size: 13px;">
                <?php esc_html_e( 'Add the new secret to your authenticator app and enter the code to activate it:', 'polanger-admin-menu-manager' ); ?>
              </p>
              <div class="pdt-2fa-verify-form">
                <div class="form-field">
                  <input type="text" id="pdt_pending_verify_code" name="pdt_pending_verify_code" maxlength="6" pattern="[0-9]{6}" inputmode="numeric" placeholder="000000" />
                </div>
                <button type="submit" name="pdt_profile_verify_pending" class="button button-primary">
                  <?php esc_html_e( 'Verify & Activate', 'polanger-admin-menu-manager' ); ?>
                </button>
                <button type="submit" name="pdt_profile_cancel_pending" class="button">
                  <?php esc_html_e( 'Cancel', 'polanger-admin-menu-manager' ); ?>
                </button>
              </div>
            </div>
          <?php else : ?>
            <!-- Management Actions -->
            <div class="pdt-2fa-actions">
              <button type="submit" name="pdt_profile_regenerate_secret" class="button">
                <?php esc_html_e( 'Generate New Secret', 'polanger-admin-menu-manager' ); ?>
              </button>
              <button type="submit" name="pdt_profile_disable_authenticator" class="button" onclick="return confirm('<?php echo esc_js( __( 'Are you sure you want to disable authenticator?', 'polanger-admin-menu-manager' ) ); ?>')">
                <?php esc_html_e( 'Disable Authenticator', 'polanger-admin-menu-manager' ); ?>
              </button>
            </div>
          <?php endif; ?>

          <?php if ( $recovery_count > 0 ) : ?>
            <div class="pdt-2fa-recovery-info">
              <p>
                <strong><?php esc_html_e( 'Recovery Keys:', 'polanger-admin-menu-manager' ); ?></strong>
                <?php
                printf(
                  /* translators: %d: Number of remaining recovery keys */
                  esc_html__( '%d keys remaining. These can be used if you lose access to your authenticator app.', 'polanger-admin-menu-manager' ),
                  $recovery_count
                );
                ?>
              </p>
            </div>
          <?php endif; ?>
        <?php endif; ?>
      <?php endif; ?>

      <?php wp_nonce_field( 'pdt_profile_2fa_action', 'pdt_profile_2fa_nonce' ); ?>
    </div>
    <?php
  }

  /**
   * Handle profile form submission.
   *
   * @param int $user_id User ID being updated.
   * @return void
   */
  public function handle_profile_update( $user_id ) {
    // Verify nonce
    if ( ! isset( $_POST['pdt_profile_2fa_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pdt_profile_2fa_nonce'] ) ), 'pdt_profile_2fa_action' ) ) {
      return;
    }

    // Check permissions - user can only edit own profile, or admin can edit others
    $current_user_id = get_current_user_id();
    if ( $current_user_id !== $user_id && ! current_user_can( 'manage_options' ) ) {
      return;
    }

    // Only allow users to manage their own authenticator
    if ( $current_user_id !== $user_id ) {
      return;
    }

    $redirect_args = array();

    // Handle verify & activate (initial setup)
    if ( isset( $_POST['pdt_profile_verify_authenticator'] ) ) {
      $code = isset( $_POST['pdt_profile_verify_code'] ) ? sanitize_text_field( wp_unslash( $_POST['pdt_profile_verify_code'] ) ) : '';
      
      if ( $this->totp->verify_code( $user_id, $code ) ) {
        $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 );
          set_transient( 'pdt_show_recovery_keys_' . $user_id, $recovery_keys, 60 );
        }
        
        $redirect_args['pdt_2fa_status'] = 'enrolled';
      } else {
        $redirect_args['pdt_2fa_status'] = 'invalid_code';
      }
    }

    // Handle generate new secret (creates pending, doesn't touch active)
    if ( isset( $_POST['pdt_profile_regenerate_secret'] ) ) {
      $this->totp->create_pending_secret( $user_id );
      $redirect_args['pdt_2fa_status'] = 'pending_setup';
    }

    // Handle verify pending secret
    if ( isset( $_POST['pdt_profile_verify_pending'] ) ) {
      $code = isset( $_POST['pdt_pending_verify_code'] ) ? sanitize_text_field( wp_unslash( $_POST['pdt_pending_verify_code'] ) ) : '';
      
      if ( $this->totp->verify_pending_code( $user_id, $code ) ) {
        // Activate pending secret
        $this->totp->activate_pending_secret( $user_id );
        
        // Generate new recovery keys (security context changed)
        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 );
          set_transient( 'pdt_show_recovery_keys_' . $user_id, $recovery_keys, 60 );
        }
        
        $redirect_args['pdt_2fa_status'] = 'pending_verified';
      } else {
        $redirect_args['pdt_2fa_status'] = 'invalid_pending_code';
      }
    }

    // Handle cancel pending secret
    if ( isset( $_POST['pdt_profile_cancel_pending'] ) ) {
      $this->totp->cancel_pending_secret( $user_id );
      $redirect_args['pdt_2fa_status'] = 'pending_cancelled';
    }

    // Handle disable authenticator
    if ( isset( $_POST['pdt_profile_disable_authenticator'] ) ) {
      $this->totp->disable_for_user( $user_id );
      // Also clear any pending secrets
      $this->totp->cancel_pending_secret( $user_id );
      $redirect_args['pdt_2fa_status'] = 'disabled';
    }

    // Redirect with status
    if ( ! empty( $redirect_args ) ) {
      $redirect_url = add_query_arg( $redirect_args, admin_url( 'profile.php' ) );
      wp_safe_redirect( $redirect_url );
      exit;
    }
  }
}
