<?php

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

// ── Helpers locaux ────────────────────────────────────────────────────────────

/** Parse le CSV uploadé. Retourne ['rows'=>[], 'has_subnet_col'=>bool] ou ['error'=>string]. */
function parseCsv(string $path): array {
    $handle = fopen($path, 'r');
    if (!$handle) return ['error' => 'Impossible de lire le fichier.'];

    // Supprimer le BOM UTF-8 éventuel
    $bom = fread($handle, 3);
    if ($bom !== "\xEF\xBB\xBF") rewind($handle);

    // Détecter le délimiteur (virgule ou point-virgule)
    $first = fgets($handle);
    rewind($handle);
    if ($bom === "\xEF\xBB\xBF") fread($handle, 3);
    $delim = substr_count($first, ';') >= substr_count($first, ',') ? ';' : ',';

    // Lire les en-têtes
    $headers = fgetcsv($handle, 0, $delim, '"', '');
    if (!$headers) { fclose($handle); return ['error' => 'Fichier vide ou illisible.']; }
    $headers = array_map(fn($h) => strtolower(trim($h)), $headers);

    $required = ['mac', 'ip', 'hostname'];
    foreach ($required as $col) {
        if (!in_array($col, $headers, true)) {
            fclose($handle);
            return ['error' => "Colonne obligatoire manquante : « $col ». En-têtes trouvés : " . implode(', ', $headers)];
        }
    }

    $idxMac       = array_search('mac',         $headers, true);
    $idxIp        = array_search('ip',          $headers, true);
    $idxHost      = array_search('hostname',    $headers, true);
    $idxDesc      = array_search('description', $headers, true);
    $idxSubnet    = array_search('subnet',      $headers, true);
    $idxGateway   = array_search('gateway',     $headers, true);
    $idxRoutes    = array_search('routes',      $headers, true);
    $idxShortLease = array_search('short_lease', $headers, true);
    $idxNoGateway = array_search('no_gateway',  $headers, true);
    $idxGroup      = array_search('group',       $headers, true);

    $rows = [];
    $line = 1;
    while (($cols = fgetcsv($handle, 0, $delim, '"', '')) !== false) {
        $line++;
        if (count(array_filter($cols, fn($c) => trim($c) !== '')) === 0) continue;
        $rows[] = [
            'line'        => $line,
            'mac_raw'     => $cols[$idxMac]    ?? '',
            'ip'          => trim($cols[$idxIp]     ?? ''),
            'hostname'    => trim($cols[$idxHost]   ?? ''),
            'description' => $idxDesc      !== false ? trim($cols[$idxDesc]      ?? '') : '',
            'subnet_name' => $idxSubnet    !== false ? trim($cols[$idxSubnet]    ?? '') : '',
            'gateway'     => $idxGateway   !== false ? trim($cols[$idxGateway]   ?? '') : '',
            'routes_raw'  => $idxRoutes    !== false ? trim($cols[$idxRoutes]    ?? '') : '',
            'short_lease' => $idxShortLease !== false ? (trim($cols[$idxShortLease] ?? '') === '1' ? 1 : 0) : 0,
            'no_gateway'  => $idxNoGateway  !== false ? (trim($cols[$idxNoGateway]  ?? '') === '1' ? 1 : 0) : 0,
            'group_name'  => $idxGroup       !== false ? trim($cols[$idxGroup]       ?? '') : '',
        ];
    }
    fclose($handle);
    return ['rows' => $rows, 'has_subnet_col' => $idxSubnet !== false];
}

// ── Initialisation ────────────────────────────────────────────────────────────

$subnetId     = (int)($_GET['subnet_id'] ?? $_POST['subnet_id'] ?? 0);
$subnet       = $subnetId ? Subnet::getById($subnetId) : null;
$multiMode    = ($subnet === null); // true = import global sans subnet par défaut

// Charger tous les subnets pour le mode multi / la colonne subnet
$allSubnets    = Subnet::getAll();
$subnetsByName = [];
foreach ($allSubnets as $s) {
    $subnetsByName[strtolower($s['name'])] = $s;
}

$step       = (int)($_POST['step'] ?? 0);
$page_title = $multiMode ? 'Import CSV global' : 'Importer — ' . $subnet['name'];

