<?php
// ============================================================
// Auth Middleware — JWT Verify + RBAC
// ============================================================

require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../helpers/JWT.php';
require_once __DIR__ . '/../helpers/Response.php';

class AuthMiddleware {

    private static $currentUser = null; // array|null

    /**
     * Verify the Bearer access token from Authorization header.
     * Populates self::$currentUser on success.
     */
    public static function verifyToken(): array {
        $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';

        // Also support Apache setups that strip Authorization header
        if (empty($authHeader) && function_exists('getallheaders')) {
            $headers    = getallheaders();
            $authHeader = $headers['Authorization'] ?? $headers['authorization'] ?? '';
        }

        if (empty($authHeader) || substr($authHeader, 0, 7) !== 'Bearer ') {
            Response::unauthorized('Access denied. No token provided.', 'NO_TOKEN');
        }

        $token = substr($authHeader, 7);

        try {
            $payload = JWT::decode($token, JWT_ACCESS_SECRET);
        } catch (RuntimeException $e) {
            $code = $e->getMessage() === 'token_expired' ? 'TOKEN_EXPIRED' : 'INVALID_TOKEN';
            $msg  = $code === 'TOKEN_EXPIRED' ? 'Access token expired.' : 'Invalid access token.';
            Response::unauthorized($msg, $code);
        }

        self::$currentUser = $payload;
        return $payload;
    }

    /**
     * Get the currently authenticated user (call after verifyToken).
     */
    public static function user(): ?array {
        return self::$currentUser;
    }

    /**
     * Require specific role(s). Must be called after verifyToken().
     */
    public static function requireRole(array $roles): void {
        $user = self::$currentUser;
        if (!$user || !in_array($user['role'], $roles, true)) {
            Response::forbidden(
                'Access restricted. Required role(s): ' . implode(', ', $roles) . '.',
                'FORBIDDEN'
            );
        }
    }

    /**
     * Optional auth — attach user if valid token present, never block.
     */
    public static function optionalAuth(): ?array {
        $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
        if (function_exists('getallheaders')) {
            $headers    = getallheaders();
            $authHeader = $headers['Authorization'] ?? $headers['authorization'] ?? $authHeader;
        }
        if (empty($authHeader) || substr($authHeader, 0, 7) !== 'Bearer ') return null;
        $token = substr($authHeader, 7);
        try {
            self::$currentUser = JWT::decode($token, JWT_ACCESS_SECRET);
            return self::$currentUser;
        } catch (\Exception $e) {
            return null;
        }
    }
}
