<?php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

// Security headers
header("X-Frame-Options: DENY");
header("X-Content-Type-Options: nosniff");
header("Referrer-Policy: strict-origin-when-cross-origin");
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:");

require_once './includes/config.php';
require_once './includes/auth_functions.php';

// Check if user is logged in
if (!isset($_SESSION['user_id'])) {
    header("Location: login.php");
    exit;
}

// Rate limiting for 2FA changes
if (!isset($_SESSION['2fa_attempts'])) {
    $_SESSION['2fa_attempts'] = 0;
    $_SESSION['last_2fa_attempt'] = 0;
}

// Check rate limits
if ($_SESSION['2fa_attempts'] > 3 && (time() - $_SESSION['last_2fa_attempt'] < 300)) {
    die("Too many attempts. Please try again later.");
}

// Get current 2FA settings and user email
$stmt = $pdo->prepare("
    SELECT u.email, u2.* 
    FROM users u
    LEFT JOIN user_2fa_settings u2 ON u.id = u2.user_id
    WHERE u.id = ?
");
$stmt->execute([$_SESSION['user_id']]);
$userData = $stmt->fetch();

// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // CSRF validation
    if (empty($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
        logSecurityEvent($_SESSION['user_id'], 'csrf_failure', '2fa_settings');
        die("Invalid request. Please try again.");
    }
    
    if (isset($_POST['enable_2fa'])) {
        try {
            // Generate backup codes (10 codes, each 12 characters)
            $backupCodes = [];
            for ($i = 0; $i < 10; $i++) {
                $backupCodes[] = bin2hex(random_bytes(6)); // 12-character codes
            }
            
            // Hash the backup codes before storage
            $hashedCodes = [];
            foreach ($backupCodes as $code) {
                $hashedCodes[] = password_hash($code, PASSWORD_DEFAULT);
            }
            
            // Save 2FA settings with additional security metadata
            $stmt = $pdo->prepare("
                INSERT INTO user_2fa_settings 
                (user_id, method, email_verified, backup_codes, enabled_at, last_used_backup_code)
                VALUES (?, 'email', TRUE, ?, NOW(), NULL)
                ON DUPLICATE KEY UPDATE 
                    method = VALUES(method),
                    email_verified = VALUES(email_verified),
                    backup_codes = VALUES(backup_codes),
                    enabled_at = VALUES(enabled_at),
                    last_used_backup_code = VALUES(last_used_backup_code)
            ");
            
            $stmt->execute([
                $_SESSION['user_id'],
                json_encode($hashedCodes)
            ]);
            
            // Log the 2FA enable event
            logSecurityEvent($_SESSION['user_id'], '2fa_enabled', [
                'method' => 'email',
                'ip' => $_SERVER['REMOTE_ADDR']
            ]);
            
            // Show backup codes to user (only once)
            $_SESSION['backup_codes'] = $backupCodes;
            $_SESSION['backup_codes_shown'] = true;
            
            header("Location: settings_2fa.php?2fa=enabled");
            exit;
        } catch (Exception $e) {
            error_log("2FA enable error: " . $e->getMessage());
            $error = "An error occurred while enabling 2FA. Please try again.";
        }
    }
    elseif (isset($_POST['disable_2fa'])) {
        try {
            // Verify current password
            $stmt = $pdo->prepare("SELECT password FROM users WHERE id = ?");
            $stmt->execute([$_SESSION['user_id']]);
            $user = $stmt->fetch();
            
            if ($user && password_verify($_POST['current_password'], $user['password'])) {
                // Disable 2FA
                $stmt = $pdo->prepare("DELETE FROM user_2fa_settings WHERE user_id = ?");
                $stmt->execute([$_SESSION['user_id']]);
                
                // Log the 2FA disable event
                logSecurityEvent($_SESSION['user_id'], '2fa_disabled', [
                    'ip' => $_SERVER['REMOTE_ADDR']
                ]);
                
                header("Location: settings_2fa.php?2fa=disabled");
                exit;
            } else {
                $_SESSION['2fa_attempts']++;
                $_SESSION['last_2fa_attempt'] = time();
                $error = "Incorrect password. 2FA remains enabled.";
                
                // Log failed attempt
                logSecurityEvent($_SESSION['user_id'], '2fa_disable_failed', [
                    'reason' => 'incorrect_password',
                    'ip' => $_SERVER['REMOTE_ADDR']
                ]);
            }
        } catch (Exception $e) {
            error_log("2FA disable error: " . $e->getMessage());
            $error = "An error occurred while disabling 2FA. Please try again.";
        }
    }
    elseif (isset($_POST['regenerate_backup_codes'])) {
        try {
            // Verify current password
            $stmt = $pdo->prepare("SELECT password FROM users WHERE id = ?");
            $stmt->execute([$_SESSION['user_id']]);
            $user = $stmt->fetch();
            
            if ($user && password_verify($_POST['current_password'], $user['password'])) {
                // Generate new backup codes
                $backupCodes = [];
                for ($i = 0; $i < 10; $i++) {
                    $backupCodes[] = bin2hex(random_bytes(6)); // 12-character codes
                }
                
                // Hash the new backup codes
                $hashedCodes = [];
                foreach ($backupCodes as $code) {
                    $hashedCodes[] = password_hash($code, PASSWORD_DEFAULT);
                }
                
                // Update backup codes
                $stmt = $pdo->prepare("
                    UPDATE user_2fa_settings 
                    SET backup_codes = ?, last_used_backup_code = NULL
                    WHERE user_id = ?
                ");
                $stmt->execute([
                    json_encode($hashedCodes),
                    $_SESSION['user_id']
                ]);
                
                // Log the regeneration event
                logSecurityEvent($_SESSION['user_id'], '2fa_backup_codes_regenerated', [
                    'ip' => $_SERVER['REMOTE_ADDR']
                ]);
                
                // Show new backup codes to user
                $_SESSION['backup_codes'] = $backupCodes;
                $_SESSION['backup_codes_shown'] = true;
                
                header("Location: settings_2fa.php?backup_codes=regenerated");
                exit;
            } else {
                $_SESSION['2fa_attempts']++;
                $_SESSION['last_2fa_attempt'] = time();
                $error = "Incorrect password. Backup codes were not regenerated.";
            }
        } catch (Exception $e) {
            error_log("Backup codes regeneration error: " . $e->getMessage());
            $error = "An error occurred while regenerating backup codes. Please try again.";
        }
    }
}

// Generate CSRF token
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Two-Factor Authentication Settings</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
    <style>
        :root {
            --primary: #4361ee;
            --primary-dark: #3a56d4;
            --error: #ef233c;
            --success: #4cc9f0;
            --warning: #f8961e;
            --text: #2b2d42;
            --text-light: #8d99ae;
            --bg: #f8f9fa;
            --card: #ffffff;
            --border: #e9ecef;
            --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: 'Inter', sans-serif;
            background-color: var(--bg);
            color: var(--text);
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            padding: 1rem;
            line-height: 1.5;
        }

        .settings-container {
            background-color: var(--card);
            padding: 2.5rem;
            border-radius: 1rem;
            box-shadow: var(--shadow);
            width: 100%;
            max-width: 42rem;
            transition: all 0.3s ease;
        }

        .settings-header {
            text-align: center;
            margin-bottom: 2rem;
        }

        .settings-header h1 {
            font-size: 1.75rem;
            font-weight: 700;
            margin-bottom: 0.5rem;
        }

        .settings-header p {
            color: var(--text-light);
            font-size: 0.875rem;
        }

        .alert {
            padding: 1rem;
            border-radius: 0.5rem;
            margin-bottom: 1.5rem;
            font-size: 0.875rem;
        }

        .alert-success {
            background-color: rgba(76, 201, 240, 0.1);
            color: var(--success);
            border-left: 3px solid var(--success);
        }

        .alert-error {
            background-color: rgba(239, 35, 60, 0.1);
            color: var(--error);
            border-left: 3px solid var(--error);
        }

        .alert-warning {
            background-color: rgba(248, 150, 30, 0.1);
            color: var(--warning);
            border-left: 3px solid var(--warning);
        }

        .settings-section {
            margin-bottom: 2rem;
        }

        .settings-section h3 {
            font-size: 1.25rem;
            margin-bottom: 1rem;
            color: var(--text);
        }

        .settings-section p {
            margin-bottom: 1.5rem;
            color: var(--text-light);
        }

        .form-group {
            margin-bottom: 1.5rem;
        }

        .form-label {
            display: block;
            font-size: 0.875rem;
            font-weight: 500;
            margin-bottom: 0.5rem;
            color: var(--text);
        }

        .form-control {
            width: 100%;
            padding: 0.75rem 1rem;
            font-size: 0.875rem;
            border: 1px solid var(--border);
            border-radius: 0.5rem;
            transition: border-color 0.3s, box-shadow 0.3s;
        }

        .form-control:focus {
            outline: none;
            border-color: var(--primary);
            box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.15);
        }

        .btn {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            padding: 0.75rem 1rem;
            font-size: 0.875rem;
            font-weight: 600;
            border-radius: 0.5rem;
            border: none;
            cursor: pointer;
            transition: all 0.3s;
        }

        .btn-primary {
            background-color: var(--primary);
            color: white;
        }

        .btn-primary:hover {
            background-color: var(--primary-dark);
        }

        .btn-outline {
            background-color: transparent;
            border: 1px solid var(--border);
            color: var(--text);
        }

        .btn-outline:hover {
            background-color: var(--bg);
        }

        .backup-codes {
            background-color: var(--bg);
            padding: 1rem;
            border-radius: 0.5rem;
            margin-bottom: 1.5rem;
        }

        .backup-codes h4 {
            margin-bottom: 0.75rem;
            font-size: 1rem;
        }

        .backup-codes-list {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 0.5rem;
            margin-bottom: 1rem;
        }

        .backup-code {
            font-family: monospace;
            padding: 0.5rem;
            background-color: var(--card);
            border-radius: 0.25rem;
            text-align: center;
        }

        .backup-actions {
            display: flex;
            gap: 1rem;
            margin-top: 1.5rem;
        }

        @media (max-width: 640px) {
            .settings-container {
                padding: 1.5rem;
            }
            
            .backup-codes-list {
                grid-template-columns: 1fr;
            }
            
            .backup-actions {
                flex-direction: column;
                gap: 0.75rem;
            }
        }
    </style>
</head>
<body>
    <div class="settings-container">
        <div class="settings-header">
            <h1>Two-Factor Authentication</h1>
            <p>Manage your account security settings</p>
        </div>

        <?php if (isset($error)): ?>
            <div class="alert alert-error">
                <?php echo htmlspecialchars($error); ?>
            </div>
        <?php endif; ?>

        <?php if (isset($_GET['2fa']) && $_GET['2fa'] === 'enabled' && isset($_SESSION['backup_codes']) && $_SESSION['backup_codes_shown']): ?>
            <div class="alert alert-success">
                <h3>2FA Enabled Successfully</h3>
                <p>Two-factor authentication is now active for your account. You'll be asked for a verification code when logging in.</p>
                
                <div class="backup-codes">
                    <h4>Your Backup Codes</h4>
                    <p>Save these codes in a secure place. Each code can be used only once.</p>
                    
                    <div class="backup-codes-list">
                        <?php foreach ($_SESSION['backup_codes'] as $code): ?>
                            <div class="backup-code"><?php echo htmlspecialchars($code); ?></div>
                        <?php endforeach; ?>
                    </div>
                    
                    <p><strong>Important:</strong> These codes won't be shown again. If you lose them, you'll need to generate new ones.</p>
                </div>
            </div>
            <?php unset($_SESSION['backup_codes_shown']); ?>
        <?php elseif (isset($_GET['2fa']) && $_GET['2fa'] === 'disabled'): ?>
            <div class="alert alert-success">
                <h3>2FA Disabled</h3>
                <p>Two-factor authentication has been removed from your account.</p>
            </div>
        <?php elseif (isset($_GET['backup_codes']) && $_GET['backup_codes'] === 'regenerated' && isset($_SESSION['backup_codes']) && $_SESSION['backup_codes_shown']): ?>
            <div class="alert alert-success">
                <h3>New Backup Codes Generated</h3>
                <p>Your previous backup codes have been invalidated. Here are your new codes:</p>
                
                <div class="backup-codes">
                    <div class="backup-codes-list">
                        <?php foreach ($_SESSION['backup_codes'] as $code): ?>
                            <div class="backup-code"><?php echo htmlspecialchars($code); ?></div>
                        <?php endforeach; ?>
                    </div>
                    
                    <p><strong>Important:</strong> These codes won't be shown again. If you lose them, you'll need to generate new ones.</p>
                </div>
            </div>
            <?php unset($_SESSION['backup_codes_shown']); ?>
        <?php endif; ?>

        <div class="settings-section">
            <?php if ($userData && $userData['method']): ?>
                <h3>Two-Factor Authentication Status</h3>
                <p><strong>Method:</strong> <?php echo htmlspecialchars(ucfirst($userData['method'])); ?></p>
                <p><strong>Enabled on:</strong> <?php echo htmlspecialchars(date('F j, Y, g:i a', strtotime($userData['enabled_at']))); ?></p>
                
                <div class="alert alert-warning">
                    <h4>Backup Codes</h4>
                    <p>If you haven't saved your backup codes or have used them all, you should generate new ones.</p>
                </div>
                
                <form method="POST" action="">
                    <input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token']); ?>">
                    
                    <div class="form-group">
                        <label for="current_password" class="form-label">Current Password</label>
                        <input type="password" id="current_password" name="current_password" class="form-control" required>
                        <small class="text-muted">Required to make changes to your 2FA settings</small>
                    </div>
                    
                    <div class="backup-actions">
                        <button type="submit" name="regenerate_backup_codes" class="btn btn-outline">
                            Generate New Backup Codes
                        </button>
                        
                        <button type="submit" name="disable_2fa" class="btn btn-primary">
                            Disable Two-Factor Authentication
                        </button>
                    </div>
                </form>
            <?php else: ?>
                <h3>Two-Factor Authentication Status</h3>
                <p>Two-factor authentication is currently <strong>disabled</strong> for your account.</p>
                
                <div class="alert alert-warning">
                    <h4>Enhanced Security</h4>
                    <p>Enabling two-factor authentication adds an extra layer of security to your account. 
                    You'll be asked to enter a verification code sent to your email when logging in.</p>
                </div>
                
                <form method="POST" action="">
                    <input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token']); ?>">
                    
                    <p>Your verification codes will be sent to: <strong><?php echo htmlspecialchars($userData['email']); ?></strong></p>
                    
                    <button type="submit" name="enable_2fa" class="btn btn-primary">
                        Enable Two-Factor Authentication
                    </button>
                </form>
            <?php endif; ?>
        </div>
    </div>
</body>
</html>