<?php

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

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

/** Normalise un MAC en minuscules séparés par ':'. */
function normalizeMac(string $raw): string {
    $hex = strtolower(preg_replace('/[^0-9a-fA-F]/', '', $raw));
    return implode(':', str_split($hex, 2));
}

/** Vérifie qu'une IP est dans le pool dynamique d'un subnet. */
function inPool(string $ip, array $subnet): bool {
    if (!$subnet['has_dynamic_pool'] || !$subnet['range_start'] || !$subnet['range_end']) {
        return false;
    }
    $n = ip2long($ip);
    return $n >= ip2long($subnet['range_start']) && $n <= ip2long($subnet['range_end']);
}

/** 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);

    $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] ?? '') : '',
        ];
    }
    fclose($handle);
    return ['rows' => $rows, 'has_subnet_col' => $idxSubnet !== false];
}

/**
 * Analyse les conflits d'un tableau de lignes CSV brutes.
 *
 * @param array      $rawRows       Lignes issues de parseCsv()
 * @param array|null $defaultSubnet Subnet par défaut (null si import global)
 * @param array      $allSubnets    Tous les subnets indexés par name (lowercase)
 * @param bool       $hasSubnetCol  Le CSV contient-il une colonne subnet ?
 */
function analyzeRows(array $rawRows, ?array $defaultSubnet, array $subnetsByName, bool $hasSubnetCol): array {
    // Cache des réservations existantes par kea_subnet_id
    $existingCache = [];
    $getExisting   = function(int $keaId) use (&$existingCache): array {
        if (!isset($existingCache[$keaId])) {
            $rows = Reservation::getBySubnet($keaId);
            $byIp  = [];
            $byMac = [];
            foreach ($rows as $r) {
                $byIp[$r['ip_address']] = $r;
                $byMac[$r['mac']]       = $r;
            }
            $existingCache[$keaId] = ['byIp' => $byIp, 'byMac' => $byMac];
        }
        return $existingCache[$keaId];
    };

    $analyzed = [];

    foreach ($rawRows as $r) {
        $macRaw  = $r['mac_raw'];
        $ip      = $r['ip'];
        $host    = $r['hostname'];
        $desc    = $r['description'];
        $lineNum = $r['line'];
        $csvSubnetName = $r['subnet_name'] ?? '';

        // ── Résolution du subnet ───────────────────────────────────────────────
        $subnet = null;
        if ($hasSubnetCol) {
            if ($csvSubnetName === '') {
                $analyzed[] = ['line'=>$lineNum,'mac'=>$macRaw,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                    'status'=>'invalid','note'=>'Colonne subnet vide',
                    'subnet_id'=>null,'subnet_name'=>'','kea_subnet_id'=>null,
                    'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];
                continue;
            }
            $key = strtolower($csvSubnetName);
            if (!isset($subnetsByName[$key])) {
                $analyzed[] = ['line'=>$lineNum,'mac'=>$macRaw,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                    'status'=>'invalid','note'=>'Subnet inconnu : « ' . $csvSubnetName . ' »',
                    'subnet_id'=>null,'subnet_name'=>$csvSubnetName,'kea_subnet_id'=>null,
                    'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];
                continue;
            }
            $subnet = $subnetsByName[$key];
        } elseif ($defaultSubnet) {
            $subnet = $defaultSubnet;
        } else {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$macRaw,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'invalid','note'=>'Subnet non déterminé (colonne subnet absente du CSV)',
                'subnet_id'=>null,'subnet_name'=>'','kea_subnet_id'=>null,
                'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];
            continue;
        }

        $keaSubnetId  = (int)$subnet['kea_subnet_id'];
        $subnetAppId  = (int)$subnet['id'];
        $subnetLabel  = $subnet['name'];

        // ── Normalisation MAC ──────────────────────────────────────────────────
        $mac = '';
        if (!empty($macRaw)) {
            $hexOnly = preg_replace('/[^0-9a-fA-F]/', '', $macRaw);
            if (strlen($hexOnly) === 12) {
                $mac = normalizeMac($macRaw);
            }
        }

        // ── Validation format ──────────────────────────────────────────────────
        if ($mac === '' || !isValidMac($mac)) {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$macRaw,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'invalid','note'=>'Format MAC invalide',
                'subnet_id'=>$subnetAppId,'subnet_name'=>$subnetLabel,'kea_subnet_id'=>$keaSubnetId,
                'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];
            continue;
        }
        if (!isValidIp($ip)) {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$mac,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'invalid','note'=>'Format IP invalide',
                'subnet_id'=>$subnetAppId,'subnet_name'=>$subnetLabel,'kea_subnet_id'=>$keaSubnetId,
                'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];
            continue;
        }
        if (empty($host)) {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$mac,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'invalid','note'=>'Hostname obligatoire',
                'subnet_id'=>$subnetAppId,'subnet_name'=>$subnetLabel,'kea_subnet_id'=>$keaSubnetId,
                'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];
            continue;
        }
        if (!preg_match('/^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?$/', $host)) {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$mac,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'invalid','note'=>'Hostname invalide (lettres, chiffres, tirets)',
                'subnet_id'=>$subnetAppId,'subnet_name'=>$subnetLabel,'kea_subnet_id'=>$keaSubnetId,
                'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];
            continue;
        }
        if (!ipInCidr($ip, $subnet['cidr'])) {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$mac,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'invalid','note'=>'IP hors subnet ' . $subnet['cidr'],
                'subnet_id'=>$subnetAppId,'subnet_name'=>$subnetLabel,'kea_subnet_id'=>$keaSubnetId,
                'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];
            continue;
        }
        if (inPool($ip, $subnet)) {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$mac,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'pool','note'=>'IP dans le pool dynamique (' . $subnet['range_start'] . '–' . $subnet['range_end'] . ')',
                'subnet_id'=>$subnetAppId,'subnet_name'=>$subnetLabel,'kea_subnet_id'=>$keaSubnetId,
                'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];
            continue;
        }

        // ── Analyse conflits ───────────────────────────────────────────────────
        $existing = $getExisting($keaSubnetId);
        $macEntry = $existing['byMac'][$mac] ?? null;
        $ipEntry  = $existing['byIp'][$ip]   ?? null;

        if ($macEntry && $ipEntry && $macEntry['host_id'] === $ipEntry['host_id']) {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$mac,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'skip','note'=>'Déjà existant (identique)',
                'subnet_id'=>$subnetAppId,'subnet_name'=>$subnetLabel,'kea_subnet_id'=>$keaSubnetId,
                'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];

        } elseif ($ipEntry) {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$mac,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'ip_conflict','note'=>'IP déjà utilisée par ' . $ipEntry['mac'],
                'subnet_id'=>$subnetAppId,'subnet_name'=>$subnetLabel,'kea_subnet_id'=>$keaSubnetId,
                'ip_taken_by'    => $ipEntry['mac'],
                'mac_host_id'    => $macEntry ? (int)$macEntry['host_id'] : null,
                'mac_existing_ip'=> $macEntry ? $macEntry['ip_address'] : null];

        } elseif ($macEntry) {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$mac,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'mac_conflict','note'=>'MAC déjà réservée avec l\'IP ' . $macEntry['ip_address'],
                'subnet_id'=>$subnetAppId,'subnet_name'=>$subnetLabel,'kea_subnet_id'=>$keaSubnetId,
                'ip_taken_by'    => null,
                'mac_host_id'    => (int)$macEntry['host_id'],
                'mac_existing_ip'=> $macEntry['ip_address']];

        } else {
            $analyzed[] = ['line'=>$lineNum,'mac'=>$mac,'ip'=>$ip,'hostname'=>$host,'description'=>$desc,
                'status'=>'clean','note'=>'Nouveau',
                'subnet_id'=>$subnetAppId,'subnet_name'=>$subnetLabel,'kea_subnet_id'=>$keaSubnetId,
                'mac_host_id'=>null,'ip_taken_by'=>null,'mac_existing_ip'=>null];
        }
    }
    return $analyzed;
}

