<?php
/**
 * Fichier d'authentification et sécurité pour les API
 * Inclure ce fichier au début de chaque API pour sécuriser l'accès
 * 
 * Usage: include_once __DIR__ . '/auth_check.php';
 */

// Configuration de la base de données - Use cPanel remote server
$db_host = '154.73.92.52';
$db_name = 'transubd_GGR';
$db_user = 'transubd_transub_user';
$db_pass = 'Tr@nsub2@24';
$db_charset = 'utf8mb4';

// Headers de sécurité
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, X-API-Key");
header("Content-Type: application/json; charset=UTF-8");
header("X-Content-Type-Options: nosniff");
header("X-Frame-Options: DENY");
header("X-XSS-Protection: 1; mode=block");

// Gérer les requêtes OPTIONS (preflight CORS)
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

// Configuration de la session
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', isset($_SERVER['HTTPS']));
ini_set('session.use_strict_mode', 1);

// Fonction pour vérifier l'authentification via token JWT ou session
function checkApiAuth($pdo) {
    // 1. Vérifier le token Bearer dans l'Authorization header
    $headers = getallheaders();
    $authHeader = $headers['Authorization'] ?? $headers['authorization'] ?? '';

    if (preg_match('/Bearer\s+(.+)/i', $authHeader, $matches)) {
        $token = $matches[1];
        return verifyJwtToken($token, $pdo);
    }

    // 2. Vérifier X-API-Key (pour les requêtes mobiles/API)
    $apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
    if (!empty($apiKey)) {
        return verifyApiKey($apiKey, $pdo);
    }

    // 3. Vérifier la session PHP (pour les appels depuis le navigateur)
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }

    if (isset($_SESSION['user_id']) && isset($_SESSION['authenticated'])) {
        return [
            'success' => true,
            'user_id' => $_SESSION['user_id'],
            'role' => $_SESSION['user_role'] ?? 'user',
            'site_id' => $_SESSION['site_id'] ?? null
        ];
    }

    return ['success' => false, 'message' => 'Non autorisé'];
}

// Fonction pour vérifier le token JWT
function verifyJwtToken($token, $pdo) {
    try {
        // Décoder le token JWT (sans vérification pour l'instant - à améliorer avec une clé secrète)
        $parts = explode('.', $token);
        if (count($parts) !== 3) {
            return ['success' => false, 'message' => 'Token invalide'];
        }

        $payload = json_decode(base64_decode($parts[1]), true);

        if (!$payload || !isset($payload['user_id']) || !isset($payload['exp'])) {
            return ['success' => false, 'message' => 'Token invalide'];
        }

        // Vérifier l'expiration
        if ($payload['exp'] < time()) {
            return ['success' => false, 'message' => 'Token expiré'];
        }

        // Vérifier que l'utilisateur existe toujours
        $stmt = $pdo->prepare("SELECT id, code_utilisateur, role, site_id FROM Utilisateurs WHERE id = ?");
        $stmt->execute([$payload['user_id']]);
        $user = $stmt->fetch();

        if (!$user) {
            return ['success' => false, 'message' => 'Utilisateur invalide'];
        }

        return [
            'success' => true,
            'user_id' => $user['id'],
            'role' => $user['role'],
            'site_id' => $user['site_id'] ?? null
        ];
    } catch (Exception $e) {
        return ['success' => false, 'message' => 'Erreur de vérification du token'];
    }
}

// Fonction pour vérifier la clé API
function verifyApiKey($apiKey, $pdo) {
    try {
        $stmt = $pdo->prepare("SELECT id, code_utilisateur, role, site_id FROM Utilisateurs WHERE api_key = ?");
        $stmt->execute([hash('sha256', $apiKey)]);
        $user = $stmt->fetch();

        if (!$user) {
            return ['success' => false, 'message' => 'Clé API invalide'];
        }

        return [
            'success' => true,
            'user_id' => $user['id'],
            'role' => $user['role'],
            'site_id' => $user['site_id'] ?? null
        ];
    } catch (Exception $e) {
        return ['success' => false, 'message' => 'Erreur de vérification'];
    }
}

// Fonction pour vérifier les permissions
function checkPermission($pdo, $userId, $permission) {
    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(*) FROM user_permissions 
            WHERE user_id = ? AND permission = ?
        ");
        $stmt->execute([$userId, $permission]);
        return $stmt->fetchColumn() > 0;
    } catch (Exception $e) {
        return false;
    }
}

// Fonction pour créer un token JWT
function createJwtToken($userId, $role, $expiry = 3600) {
    $secret = 'GGR_SECRET_KEY_' . date('Ymd'); // Clé secrète - à changer en production

    $payload = [
        'user_id' => $userId,
        'role' => $role,
        'iat' => time(),
        'exp' => time() + $expiry
    ];

    $header = base64_encode(json_encode(['typ' => 'JWT', 'alg' => 'HS256']));
    $payloadEncoded = base64_encode(json_encode($payload));
    $signature = base64_encode(hash_hmac('sha256', "$header.$payloadEncoded", $secret, true));

    return "$header.$payloadEncoded.$signature";
}

// Connexion à la base de données via la classe Database centralisée
function getDbConnection() {
    require_once __DIR__ . '/../../config/database.php';
    return Database::getInstance();
}

// Rate limiting simple (à améliorer en production)
function checkRateLimit($identifier) {
    $maxRequests = 60; // Maximum de requêtes
    $timeWindow = 60; // Par minute

    // Utiliser un fichier pour le rate limiting
    $rateFile = sys_get_temp_dir() . '/api_rate_' . md5($identifier);

    if (file_exists($rateFile)) {
        $data = json_decode(file_get_contents($rateFile), true);

        if ($data['timestamp'] > time() - $timeWindow) {
            if ($data['count'] >= $maxRequests) {
                http_response_code(429);
                echo json_encode(['success' => false, 'message' => 'Trop de requêtes. Veuillez patienter.']);
                exit;
            }
            $data['count']++;
        } else {
            $data = ['count' => 1, 'timestamp' => time()];
        }
    } else {
        $data = ['count' => 1, 'timestamp' => time()];
    }

    file_put_contents($rateFile, json_encode($data));
}

// Nettoyer les entrées utilisateur
function sanitizeInput($data) {
    if (is_array($data)) {
        return array_map('sanitizeInput', $data);
    }
    return htmlspecialchars(strip_tags(trim($data)), ENT_QUOTES, 'UTF-8');
}