// ── Étape 2 : Application de l'import ─────────────────────────────────────────

if ($step === 2) {
    $rows        = $_POST['r'] ?? [];
    $applied     = 0;
    $skipped     = 0;
    $errMessages = [];

    // IPs déjà utilisées dans ce batch, indexées par kea_subnet_id
    $batchIps = [];

    // IPs existantes en DB, indexées par kea_subnet_id
    $existingIpsCache = [];
    $getExistingIps   = function(int $keaId) use (&$existingIpsCache): array {
        if (!isset($existingIpsCache[$keaId])) {
            $existingIpsCache[$keaId] = array_column(
                Reservation::getBySubnet($keaId), null, 'ip_address'
            );
        }
        return $existingIpsCache[$keaId];
    };

    // Subnets touchés pour le sync
    $touchedSubnetIds = [];

    foreach ($rows as $i => $row) {
        $status      = $row['status']      ?? '';
        $action      = trim($row['action'] ?? '');
        $mac         = $row['mac']         ?? '';
        $ip          = $row['ip']          ?? '';
        $host        = $row['hostname']    ?? '';
        $desc        = $row['description'] ?? '';
        $hostId      = (int)($row['mac_host_id']   ?? 0);
        $newIp       = trim($row['new_ip']  ?? '');
        $lineNum     = (int)($row['line']   ?? ($i + 2));
        $keaSubnetId = (int)($row['kea_subnet_id'] ?? 0);
        $subnetAppId = (int)($row['subnet_id']     ?? 0);
        $gateway     = trim($row['gateway']    ?? '');
        $routesRaw   = trim($row['routes_raw'] ?? '');
        $shortLease  = (int)($row['short_lease'] ?? 0);
        $noGateway   = (int)($row['no_gateway'] ?? 0);
        $group = trim($row['group_name'] ?? '');
        if ($noGateway) $gateway = '';  // no_gateway l'emporte sur une gateway renseignée

        // Parse les routes "10.0.0.0/8-192.168.1.1|172.16.0.0/12-192.168.1.1"
        $routes = [];
        if ($routesRaw !== '') {
            foreach (explode('|', $routesRaw) as $part) {
                $part = trim($part);
                if ($part === '') continue;
                $sep = strrpos($part, '-');
                if ($sep !== false) {
                    $routes[] = ['dest' => trim(substr($part, 0, $sep)), 'gw' => trim(substr($part, $sep + 1))];
                }
            }
        }

        if (in_array($status, ['skip', 'invalid', 'pool'], true) || $action === 'skip' || !$keaSubnetId) {
            $skipped++;
            continue;
        }

        $existingIps = $getExistingIps($keaSubnetId);
        $batchIps[$keaSubnetId] ??= [];

        $data = ['mac'=>$mac,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,'group_name'=>$group,'gateway'=>$gateway,'routes'=>$routes,'short_lease'=>$shortLease,'no_gateway'=>$noGateway];

        // ── Ligne propre ──────────────────────────────────────────────────────
        if ($status === 'clean') {
            // IP vide = allocation dynamique (short-lease sans IP fixe) — pas de vérif doublons IP
            if ($ip !== '' && (isset($existingIps[$ip]) || isset($batchIps[$keaSubnetId][$ip]))) {
                $errMessages[] = "Ligne $lineNum ($ip) : IP déjà utilisée.";
                $skipped++;
                continue;
            }
            try {
                Reservation::add($keaSubnetId, $data);
                if ($ip !== '') $batchIps[$keaSubnetId][$ip] = true;
                $touchedSubnetIds[$subnetAppId] = true;
                $applied++;
            } catch (Throwable $e) {
                $errMessages[] = "Ligne $lineNum : " . $e->getMessage();
            }
            continue;
        }

        // ── Conflit IP / IP réservée hors DHCP ───────────────────────────────────
        if ($status === 'ip_conflict' || $status === 'reserved') {
            $curSubnet = $allSubnets[array_search($subnetAppId, array_column($allSubnets,'id'))] ?? null;
            $targetIp = $newIp;
            if (!$targetIp) { $skipped++; continue; }
            if (!isValidIp($targetIp))               { $errMessages[] = "Ligne $lineNum : IP « $targetIp » invalide."; $skipped++; continue; }
            if (!ipInCidr($targetIp, $curSubnet['cidr'] ?? '0.0.0.0/0')) {
                $errMessages[] = "Ligne $lineNum : IP « $targetIp » hors subnet."; $skipped++; continue;
            }
            if (isset($existingIps[$targetIp]) || isset($batchIps[$keaSubnetId][$targetIp])) {
                $errMessages[] = "Ligne $lineNum : IP « $targetIp » déjà utilisée.";
                $skipped++;
                continue;
            }
            // Garde-fou : la nouvelle IP ne doit pas tomber sur une IP réservée (hors DHCP)
            if ($curSubnet && !empty($curSubnet['reserved_ips'])) {
                require_once __DIR__ . '/../lib/ReservedIps.php';
                $rNet = ReservedIps::networkIntFromCidr($curSubnet['cidr']);
                if ($rNet !== null && ReservedIps::contains($curSubnet['reserved_ips'], $rNet, $targetIp) !== null) {
                    $errMessages[] = "Ligne $lineNum : IP « $targetIp » réservée (hors DHCP).";
                    $skipped++; continue;
                }
            }
            $data['ip'] = $targetIp;
            try {
                if ($hostId) {
                    Reservation::update($hostId, $data);
                } else {
                    Reservation::add($keaSubnetId, $data);
                }
                $batchIps[$keaSubnetId][$targetIp] = true;
                $touchedSubnetIds[$subnetAppId] = true;
                $applied++;
            } catch (Throwable $e) {
                $errMessages[] = "Ligne $lineNum : " . $e->getMessage();
            }
            continue;
        }

        // ── Conflit MAC ───────────────────────────────────────────────────────
        if ($status === 'mac_conflict') {
            if ($action === 'keep') { $skipped++; continue; }

            if ($action === 'update') {
                if (isset($existingIps[$ip]) || isset($batchIps[$keaSubnetId][$ip])) {
                    $errMessages[] = "Ligne $lineNum ($ip) : IP devenue indisponible.";
                    $skipped++;
                    continue;
                }
                try {
                    Reservation::update($hostId, $data);
                    $batchIps[$keaSubnetId][$ip] = true;
                    $touchedSubnetIds[$subnetAppId] = true;
                    $applied++;
                } catch (Throwable $e) {
                    $errMessages[] = "Ligne $lineNum : " . $e->getMessage();
                }
                continue;
            }

            if ($action === 'custom_ip') {
                $targetIp = $newIp;
                if (!$targetIp) { $skipped++; continue; }
                if (!isValidIp($targetIp))               { $errMessages[] = "Ligne $lineNum : IP « $targetIp » invalide."; $skipped++; continue; }
                if (isset($existingIps[$targetIp]) || isset($batchIps[$keaSubnetId][$targetIp])) {
                    $errMessages[] = "Ligne $lineNum : IP « $targetIp » déjà utilisée.";
                    $skipped++;
                    continue;
                }
                $data['ip'] = $targetIp;
                try {
                    Reservation::update($hostId, $data);
                    $batchIps[$keaSubnetId][$targetIp] = true;
                    $touchedSubnetIds[$subnetAppId] = true;
                    $applied++;
                } catch (Throwable $e) {
                    $errMessages[] = "Ligne $lineNum : " . $e->getMessage();
                }
                continue;
            }
        }

        $skipped++;
    }

    // Sync unique si au moins une modification
    $syncMsg = '';
    if ($applied > 0) {
        $sync    = SyncService::sync();
        $syncMsg = $sync['success'] ? '' : ' Sync : ' . $sync['message'];
        $subnetNames = implode(', ', array_map(
            fn($sid) => Subnet::getById($sid)['name'] ?? $sid,
            array_keys($touchedSubnetIds)
        ));
        AuditLog::log('reservation.import', 'subnet', $subnetId ?: null,
            "$applied ajoutée(s)/modifiée(s), $skipped ignorée(s) — " . ($subnetNames ?: 'multi'));
    }

    $type = ($applied > 0 && !$errMessages) ? 'success' : ($applied > 0 ? 'warning' : 'danger');
    $msg  = "$applied réservation(s) importée(s), $skipped ignorée(s).";
    if ($errMessages) $msg .= ' Erreurs : ' . implode(' | ', $errMessages);
    $msg .= $syncMsg;

    $_SESSION['flash'] = ['type' => $type, 'message' => $msg];
    header('Location: ' . ($subnet ? 'subnet.php?id=' . $subnetId : 'subnets.php'));
    exit;
}

