<?php
/**
 * JWT Authentication Middleware
 * Verifies Bearer token on every protected request.
 */

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;

class AuthMiddleware {

    /**
     * Authenticate the request using JWT token.
     * Returns the user object on success.
     * Throws/exits on failure.
     */
    public static function authenticate(PDO $db): object {
        $headers = getallheaders();
        $authHeader = $headers['Authorization'] ?? $headers['authorization'] ?? '';

        if (empty($authHeader) || !preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
            Response::unauthorized('Token not provided. Authorization header required.');
        }

        $token = $matches[1];

        try {
            $decoded = JWT::decode($token, new Key(Database::JWT_SECRET, 'HS256'));
        } catch (ExpiredException $e) {
            Response::unauthorized('Token expired. Please login again.');
        } catch (\Exception $e) {
            Response::unauthorized('Invalid token: ' . $e->getMessage());
        }

        // Verify user still exists and is active
        $stmt = $db->prepare("SELECT id, username, full_name, department, role, status, hide_reversals FROM users WHERE id = ? AND status = 'active'");
        $stmt->execute([$decoded->user_id]);
        $user = $stmt->fetch();

        if (!$user) {
            Response::unauthorized('User not found or is blocked.');
        }

        // Verify session is still active
        $tokenHash = hash('sha256', $token);
        $sessionStmt = $db->prepare("SELECT id FROM user_sessions WHERE user_id = ? AND token_hash = ? AND is_active = 1");
        $sessionStmt->execute([$user['id'], $tokenHash]);
        
        if (!$sessionStmt->fetch()) {
            Response::unauthorized('Session expired or invalidated. Please login again.');
        }

        // Return as object for easy access
        return (object) $user;
    }
}