// ── 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);

        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];

        // ── Ligne propre ──────────────────────────────────────────────────────
        if ($status === 'clean') {
            if (isset($existingIps[$ip]) || isset($batchIps[$keaSubnetId][$ip])) {
                $errMessages[] = "Ligne $lineNum ($ip) : IP déjà utilisée.";
                $skipped++;
                continue;
            }
            try {
                Reservation::add($keaSubnetId, $data);
                $batchIps[$keaSubnetId][$ip] = true;
                $touchedSubnetIds[$subnetAppId] = true;
                $applied++;
            } catch (Throwable $e) {
                $errMessages[] = "Ligne $lineNum : " . $e->getMessage();
            }
            continue;
        }

        // ── Conflit IP ────────────────────────────────────────────────────────
        if ($status === 'ip_conflict') {
            $targetIp = $newIp;
            if (!$targetIp) { $skipped++; continue; }
            if (!isValidIp($targetIp))               { $errMessages[] = "Ligne $lineNum : IP « $targetIp » invalide."; $skipped++; continue; }
            if (!ipInCidr($targetIp, $allSubnets[array_search($subnetAppId, array_column($allSubnets,'id'))]['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;
            }
            $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     = 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'])));
$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>' ?>).<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>

<form method="post">
    <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>É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',
                'mac_conflict' => 'table-info',
                default        => 'table-danger',
            };
        ?>
        <tr class="<?= $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; ?>

            <!-- É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>',
                '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 ?>][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"
                               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"
                               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 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'; ?>
