<?php
/**
 * auth_entry.php - Point d'entrée authentification API
 * Version sécurisée - Janvier 2026
 * Méthodes autorisées : PUT ou PATCH (au lieu de POST)
 */

require_once 'config.php';

// === HEADERS DE SÉCURITÉ (réduction surface d'attaque + anti-XSS/CSRF) ===
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *'); // À remplacer en prod par ex: 'app://com.transub.pointage'
header('Access-Control-Allow-Methods: PUT, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('X-XSS-Protection: 1; mode=block');
header('Referrer-Policy: strict-origin-when-cross-origin');
header('Permissions-Policy: geolocation=(), microphone=(), camera=()');
header('Content-Security-Policy: default-src \'self\'; script-src \'self\' \'unsafe-inline\'; style-src \'self\' \'unsafe-inline\';');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

// Autoriser uniquement PUT et PATCH
if (!in_array($_SERVER['REQUEST_METHOD'], ['PUT', 'PATCH'])) {
    http_response_code(405);
    die(json_encode(['success' => false, 'message' => 'Méthode non autorisée - PUT ou PATCH uniquement']));
}

// === RÉCUPÉRATION ET VALIDATION DES DONNÉES ===
$rawInput = file_get_contents('php://input');
$data = json_decode($rawInput, true);

if (json_last_error() !== JSON_ERROR_NONE) {
    http_response_code(400);
    die(json_encode(['success' => false, 'message' => 'JSON invalide']));
}

// Validation stricte + assainissement
$code = trim($data['code_utilisateur'] ?? '');
$pass = $data['mot_de_passe'] ?? '';

// Regex + longueur + caractères autorisés
if (!preg_match('/^[A-Za-z0-9_-]{3,50}$/', $code) || strlen($pass) < 6 || strlen($pass) > 255) {
    http_response_code(400);
    die(json_encode(['success' => false, 'message' => 'Données invalides']));
}

// === RATE LIMITING (contre brute-force) ===
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$key = 'login_' . md5($ip . $code);
if (!checkRateLimit($key)) {
    logAction('RATE_LIMIT_EXCEEDED', 'Trop de tentatives login', ['ip' => $ip, 'code' => $code]);
    http_response_code(429);
    die(json_encode([
        'success' => false,
        'message' => 'Trop de tentatives. Réessayez dans 5 minutes.'
    ]));
}

// === CONNEXION BDD ===
$pdo = getPDO();

try {
    $stmt = $pdo->prepare("
        SELECT id, nom, prenom, role, actif, mot_de_passe 
        FROM agents 
        WHERE code_utilisateur = ?
    ");
    $stmt->execute([$code]);
    $agent = $stmt->fetch();

    if (!$agent || $agent['actif'] != 1 || !password_verify($pass, $agent['mot_de_passe'])) {
        logAction('LOGIN_FAIL', 'Échec authentification', [
            'ip' => $ip,
            'code' => $code,
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown'
        ]);
        http_response_code(401);
        die(json_encode(['success' => false, 'message' => 'Identifiants incorrects ou compte inactif']));
    }

    // Mise à jour dernier login (audit)
    $stmt = $pdo->prepare("UPDATE agents SET dernier_login = NOW() WHERE id = ?");
    $stmt->execute([$agent['id']]);

    // Génération token sécurisé
    $token = generateToken($agent['id'], $agent['role']);

    // Log succès
    logAction('LOGIN_SUCCESS', 'Authentification réussie', [
        'user_id' => $agent['id'],
        'ip' => $ip,
        'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown'
    ]);

    echo json_encode([
        'success' => true,
        'token' => $token,
        'expires_in' => TOKEN_EXPIRY,
        'agent' => [
            'id'     => $agent['id'],
            'nom'    => $agent['nom'],
            'prenom' => $agent['prenom'],
            'role'   => $agent['role']
        ]
    ]);

} catch (Exception $e) {
    logAction('ERROR_CRITICAL', $e->getMessage(), ['ip' => $ip]);
    http_response_code(500);
    die(json_encode(['success' => false, 'message' => 'Erreur interne du serveur']));
}
?>