<?php
require_once __DIR__ . '/../config/auth.php';
require_once __DIR__ . '/../config/rbac.php';

/**
 * Middleware to check if user is authenticated
 */
function authMiddleware() {
    if (!isLoggedIn()) {
        header('Location: /login.php');
        exit;
    }
    checkSessionTimeout();
}

/**
 * Middleware to check specific role
 */
function roleMiddleware($role) {
    authMiddleware();
    requireRole($role);
}

/**
 * Middleware to check any of the specified roles
 */
function anyRoleMiddleware($roles) {
    authMiddleware();
    requireAnyRole($roles);
}

/**
 * Middleware to check permission
 */
function permissionMiddleware($permission) {
    authMiddleware();
    requirePermission($permission);
}

/**
 * Admin-only middleware
 */
function adminOnly() {
    roleMiddleware('admin');
}

/**
 * Instructor or Admin middleware
 */
function instructorOrAdmin() {
    anyRoleMiddleware(['instructor', 'admin']);
}

/**
 * Student or higher middleware
 */
function studentOrHigher() {
    anyRoleMiddleware(['student', 'instructor', 'admin']);
}

/**
 * Check if current user can access admin panel
 */
function canAccessAdminPanel() {
    return isLoggedIn() && hasAnyRole(['admin', 'instructor']);
}

/**
 * Check if current user can manage users
 */
function canManageUsers() {
    return hasRole('admin');
}

/**
 * Check if current user can manage content
 */
function canManageContent() {
    return hasAnyRole(['admin', 'instructor']);
}

/**
 * Check if current user can view analytics
 */
function canViewAnalytics() {
    return hasRole('admin');
}

/**
 * Validate CSRF token middleware
 */
function csrfMiddleware() {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $token = $_POST['csrf_token'] ?? '';
        if (!validateCSRFToken($token)) {
            http_response_code(403);
            die('CSRF token validation failed');
        }
    }
}

/**
 * Rate limiting middleware (basic implementation)
 */
function rateLimitMiddleware($maxRequests = 100, $timeWindow = 3600) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $key = "rate_limit_{$ip}";

    // In a real application, you'd use Redis or similar for this
    // For now, we'll use session-based rate limiting
    if (!isset($_SESSION['rate_limit'])) {
        $_SESSION['rate_limit'] = ['count' => 0, 'reset_time' => time() + $timeWindow];
    }

    if (time() > $_SESSION['rate_limit']['reset_time']) {
        $_SESSION['rate_limit'] = ['count' => 1, 'reset_time' => time() + $timeWindow];
    } else {
        $_SESSION['rate_limit']['count']++;
        if ($_SESSION['rate_limit']['count'] > $maxRequests) {
            http_response_code(429);
            die('Too many requests. Please try again later.');
        }
    }
}

/**
 * API authentication middleware for future API endpoints
 */
function apiAuthMiddleware() {
    $headers = getallheaders();
    $authHeader = $headers['Authorization'] ?? '';

    if (empty($authHeader) || !preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) {
        http_response_code(401);
        die(json_encode(['error' => 'Unauthorized']));
    }

    $token = $matches[1];

    // In a real application, you'd validate JWT tokens here
    // For now, we'll check session
    if (!isLoggedIn()) {
        http_response_code(401);
        die(json_encode(['error' => 'Invalid token']));
    }
}

/**
 * Content Security Policy headers
 */
function securityHeaders() {
    header('X-Frame-Options: DENY');
    header('X-Content-Type-Options: nosniff');
    header('X-XSS-Protection: 1; mode=block');
    header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
    header('Referrer-Policy: strict-origin-when-cross-origin');
}

/**
 * Initialize all security middleware
 */
function initSecurity() {
    securityHeaders();
    rateLimitMiddleware();
}

/**
 * Get current user info for templates
 */
function getUserContext() {
    if (!isLoggedIn()) {
        return null;
    }

    $user = getCurrentUser();
    return [
        'id' => $user['id'],
        'username' => $user['username'],
        'email' => $user['email'],
        'role' => $user['role'],
        'role_display' => getRoleDisplayName($user['role']),
        'email_verified' => $user['email_verified'],
        'last_login' => $user['last_login'],
        'dashboard_url' => getDashboardUrl()
    ];
}