# OTP Integration - Code Reference

## Quick Code Snippets

### 1. Load .env File (Add to top of includes/mailer.php)

```php
<?php
// Load environment variables from .env file
if (file_exists(__DIR__ . '/../.env')) {
    $env = parse_ini_file(__DIR__ . '/../.env');
    foreach ($env as $key => $value) {
        putenv("$key=$value");
    }
}
```

### 2. Using Environment Variables in PHPMailer

```php
$this->mail->Username = getenv('SMTP_USERNAME') ?: 'default@example.com';
$this->mail->Password = getenv('SMTP_PASSWORD') ?: 'default-password';
$this->mail->setFrom(getenv('SMTP_FROM') ?: 'noreply@example.com', 'Company Name');
```

### 3. Real-Time OTP Input Validation (JavaScript)

```javascript
const otpInput = document.getElementById('otp_code');

otpInput.addEventListener('input', function(e) {
    // Remove non-numeric characters
    this.value = this.value.replace(/[^0-9]/g, '');
    
    // Auto-submit when 6 digits entered
    if (this.value.length === 6) {
        setTimeout(() => {
            verifyOTP({ preventDefault: () => {} });
        }, 300);
    }
});

// Smart paste handling
otpInput.addEventListener('paste', function(e) {
    e.preventDefault();
    const pastedText = (e.clipboardData || window.clipboardData).getData('text');
    const numericOnly = pastedText.replace(/[^0-9]/g, '').slice(0, 6);
    this.value = numericOnly;
    
    const inputEvent = new Event('input', { bubbles: true });
    this.dispatchEvent(inputEvent);
});
```

### 4. Error Handling for Fatal PHP Errors

```php
<?php
header('Content-Type: application/json; charset=utf-8');
error_reporting(E_ALL);
ini_set('display_errors', 0);

// Catch fatal errors
register_shutdown_function(function() {
    if (connection_status() == CONNECTION_ABORTED) {
        return;
    }
    
    $error = error_get_last();
    if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        http_response_code(500);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['status' => 'error', 'message' => 'Server error: ' . $error['message']]);
        exit;
    }
});
```

### 5. OTP Sending with Retry Logic

```php
$otp_sent = false;
$email_error = '';

try {
    require_once "../includes/mailer.php";
    $mailer = new MailerService();
    
    // Retry mechanism
    $max_retries = 2;
    $retry_count = 0;
    
    while ($retry_count < $max_retries && !$otp_sent) {
        try {
            $otp_sent = $mailer->sendOTP($email, $otp, $full_name);
            if ($otp_sent) break;
        } catch (Exception $e) {
            error_log("OTP Send Attempt " . ($retry_count + 1) . " Error: " . $e->getMessage());
            $email_error = $e->getMessage();
        }
        $retry_count++;
        
        if (!$otp_sent && $retry_count < $max_retries) {
            usleep(500000); // 500ms delay
        }
    }
} catch (Exception $e) {
    error_log("Mailer service initialization error: " . $e->getMessage());
    $email_error = $e->getMessage();
    $otp_sent = false;
}

// Fallback to PHP mail()
if (!$otp_sent) {
    error_log("Falling back to PHP mail(). PHPMailer error: " . $email_error);
    
    $subject = "PowerZone OTP Verification - " . date('Y-m-d H:i:s');
    $message = "Your OTP is: $otp\n\n";
    $message .= "Valid for 10 minutes.\n\n";
    $message .= "Do not share this with anyone.\n\n";
    $message .= "Thank you,\nPowerZone Fitness Team";
    
    $headers = "From: noreply@powerzone.com\r\n";
    $headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
    
    try {
        $otp_sent = @mail($email, $subject, $message, $headers);
        if (!$otp_sent) {
            error_log("PHP mail() function failed for email: " . $email);
        }
    } catch (Exception $e) {
        error_log("PHP mail() exception: " . $e->getMessage());
        $otp_sent = false;
    }
}
```

### 6. Better Fetch Error Handling (JavaScript)