// ── Étape 1 : Parsing + analyse ───────────────────────────────────────────────

$analyzed      = [];
$parseError    = '';
$hasSubnetCol  = false;

if ($step === 1) {
    if (empty($_FILES['csvfile']['tmp_name']) || $_FILES['csvfile']['error'] !== UPLOAD_ERR_OK) {
        $parseError = 'Aucun fichier reçu ou erreur d\'upload.';
    } else {
        $parsed = parseCsv($_FILES['csvfile']['tmp_name']);
        if (isset($parsed['error'])) {
            $parseError = $parsed['error'];
        } else {
            $hasSubnetCol = $parsed['has_subnet_col'];
            $analyzed     = ReservationImportAnalyzer::analyzeRows($parsed['rows'], $subnet, $subnetsByName, $hasSubnetCol);
        }
    }
}

require_once APP_ROOT . '/lib/layout_header.php';

$cClean    = count(array_filter($analyzed, fn($r) => $r['status'] === 'clean'));
$cSkip     = count(array_filter($analyzed, fn($r) => $r['status'] === 'skip'));
$cConflict = count(array_filter($analyzed, fn($r) => in_array($r['status'], ['ip_conflict','mac_conflict','reserved'])));
$cInvalid  = count(array_filter($analyzed, fn($r) => in_array($r['status'], ['invalid','pool'])));
?>

