<?php
// authenticate.php
header("Content-Type: application/json; charset=UTF-8");

// Inklusi file keamanan
require 'security.php';
require 'logger.php';
require 'rate_limit.php';

// Inklusi file koneksi database
require 'db.php';

/**
 * Fungsi untuk mengautentikasi pengguna berdasarkan token dan role.
 *
 * @param array $required_roles Array yang berisi role yang diizinkan.
 * @return array Data pengguna.
 */
function authenticate($pdo, $required_roles = []) {
    // Cek HTTPS
    ensure_https();

    // Ambil header Authorization
    $headers = getallheaders();
    if (!isset($headers['Authorization'])) {
        http_response_code(401);
        echo json_encode(['error' => 'Authorization header missing']);
        log_activity("Authorization header missing from IP: " . $_SERVER['REMOTE_ADDR']);
        exit;
    }

    // Ekstrak token dari header
    $auth_header = $headers['Authorization'];
    if (!preg_match('/Bearer\s(\S+)/', $auth_header, $matches)) {
        http_response_code(401);
        echo json_encode(['error' => 'Invalid Authorization header format']);
        log_activity("Invalid Authorization header format from IP: " . $_SERVER['REMOTE_ADDR']);
        exit;
    }

    $token = sanitize_input($matches[1]);

    // Terapkan rate limiting per token dan endpoint
    $identifier = $_SERVER['REMOTE_ADDR'] . ':' . $_SERVER['REQUEST_URI'];
    rate_limit($pdo, 100, 60, $identifier);

    // Cek token di database
    try {
        $stmt = $pdo->prepare("SELECT user_id, expires_at FROM tokens WHERE token = ?");
        $stmt->execute([$token]);
        $tokenData = $stmt->fetch();

        if (!$tokenData) {
            http_response_code(401);
            echo json_encode(['error' => 'Invalid token']);
            log_activity("Invalid token attempt from IP: " . $_SERVER['REMOTE_ADDR']);
            exit;
        }

        // Cek apakah token sudah kedaluwarsa
        if (new DateTime() > new DateTime($tokenData['expires_at'])) {
            // Token sudah kedaluwarsa, hapus dari database
            $stmt = $pdo->prepare("DELETE FROM tokens WHERE token = ?");
            $stmt->execute([$token]);

            http_response_code(401);
            echo json_encode(['error' => 'Token expired']);
            log_activity("Expired token from user_id: " . $tokenData['user_id']);
            exit;
        }

        // Ambil informasi pengguna
        $stmt = $pdo->prepare("SELECT id, name, email, role FROM users WHERE id = ?");
        $stmt->execute([$tokenData['user_id']]);
        $user = $stmt->fetch();

        if (!$user) {
            http_response_code(401);
            echo json_encode(['error' => 'User not found']);
            log_activity("User not found for token: " . $token);
            exit;
        }

        // Cek apakah role pengguna sesuai
        if (!empty($required_roles) && !in_array($user['role'], $required_roles)) {
            http_response_code(403);
            echo json_encode(['error' => 'Forbidden: Insufficient permissions']);
            log_activity("Forbidden access by user_id: " . $user['id']);
            exit;
        }

        // Catat aktivitas login atau akses
        log_activity("User authenticated: user_id " . $user['id'] . ", role: " . $user['role']);

        // Kembalikan data pengguna
        return $user;

    } catch (Exception $e) {
        http_response_code(500);
        echo json_encode(['error' => 'Server error']);
        log_activity("Authentication server error: " . $e->getMessage());
        exit;
    }
}
?>