```javascript
fetch('auth/otp.php', {
    method: 'POST',
    body: formData
})
.then(res => {
    if (!res.ok) {
        throw new Error('HTTP Error ' + res.status);
    }
    return res.json();
})
.then(response => {
    if (response.status === 'success') {
        // Handle success
    } else {
        Swal.fire('Error', response.message || 'Failed to process', 'error');
    }
})
.catch(err => {
    console.error('Error:', err);
    Swal.fire(
        'Error',
        'Network error. Please check your connection and try again. Error: ' + err.message,
        'error'
    );
});
```

### 7. Database Query for OTP Testing

```sql
-- Check recent OTP records
SELECT id, email, otp, verified, attempts, 
       expires_at, created_at
FROM otp_verification 
WHERE email = 'test@example.com'
ORDER BY created_at DESC LIMIT 5;

-- Check OTP expiry status
SELECT email, otp, 
       CASE 
           WHEN expires_at > NOW() THEN 'VALID'
           ELSE 'EXPIRED'
       END as status,
       TIMESTAMPDIFF(SECOND, NOW(), expires_at) as seconds_remaining
FROM otp_verification 
WHERE verified = 0
ORDER BY created_at DESC;

-- Reset for testing
DELETE FROM otp_verification WHERE email = 'test@example.com';
```

### 8. Test SMTP Connection (CLI)

```bash
php -r "
require 'includes/vendor/autoload.php';
\$mail = new PHPMailer\PHPMailer\PHPMailer(true);
\$mail->isSMTP();
\$mail->Host = getenv('SMTP_HOST');
\$mail->SMTPAuth = true;
\$mail->Username = getenv('SMTP_USERNAME');
\$mail->Password = getenv('SMTP_PASSWORD');
\$mail->SMTPSecure = 'tls';
\$mail->Port = 587;
\$mail->SMTPDebug = 3;
try {
    \$mail->smtpConnect();
    echo 'SMTP connection successful!' . PHP_EOL;
} catch (Exception \$e) {
    echo 'Error: ' . \$e->getMessage();
}
"
```

### 9. .gitignore Entry

```
# Environment variables
.env
.env.local
.env.*.local

# Logs
*.log

# IDE
.vscode/
.idea/
*.swp
*.swo

# Vendor
vendor/
composer.lock
```

### 10. Configuration Helper Function (Optional)

```php
<?php
class Config {
    private static $config = [];
    
    public static function init() {
        if (file_exists(__DIR__ . '/../.env')) {
            self::$config = parse_ini_file(__DIR__ . '/../.env');
        }
    }
    
    public static function get($key, $default = null) {
        return self::$config[$key] ?? getenv($key) ?: $default;
    }
    
    public static function set($key, $value) {
        self::$config[$key] = $value;
        putenv("$key=$value");
    }
}

Config::init();

// Usage:
$smtpHost = Config::get('SMTP_HOST', 'smtp.gmail.com');
```

---

## Common Integration Points

### In mailer.php
```php
require_once 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

class MailerService {
    private $mail;

    public function __construct() {
        $this->mail = new PHPMailer(true);
        // ... SMTP configuration using getenv()
    }

    public function sendOTP($email, $otp, $name) {
        // ... HTML email template
        // ... Send logic with error handling
    }
}
```

### In auth/otp.php
```php
// 1. Load database
include "../includes/db.php";

// 2. Handle send_otp action
if ($_POST['action'] === 'send_otp') {
    // Validate input
    // Generate OTP
    // Store in database
    // Send email with retry logic
    // Return JSON response
}

// 3. Handle verify_otp action
if ($_POST['action'] === 'verify_otp') {
    // Validate email and OTP
    // Check expiry
    // Check attempts
    // Create user if valid
    // Return JSON response
}
```

### In header.html
```javascript
// 1. sendOTP() function
// - Validate form
// - Fetch to auth/otp.php with send_otp action
// - Handle success/error responses
// - Show OTP verification form

// 2. verifyOTP() function  
// - Fetch to auth/otp.php with verify_otp action
// - Handle success/error
// - Redirect on success

// 3. Real-time input validation
// - Auto-format numeric input
// - Auto-submit on 6 digits
// - Smart paste handling
```

---

**All code is production-ready. Test thoroughly before deployment.**