<div class="mb-3">
<?php if ($subnet): ?>
    <a href="subnet.php?id=<?= $subnetId ?>" class="text-muted text-decoration-none">
        <i class="bi bi-arrow-left"></i> <?= h($subnet['name']) ?>
    </a>
<?php else: ?>
    <a href="subnets.php" class="text-muted text-decoration-none">
        <i class="bi bi-arrow-left"></i> Subnets
    </a>
<?php endif; ?>
</div>

<?php if ($step === 0 || $parseError): ?>
<!-- ── Formulaire d'upload ─────────────────────────────────────────────────── -->
<div class="row justify-content-center">
<div class="col-lg-6">
<div class="card">
    <div class="card-header py-3">
        <i class="bi bi-upload me-2"></i><?= $multiMode ? 'Import CSV global (multi-subnet)' : 'Importer des réservations CSV' ?>
    </div>
    <div class="card-body">
        <?php if ($parseError): ?>
        <div class="alert alert-danger"><?= h($parseError) ?></div>
        <?php endif; ?>

        <?php if ($multiMode): ?>
        <div class="alert alert-info py-2 small">
            <i class="bi bi-info-circle me-1"></i>
            Mode multi-subnet : le CSV doit contenir une colonne <code>subnet</code> avec le nom exact du subnet de destination.
        </div>
        <?php endif; ?>

        <p class="text-muted small mb-3">
            Colonnes : <code>mac</code>, <code>ip</code>, <code>hostname</code><?= $multiMode ? ', <code>subnet</code>' : '' ?> (et optionnellement <code>description</code><?= $multiMode ? '' : ', <code>subnet</code>' ?>, <code>group</code>, <code>gateway</code>, <code>routes</code>, <code>short_lease</code>, <code>no_gateway</code>).<br>
            Format <code>routes</code> : <code>10.0.0.0/8-192.168.1.254|172.16.0.0/12-192.168.1.1</code> (routes séparées par <code>|</code>, CIDR<code>-</code>gateway).<br>
            Format <code>short_lease</code> : <code>1</code> pour activer le lease court (1h), <code>0</code> ou vide sinon.<br>
            Format <code>no_gateway</code> : <code>1</code> pour ne pas envoyer de gateway à l'hôte (l'emporte sur <code>gateway</code>), <code>0</code> ou vide sinon.<br>
            Délimiteur : virgule ou point-virgule. Encodage : UTF-8.
        </p>

        <form method="post" enctype="multipart/form-data">
            <input type="hidden" name="subnet_id" value="<?= $subnetId ?>">
            <input type="hidden" name="step" value="1">
            <div class="mb-3">
                <label class="form-label fw-semibold">Fichier CSV</label>
                <input type="file" name="csvfile" class="form-control" accept=".csv,text/csv" required>
            </div>
            <div class="d-flex gap-2">
                <button type="submit" class="btn btn-primary">
                    <i class="bi bi-search"></i> Analyser
                </button>
                <?php if ($subnet): ?>
                <a href="subnet_export.php?subnet_id=<?= $subnetId ?>&template=1"
                   class="btn btn-outline-secondary">
                    <i class="bi bi-download"></i> Télécharger le modèle
                </a>
                <?php endif; ?>
                <a href="<?= $subnet ? 'subnet.php?id=' . $subnetId : 'subnets.php' ?>"
                   class="btn btn-outline-secondary ms-auto">Annuler</a>
            </div>
        </form>
    </div>
