<?php

require_once __DIR__ . '/../lib/init.php';
Auth::requireLogin();
Auth::requireRole('admin', 'tech');

// POST-only
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: dashboard.php');
    exit;
}

$subnetId = (int)($_POST['subnet_id'] ?? 0);
$subnet   = Subnet::getById($subnetId);
if (!$subnet) {
    header('Location: dashboard.php');
    exit;
}
$backUrl = 'subnet.php?id=' . $subnetId;

$hostIds = array_values(array_unique(array_map('intval', $_POST['host_ids'] ?? [])));
if (!$hostIds) {
    $_SESSION['flash'] = ['type' => 'warning', 'message' => 'Aucune réservation sélectionnée.'];
    header('Location: ' . $backUrl);
    exit;
}

// Sécurité : tous les host_ids doivent appartenir à ce subnet
$in   = implode(',', $hostIds);
$stmt = Database::get()->prepare(
    "SELECT host_id FROM hosts WHERE dhcp4_subnet_id = ? AND host_id IN ($in)"
);
$stmt->execute([$subnet['kea_subnet_id']]);
$valid = array_map('intval', $stmt->fetchAll(PDO::FETCH_COLUMN));
if (count($valid) !== count($hostIds)) {
    $_SESSION['flash'] = ['type' => 'danger', 'message' => 'Sélection invalide (réservation hors subnet).'];
    header('Location: ' . $backUrl);
    exit;
}

// Champs modifiés : $_POST['changed'][<champ>] = '1'
$changed = $_POST['changed'] ?? [];
$changes = [];

if (!empty($changed['group_name'])) {
    $changes['group_name'] = trim((string)($_POST['group_name'] ?? ''));
}
if (!empty($changed['short_lease'])) {
    $changes['short_lease'] = !empty($_POST['short_lease']) ? 1 : 0;
}
if (!empty($changed['ntp'])) {
    $changes['ntp'] = !empty($_POST['ntp']) ? 1 : 0;
}
if (!empty($changed['no_gateway'])) {
    $changes['no_gateway'] = !empty($_POST['no_gateway']) ? 1 : 0;
}
if (!empty($changed['gateway'])) {
    $changes['gateway'] = trim((string)($_POST['gateway'] ?? ''));
}
if (!empty($changed['routes'])) {
    $routesDest = $_POST['routes_dest'] ?? [];
    $routesGw   = $_POST['routes_gw']   ?? [];
    $routes = [];
    for ($i = 0; $i < max(count($routesDest), count($routesGw)); $i++) {
        $dest = trim($routesDest[$i] ?? '');
        $gw   = trim($routesGw[$i]   ?? '');
        if ($dest !== '' || $gw !== '') $routes[] = ['dest' => $dest, 'gw' => $gw];
    }
    $changes['routes'] = $routes;
}

if (!$changes) {
    $_SESSION['flash'] = ['type' => 'warning', 'message' => 'Aucune modification à appliquer.'];
    header('Location: ' . $backUrl);
    exit;
}

// Validation des valeurs fournies (réutilise les mêmes règles que le formulaire)
$errors = [];
if (isset($changes['gateway']) && $changes['gateway'] !== '' && !isValidIp($changes['gateway'])) {
    $errors[] = 'Gateway spécifique : format IPv4 invalide.';
}
if (isset($changes['routes'])) {
    foreach ($changes['routes'] as $i => $r) {
        $dest = trim($r['dest'] ?? ''); $gw = trim($r['gw'] ?? '');
        if ($dest === '' && $gw === '') continue;
        if (!preg_match('/^(\d{1,3}(?:\.\d{1,3}){3})\/(\d{1,2})$/', $dest)) {
            $errors[] = 'Route ' . ($i + 1) . ' : destination CIDR invalide.';
        }
        if (!isValidIp($gw)) {
            $errors[] = 'Route ' . ($i + 1) . ' : gateway invalide.';
        }
    }
}
if ($errors) {
    $_SESSION['flash'] = ['type' => 'danger', 'message' => implode(' ', $errors)];
    header('Location: ' . $backUrl);
    exit;
}

$count = Reservation::massUpdate($hostIds, $changes);
$sync  = SyncService::sync();

AuditLog::log(
    'reservation.bulk_update',
    'host',
    null,
    sprintf('%d réservation(s) — champs: %s (subnet %s)', $count, implode(', ', array_keys($changes)), $subnet['name'])
);

if ($sync['success']) {
    $_SESSION['flash'] = ['type' => 'success', 'message' => "$count réservation(s) mise(s) à jour et Kea rechargé."];
} else {
    $_SESSION['flash'] = ['type' => 'warning', 'message' => "$count réservation(s) mise(s) à jour mais le reload Kea a échoué : " . $sync['message']];
}
header('Location: ' . $backUrl);
exit;