</div>
</div>
</div>

<?php elseif ($step === 1 && $analyzed): ?>
<!-- ── Aperçu + résolution des conflits ───────────────────────────────────── -->

<div class="d-flex justify-content-between align-items-center mb-3">
    <div class="d-flex gap-2 flex-wrap">
        <span class="badge bg-success fs-6"><?= $cClean ?> à ajouter</span>
        <?php if ($cConflict): ?>
        <span class="badge bg-warning text-dark fs-6"><?= $cConflict ?> conflit(s)</span>
        <?php endif; ?>
        <?php if ($cSkip): ?>
        <span class="badge bg-secondary fs-6"><?= $cSkip ?> identique(s)</span>
        <?php endif; ?>
        <?php if ($cInvalid): ?>
        <span class="badge bg-danger fs-6"><?= $cInvalid ?> invalide(s)/bloqué(s)</span>
        <?php endif; ?>
    </div>
    <a href="subnet_import.php?subnet_id=<?= $subnetId ?>" class="btn btn-sm btn-outline-secondary">
        <i class="bi bi-upload"></i> Changer de fichier
    </a>
</div>

<?php if (!$multiMode && $subnet):
    require_once __DIR__ . '/../lib/sbg_helpers.php';
    $sbgSubnet = buildBargraphSubnet($subnet);
?>
<div id="subnet-bargraph" class="mb-3"></div>
<?php endif; ?>

<form method="post" id="copy-apply-form">
    <input type="hidden" name="subnet_id" value="<?= $subnetId ?>">
    <input type="hidden" name="step" value="2">

    <div class="card mb-3">
    <div class="card-body p-0">
    <div class="table-responsive">
    <table class="table table-sm mb-0 align-middle">
        <thead class="table-light">
            <tr>
                <th class="ps-3" style="width:40px">#</th>
                <th>MAC</th>
                <th>IP</th>
                <th>Hostname</th>
                <?php if ($multiMode || $hasSubnetCol): ?>
                <th>Subnet</th>
                <?php endif; ?>
                <th>Options DHCP</th>
                <th>État</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
        <?php foreach ($analyzed as $i => $row):
            $rowCls = match($row['status']) {
                'clean'        => '',
                'skip'         => 'table-secondary',
                'ip_conflict'  => 'table-warning',
                'reserved'     => 'table-warning',
                'mac_conflict' => 'table-info',
                default        => 'table-danger',
            };
        ?>
        <tr class="copy-row <?= $rowCls ?>">
            <td class="ps-3 text-muted small"><?= $row['line'] ?></td>
            <td class="font-monospace small"><?= h($row['mac']) ?></td>
            <td class="font-monospace small"><?= h($row['ip']) ?></td>
            <td class="small"><?= h($row['hostname']) ?></td>

            <?php if ($multiMode || $hasSubnetCol): ?>
            <td class="small">
                <?php if ($row['subnet_name']): ?>
                    <span class="badge bg-secondary"><?= h($row['subnet_name']) ?></span>
                <?php else: ?>
                    <span class="text-danger">—</span>
                <?php endif; ?>
            </td>
            <?php endif; ?>

            <!-- Options DHCP -->
            <td class="small">
            <?php
                $gw = $row['gateway'] ?? '';
                $rr = $row['routes_raw'] ?? '';
                $ng = (int)($row['no_gateway'] ?? 0);
                if ($ng || $gw !== '' || $rr !== ''):
            ?>
                <?php if ($ng): ?>
                    <span class="badge bg-dark" title="Ne pas envoyer de gateway">no-gateway</span><br>
                <?php elseif ($gw !== ''): ?>
                    <span class="text-muted">GW&nbsp;</span><code><?= h($gw) ?></code><br>
                <?php endif; ?>
                <?php if ($rr !== ''): ?>
                    <?php foreach (explode('|', $rr) as $rt): $rt = trim($rt); if ($rt === '') continue; ?>
                    <code class="d-block"><?= h($rt) ?></code>
                    <?php endforeach; ?>
                <?php endif; ?>
            <?php else: ?>
                <span class="text-muted">—</span>
            <?php endif; ?>
            </td>

            <!-- État -->
            <td class="small">
            <?php match($row['status']) {
                'clean'        => print '<span class="badge bg-success">Nouveau</span>',
                'skip'         => print '<span class="badge bg-secondary">Identique</span>',
                'pool'         => print '<span class="badge bg-warning text-dark" title="' . h($row['note']) . '">Pool dyn.</span>',
                'invalid'      => print '<span class="badge bg-danger" title="' . h($row['note']) . '">Invalide</span> <small class="text-danger">' . h($row['note']) . '</small>',
                'ip_conflict'  => print '<span class="badge bg-warning text-dark">IP prise</span><br><small class="text-muted">' . h($row['ip_taken_by']) . '</small>',
                'reserved'     => print '<span class="badge bg-warning text-dark" title="' . h($row['note']) . '">IP réservée</span><br><small class="text-muted">' . h($row['note']) . '</small>',
                'mac_conflict' => print '<span class="badge bg-info text-dark">MAC connue</span><br><small class="text-muted">IP actuelle : ' . h($row['mac_existing_ip']) . '</small>',
                default        => print '',
            }; ?>
            </td>

            <!-- Champs cachés -->
            <input type="hidden" name="r[<?= $i ?>][line]"          value="<?= $row['line'] ?>">
            <input type="hidden" name="r[<?= $i ?>][mac]"           value="<?= h($row['mac']) ?>">
            <input type="hidden" name="r[<?= $i ?>][ip]"            value="<?= h($row['ip']) ?>">
            <input type="hidden" name="r[<?= $i ?>][hostname]"      value="<?= h($row['hostname']) ?>">
            <input type="hidden" name="r[<?= $i ?>][description]"   value="<?= h($row['description']) ?>">
            <input type="hidden" name="r[<?= $i ?>][gateway]"       value="<?= h($row['gateway'] ?? '') ?>">
            <input type="hidden" name="r[<?= $i ?>][routes_raw]"    value="<?= h($row['routes_raw'] ?? '') ?>">
            <input type="hidden" name="r[<?= $i ?>][short_lease]"   value="<?= (int)($row['short_lease'] ?? 0) ?>">
            <input type="hidden" name="r[<?= $i ?>][no_gateway]"    value="<?= (int)($row['no_gateway'] ?? 0) ?>">
            <input type="hidden" name="r[<?= $i ?>][group_name]"    value="<?= h($row['group_name'] ?? '') ?>">
            <input type="hidden" name="r[<?= $i ?>][status]"        value="<?= h($row['status']) ?>">
            <input type="hidden" name="r[<?= $i ?>][mac_host_id]"   value="<?= (int)($row['mac_host_id'] ?? 0) ?>">
            <input type="hidden" name="r[<?= $i ?>][kea_subnet_id]" value="<?= (int)($row['kea_subnet_id'] ?? 0) ?>">
            <input type="hidden" name="r[<?= $i ?>][subnet_id]"     value="<?= (int)($row['subnet_id'] ?? 0) ?>">

            <!-- Action -->
            <td>
            <?php if ($row['status'] === 'clean'): ?>
                <input type="hidden" name="r[<?= $i ?>][action]" value="add">
                <span class="text-success small"><i class="bi bi-plus-circle"></i> Ajouter</span>

            <?php elseif (in_array($row['status'], ['skip', 'invalid', 'pool'])): ?>
                <input type="hidden" name="r[<?= $i ?>][action]" value="skip">
                <span class="text-muted small"><i class="bi bi-dash-circle"></i> Ignoré</span>

            <?php elseif ($row['status'] === 'ip_conflict'): ?>
                <div class="d-flex align-items-start gap-2 flex-wrap">
                    <input type="hidden" name="r[<?= $i ?>][action]" value="new_ip">
                    <div>
                        <input type="text" name="r[<?= $i ?>][new_ip]"
                               id="new-ip-<?= $i ?>"
                               data-fb="fb-ip-<?= $i ?>"
                               data-subnet="<?= (int)($row['kea_subnet_id'] ?? 0) ?>"
                               class="form-control form-control-sm font-monospace new-ip-field ip-field"
                               style="width:175px"
                               placeholder="Nouvelle IP"
                               title="Laisser vide pour ignorer">
                        <div id="fb-ip-<?= $i ?>" class="form-text mt-1" style="min-width:175px"></div>
                    </div>
                    <small class="text-muted mt-1">vide = ignorer</small>
                </div>

            <?php elseif ($row['status'] === 'reserved'): ?>
                <div class="d-flex align-items-start gap-2 flex-wrap">
                    <input type="hidden" name="r[<?= $i ?>][action]" value="new_ip">
                    <div>
                        <input type="text" name="r[<?= $i ?>][new_ip]"
                               id="new-ip-<?= $i ?>"
                               data-fb="fb-ip-<?= $i ?>"
                               data-subnet="<?= (int)($row['kea_subnet_id'] ?? 0) ?>"
                               class="form-control form-control-sm font-monospace new-ip-field ip-field"
                               style="width:175px"
                               placeholder="Nouvelle IP"
                               title="Laisser vide pour ignorer">
                        <div id="fb-ip-<?= $i ?>" class="form-text mt-1" style="min-width:175px"></div>
                    </div>
                    <small class="text-muted mt-1">vide = ignorer</small>
                </div>

            <?php elseif ($row['status'] === 'mac_conflict'): ?>
                <div class="d-flex flex-column gap-1">
                    <select name="r[<?= $i ?>][action]"
                            class="form-select form-select-sm mac-action-sel"
                            style="width:200px"
                            data-idx="<?= $i ?>">
                        <option value="update">Mettre à jour → <?= h($row['ip']) ?></option>
                        <option value="keep">Conserver l'existant</option>
                        <option value="custom_ip">Autre IP…</option>
                    </select>
                    <div>
                        <input type="text"
                               name="r[<?= $i ?>][new_ip]"
                               id="custom-ip-<?= $i ?>"
                               data-fb="fb-ip-<?= $i ?>"
                               data-subnet="<?= (int)($row['kea_subnet_id'] ?? 0) ?>"
                               class="form-control form-control-sm font-monospace d-none new-ip-field ip-field"
                               style="width:175px"
                               placeholder="IP personnalisée">
                        <div id="fb-ip-<?= $i ?>" class="form-text mt-1 d-none" style="min-width:175px"></div>
                    </div>
                </div>
            <?php endif; ?>
            </td>
        </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
    </div>
    </div>
    </div>

    <div class="d-flex gap-2">
        <?php if ($cClean + $cConflict > 0): ?>
        <button type="submit" class="btn btn-primary">
            <i class="bi bi-check-lg"></i> Confirmer l'import
        </button>
        <?php else: ?>
        <button type="submit" class="btn btn-primary" disabled>
            <i class="bi bi-check-lg"></i> Confirmer l'import
        </button>
        <?php endif; ?>
        <a href="<?= $subnet ? 'subnet.php?id=' . $subnetId : 'subnets.php' ?>"
           class="btn btn-outline-secondary">Annuler</a>
    </div>
</form>

<script>
(function () {
'use strict';

// Tous les champs new_ip du formulaire (visibles ou non)
var newIpInputs = Array.from(document.querySelectorAll('.new-ip-field'));

function getFeedback(input) {
    var id = input.dataset.fb;
    return id ? document.getElementById(id) : null;
}

function getOtherValues(skipInput) {
    return newIpInputs
        .filter(function (inp) {
            return inp !== skipInput
                && !inp.classList.contains('d-none')
                && inp.value.trim() !== ''
                && inp.dataset.subnet === skipInput.dataset.subnet;
        })
        .map(function (inp) { return inp.value.trim().toLowerCase(); });
}

function setFeedback(input, type, html) {
    var fb = getFeedback(input);
    input.classList.remove('is-valid', 'is-invalid');
    if (!fb) return;
    if (type === 'valid') {
        input.classList.add('is-valid');
        fb.className = 'form-text text-success mt-1';
    } else if (type === 'invalid') {
        input.classList.add('is-invalid');
        fb.className = 'form-text text-danger mt-1';
    } else {
        fb.className = 'form-text mt-1';
    }
    fb.innerHTML = html;
}

function validateIp(input) {
    var val       = input.value.trim();
    var subnetId  = input.dataset.subnet;

    if (input.classList.contains('d-none') || !val) {
        setFeedback(input, 'none', '');
        return;
    }

    if (getOtherValues(input).indexOf(val.toLowerCase()) !== -1) {
        setFeedback(input, 'invalid', '<i class="bi bi-x-circle-fill"></i> Déjà utilisée dans cet import.');
        return;
    }

    fetch('api_check_duplicate.php?type=ip&value=' + encodeURIComponent(val) + '&subnet_id=' + subnetId)
        .then(function (r) { return r.json(); })
        .then(function (d) {
            if (d.invalid) { setFeedback(input, 'none', ''); return; }
            if (d.duplicate) {
                setFeedback(input, 'invalid', '<i class="bi bi-x-circle-fill"></i> ' + (d.message || 'IP non disponible.'));
            } else {
                if (getOtherValues(input).indexOf(val.toLowerCase()) !== -1) {
                    setFeedback(input, 'invalid', '<i class="bi bi-x-circle-fill"></i> Déjà utilisée dans cet import.');
                } else {
                    setFeedback(input, 'valid', '<i class="bi bi-check-circle-fill"></i> Disponible');
                }
            }
        })
        .catch(function () {});
}

function revalidateOthers(changedInput) {
    newIpInputs
        .filter(function (inp) {
            return inp !== changedInput
                && !inp.classList.contains('d-none')
                && inp.value.trim() !== ''
                && inp.dataset.subnet === changedInput.dataset.subnet;
        })
        .forEach(validateIp);
}

newIpInputs.forEach(function (input) {
    input.addEventListener('blur',  function () { validateIp(this); });
    input.addEventListener('input', function () { revalidateOthers(this); });
});

document.querySelectorAll('.mac-action-sel').forEach(function (sel) {
    sel.addEventListener('change', function () {
        var idx   = this.dataset.idx;
        var input = document.getElementById('custom-ip-' + idx);
        var fb    = document.getElementById('fb-ip-' + idx);

        if (this.value === 'custom_ip') {
            input.classList.remove('d-none');
            if (fb) fb.classList.remove('d-none');
            input.required = true;
            if (input.value.trim()) validateIp(input);
        } else {
            input.classList.add('d-none');
            if (fb) { fb.classList.add('d-none'); fb.innerHTML = ''; fb.className = 'form-text mt-1 d-none'; }
            input.classList.remove('is-valid', 'is-invalid');
            input.required = false;
            input.value = '';
            revalidateOthers(input);
        }
    });
});

}());
</script>

<?php if (!$multiMode && $subnet): ?>
<script>
  var SUBNET = <?= json_encode($sbgSubnet, JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP) ?>;
  var EXISTING_ROWS = <?= json_encode(array_map(function($r){
      return ['ip_int'=>($r['ip_address']!==''&&$r['ip_address']!=='0.0.0.0')?(int)ipToInt($r['ip_address']):0,
              'hostname'=>$r['hostname'],'host_id'=>(int)$r['host_id'],'group_name'=>$r['group_name']??'','short_lease'=>(int)($r['short_lease']??0)];
  }, Reservation::getBySubnet($subnet['kea_subnet_id'])), JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP) ?>;
</script>
<script src="assets/js/subnet-bargraph.js"></script>
<script src="assets/js/subnet-copy.js"></script>
<?php endif; ?>

<?php elseif ($step === 1 && !$parseError): ?>
<div class="alert alert-info">Le fichier CSV ne contient aucune ligne de données.</div>
<?php endif; ?>

<?php require_once APP_ROOT . '/lib/layout_footer.php'; ?>
