<template>
  <div
    v-if="showOnlyFilters"
    class="bg-monokai-bg border-t border-monokai-comment"
    :style="detailsStyles"
  >
    <div class="p-3">
      <div class="flex items-center justify-between mb-2">
        <div class="text-xs font-bold text-monokai-green no-select">Recherche</div>
        <label class="flex items-center gap-2 text-xs text-monokai-text">
          <input v-model="invertSearch" type="checkbox" class="form-checkbox" />
          Inverser
        </label>
      </div>
      <div class="relative">
        <input
          v-model="searchQuery"
          type="text"
          class="w-full pl-3 pr-8 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text text-sm"
          placeholder="Rechercher dans toutes les cellules"
          title="Recherche multi-termes, insensible à la casse et aux accents"
        />
        <button
          v-if="searchQuery"
          @click="searchQuery = ''"
          class="absolute right-2 top-1/2 -translate-y-1/2 w-6 h-6 rounded-full flex items-center justify-center text-monokai-bg bg-monokai-cyan hover:bg-monokai-green shadow"
          aria-label="Effacer la recherche"
          title="Effacer la recherche"
        >
          ✕
        </button>
      </div>
      <div class="grid grid-cols-3 gap-2 mt-2">
        <div>
          <div class="text-[10px] font-semibold text-monokai-comment mb-1 no-select">Statut</div>
          <div class="flex flex-col gap-1">
            <button
              v-for="tag in tagGroups.status"
              :key="tag.value"
              @click="toggleTag(tag.value)"
              class="w-full px-1.5 py-0.5 text-[10px] leading-tight rounded-full border border-transparent transition-colors hover:opacity-80 shadow-sm text-left"
              :class="isTagActive(tag.value) ? 'ring-2 ring-monokai-text/40 shadow-inner font-semibold border-monokai-text/60' : ''"
              :style="tag.style"
            >
              {{ tag.label }}
            </button>
          </div>
        </div>
        <div>
          <div class="text-[10px] font-semibold text-monokai-comment mb-1 no-select">Type d'hote</div>
          <div class="flex flex-col gap-1">
            <button
              v-for="tag in tagGroups.host"
              :key="tag.value"
              @click="toggleTag(tag.value)"
              class="w-full px-1.5 py-0.5 text-[10px] leading-tight rounded-full border border-transparent transition-colors hover:opacity-80 shadow-sm text-left"
              :class="isTagActive(tag.value) ? 'ring-2 ring-monokai-text/40 shadow-inner font-semibold border-monokai-text/60' : ''"
              :style="tag.style"
            >
              {{ tag.label }}
            </button>
          </div>
        </div>
        <div>
          <div class="text-[10px] font-semibold text-monokai-comment mb-1 no-select">Localisation</div>
          <div class="flex flex-col gap-1">
            <button
              v-for="tag in tagGroups.location"
              :key="tag.value"
              @click="toggleTag(tag.value)"
              class="w-full px-1.5 py-0.5 text-[10px] leading-tight rounded-full border border-transparent transition-colors hover:opacity-80 shadow-sm text-left"
              :class="isTagActive(tag.value) ? 'ring-2 ring-monokai-text/40 shadow-inner font-semibold border-monokai-text/60' : ''"
              :style="tag.style"
            >
              {{ tag.label }}
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div
    v-else
    class="h-full flex flex-col bg-monokai-bg border-r border-monokai-comment"
    :style="detailsStyles"
  >
    <!-- Contenu scrollable -->
    <div class="flex-1 overflow-hidden flex flex-col">
      <div v-if="selectedIP" class="flex flex-col h-full">
        <!-- Section fixe (sticky) : IP et État sur la même ligne -->
        <div class="bg-monokai-bg border-b border-monokai-comment" :style="headerPadding">
          <div class="flex items-center justify-between gap-2">
            <!-- Adresse IP -->
            <div class="flex-1 min-w-0">
              <a
                v-if="selectedIP.link"
                :href="selectedIP.link"
                target="_blank"
                class="font-mono font-bold text-monokai-green hover:text-monokai-cyan transition-colors cursor-pointer underline block truncate"
                :style="{ fontSize: ipFontSize }"
              >
                {{ selectedIP.ip }}
              </a>
              <div v-else class="font-mono font-bold text-monokai-green truncate" :style="{ fontSize: ipFontSize }">
                {{ selectedIP.ip }}
              </div>
            </div>

            <!-- État -->
            <div class="flex items-center gap-1 flex-shrink-0">
              <div
                :class="[
                  'w-2 h-2 rounded-full',
                  selectedIP.last_status === 'online' ? 'bg-monokai-green' : 'bg-monokai-pink'
                ]"
              ></div>
              <span class="text-monokai-text capitalize text-xs">
                {{ selectedIP.last_status || 'Inconnu' }}
              </span>
            </div>
          </div>
        </div>

        <!-- Section scrollable : Formulaire et reste -->
        <div class="flex-1 overflow-auto" :style="contentPadding">
          <!-- Formulaire d'édition -->
          <div :style="formSpacing">
            <!-- Nom -->
            <div>
              <div class="flex items-center justify-between mb-1">
                <label class="text-sm text-monokai-comment block no-select">Nom</label>
                <button
                  @click="openIconModal"
                  class="p-1 rounded bg-monokai-comment/30 text-monokai-text hover:bg-monokai-comment/50 transition-colors"
                  title="Associer une icône"
                >
                  <span class="mdi mdi-image-outline text-base"></span>
                </button>
              </div>
              <div class="flex items-center gap-3">
                <input
                  v-model="formData.name"
                  type="text"
                  class="w-[60%] px-3 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text"
                  placeholder="Ex: Serveur Principal"
                />
                <div class="flex-shrink-0">
                  <img
                    v-if="selectedIP?.icon_filename"
                    :src="`/icons/${selectedIP.icon_filename}`"
                    alt="Icône"
                    class="w-12 h-12 object-contain rounded-sm border border-monokai-comment/40"
                    style="box-shadow: 0 0 10px rgba(230, 219, 116, 0.4);"
                  />
                </div>
              </div>
            </div>

            <!-- Connue / Suivie / VM -->
            <div class="flex flex-wrap gap-4">
              <label class="flex items-center gap-2 cursor-pointer">
                <input
                  v-model="formData.known"
                  type="checkbox"
                  class="form-checkbox"
                  title="Marquer cette IP comme connue"
                />
                <span class="text-sm text-monokai-text no-select">IP connue</span>
              </label>
              <label class="flex items-center gap-2 cursor-pointer">
                <input
                  v-model="formData.tracked"
                  type="checkbox"
                  class="form-checkbox"
                  title="Afficher cette IP dans la page de suivi"
                />
                <span class="text-sm text-monokai-text no-select">IP suivie</span>
              </label>
              <label class="flex items-center gap-2 cursor-pointer">
                <input
                  v-model="formData.vm"
                  type="checkbox"
                  class="form-checkbox"
                  title="Marquer comme machine virtuelle"
                />
                <span class="text-sm text-monokai-text no-select">VM</span>
              </label>
              <label class="flex items-center gap-2" :title="selectedIP?.dhcp_synced ? 'Réservation DHCP active dans Kea' : 'Pas de réservation DHCP'">
                <input
                  :checked="selectedIP?.dhcp_synced"
                  type="checkbox"
                  class="form-checkbox"
                  disabled
                  :style="{ accentColor: selectedIP?.dhcp_synced ? '#A6E22E' : '#75715E' }"
                />
                <span class="text-sm no-select" :class="selectedIP?.dhcp_synced ? 'text-monokai-green' : 'text-monokai-comment'">DHCP réservé</span>
              </label>
            </div>

            <!-- Type d'hôte + Localisation -->
            <div class="flex gap-3">
              <div class="flex-1 min-w-0">
                <label class="text-sm text-monokai-comment mb-1 block no-select">Type d'hôte</label>
                <select
                  v-model="formData.host"
                  @change="onHostChange"
                  class="w-full px-3 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text"
                >
                  <option value="">-- Sélectionner --</option>
                  <option v-for="host in hosts" :key="host.name" :value="host.name">{{ host.name }}</option>
                </select>
              </div>

              <div class="flex-1 min-w-0">
                <label class="text-sm text-monokai-comment mb-1 block no-select">Localisation</label>
                <select
                  v-model="formData.location"
                  class="w-full px-3 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text"
                >
                  <option value="">-- Sélectionner --</option>
                  <option v-for="loc in locations" :key="loc" :value="loc">{{ loc }}</option>
                </select>
              </div>
            </div>

            <!-- Lien -->
            <div>
              <label class="text-sm text-monokai-comment mb-1 block no-select">Lien (URL)</label>
              <input
                v-model="formData.link"
                type="url"
                class="w-full px-3 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text"
                placeholder="https://exemple.com"
              />
            </div>

            <!-- Lien hardware bench -->
            <div class="flex items-center gap-3">
              <label class="flex items-center gap-2 cursor-pointer">
                <input v-model="formData.hardware_bench" type="checkbox" class="form-checkbox" title="Activer le lien hardware bench" />
                <span class="text-sm text-monokai-text no-select">Hardware bench</span>
              </label>
              <button
                @click="openHardwareBench"
                :disabled="!hardwareBenchUrl || !formData.hardware_bench"
                class="p-2 rounded bg-monokai-cyan text-monokai-bg hover:bg-monokai-green transition-colors disabled:opacity-40"
                title="Ouvrir la page hardware bench"
              >
                <img :src="hardwareBenchIconUrl" alt="Hardware bench" class="w-5 h-5" />
              </button>
            </div>

          </div>

          <!-- Informations réseau -->
          <div class="border-t border-monokai-comment" :style="{ paddingTop: `${uiConfig.details_spacing * 2}px`, marginTop: `${uiConfig.details_spacing * 2}px` }">
            <div :style="formSpacing">
              <div class="flex items-center justify-between">
                <h3 class="text-monokai-cyan font-bold mb-2">Informations réseau</h3>
                <div class="flex items-center gap-2">
                  <button
                    @click="toggleNetworkEdit"
                    class="p-1 rounded bg-monokai-comment/30 text-monokai-text hover:bg-monokai-comment/50 transition-colors"
                    :class="[
                      networkDirty ? 'animate-pulse' : '',
                      networkEditMode ? 'ring-2 ring-monokai-cyan/50 bg-monokai-cyan/10' : ''
                    ]"
                    title="Éditer MAC / Fabricant / Hostname"
                  >
                    <span class="mdi mdi-pencil"></span>
                  </button>
                </div>
              </div>

              <div class="flex items-start gap-4">
                <div class="flex-1 min-w-0">
                  <div class="text-sm text-monokai-comment">MAC</div>
                  <div v-if="networkEditMode">
                    <input
                      v-model="networkForm.mac"
                      type="text"
                      class="w-full px-2 py-1 bg-monokai-bg border border-monokai-comment rounded text-monokai-text font-mono"
                      placeholder="00:00:00:00:00:00"
                    />
                  </div>
                  <button
                    v-else
                    @click="copyField('mac', selectedIP.mac)"
                    class="text-monokai-text font-mono truncate text-left hover:text-monokai-cyan transition-colors"
                    :title="selectedIP.mac ? (copiedField === 'mac' ? 'Copié' : 'Cliquer pour copier') : ''"
                  >
                    {{ selectedIP.mac || '—' }}
                  </button>
                </div>
                <div class="flex-1 min-w-0">
                  <div class="text-sm text-monokai-comment">Fabricant</div>
                  <div v-if="networkEditMode">
                    <input
                      v-model="networkForm.vendor"
                      type="text"
                      class="w-full px-2 py-1 bg-monokai-bg border border-monokai-comment rounded text-monokai-text"
                      placeholder="Fabricant"
                    />
                  </div>
                  <button
                    v-else
                    @click="copyField('vendor', selectedIP.vendor)"
                    class="text-monokai-text text-left whitespace-normal break-words hover:text-monokai-cyan transition-colors"
                    :title="selectedIP.vendor ? (copiedField === 'vendor' ? 'Copié' : 'Cliquer pour copier') : ''"
                  >
                    {{ selectedIP.vendor || '—' }}
                  </button>
                </div>
              </div>

              <div>
                <div class="text-sm text-monokai-comment">Hostname</div>
                <div class="flex items-center justify-between gap-3">
                  <div v-if="networkEditMode" class="flex-1">
                    <input
                      v-model="networkForm.hostname"
                      type="text"
                      class="w-full px-2 py-1 bg-monokai-bg border border-monokai-comment rounded text-monokai-text font-mono"
                      placeholder="hostname.local"
                    />
                  </div>
                  <button
                    v-else
                    @click="copyField('hostname', selectedIP.hostname)"
                    class="text-monokai-text font-mono text-left hover:text-monokai-cyan transition-colors"
                    :title="selectedIP.hostname ? (copiedField === 'hostname' ? 'Copié' : 'Cliquer pour copier') : ''"
                  >
                    {{ selectedIP.hostname || '—' }}
                  </button>
                </div>
              </div>

              <div v-if="selectedIP.open_ports && selectedIP.open_ports.length > 0">
                <div class="text-sm text-monokai-comment">Ports ouverts</div>
                <div class="flex flex-wrap gap-1 mt-1">
                  <a
                    v-for="port in selectedIP.open_ports"
                    :key="port"
                    :href="getPortUrl(port)"
                    :target="getPortUrl(port) ? '_blank' : undefined"
                    :class="[
                      'px-2 py-1 rounded text-xs font-mono',
                      getPortUrl(port)
                        ? 'bg-monokai-cyan/20 text-monokai-cyan hover:bg-monokai-cyan/30 cursor-pointer underline'
                        : 'bg-monokai-cyan/20 text-monokai-cyan cursor-default'
                    ]"
                    :title="getPortUrl(port) ? `Ouvrir ${portProtocols[port] || portProtocols[String(port)]}://${selectedIP.ip}:${port}` : `Port ${port}`"
                  >
                    {{ port }}
                  </a>
                </div>
              </div>

              <!-- Boutons d'action avec icônes -->
              <div class="flex gap-2 justify-center" :style="{ marginTop: `${uiConfig.details_spacing * 3}px` }">
                <button
                  @click="saveChanges"
                  :class="[
                    'p-2 rounded transition-colors',
                    saveButtonState === 'saved'
                      ? 'bg-green-800 text-monokai-text'
                      : 'bg-monokai-green text-monokai-bg hover:bg-monokai-cyan',
                    isDirty && saveButtonState === 'idle'
                      ? 'ring-2 ring-monokai-yellow ring-offset-2 ring-offset-monokai-bg animate-pulse'
                      : ''
                  ]"
                  :disabled="saveButtonState === 'saving'"
                  title="Enregistrer les modifications"
                >
                  <span class="mdi mdi-content-save text-xl"></span>
                </button>
                <button
                  @click="scanPorts"
                  :class="[
                    'p-2 rounded transition-colors',
                    portScanState === 'scanning'
                      ? 'bg-monokai-orange text-monokai-bg'
                      : 'bg-monokai-cyan text-monokai-bg hover:bg-monokai-purple'
                  ]"
                  :disabled="portScanState === 'scanning'"
                  title="Scanner les ports ouverts"
                >
                  <span class="mdi mdi-wifi-settings text-xl"></span>
                </button>
                <button
                  v-if="selectedIP?.mac"
                  @click="openDhcpModal"
                  class="p-2 rounded transition-colors"
                  :class="selectedIP?.dhcp_synced
                    ? 'bg-monokai-green/20 text-monokai-green hover:bg-monokai-green/30 ring-1 ring-monokai-green/40'
                    : 'bg-monokai-orange text-monokai-bg hover:bg-monokai-yellow'"
                  title="Réservation DHCP OPNsense"
                >
                  <span class="mdi mdi-router-wireless text-xl"></span>
                </button>
                <button
                  @click="resetForm"
                  class="p-2 bg-monokai-comment text-monokai-bg rounded hover:bg-monokai-text transition-colors"
                  title="Annuler les changements"
                >
                  <span class="mdi mdi-close-box text-xl"></span>
                </button>
                <button
                  @click="deleteIP"
                  class="p-2 bg-monokai-pink text-monokai-bg rounded hover:bg-red-700 transition-colors"
                  title="Réinitialiser les données de cette IP"
                >
                  <span class="mdi mdi-eraser text-xl"></span>
                </button>
              </div>
            </div>
          </div>

          <!-- Timestamps -->
          <div class="border-t border-monokai-comment text-xs" :style="{ paddingTop: `${uiConfig.details_spacing * 2}px`, marginTop: `${uiConfig.details_spacing * 2}px` }">
            <div :style="formSpacing">
              <div v-if="selectedIP.first_seen">
                <span class="text-monokai-comment">Première vue:</span>
                <span class="text-monokai-text ml-2">{{ formatDate(selectedIP.first_seen) }}</span>
              </div>
              <div v-if="selectedIP.last_seen">
                <span class="text-monokai-comment">Dernière vue:</span>
                <span class="text-monokai-text ml-2">{{ formatDate(selectedIP.last_seen) }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Placeholder si rien sélectionné -->
      <div v-else class="text-center text-monokai-comment mt-10 p-4">
        <p>Sélectionnez une IP pour voir les détails</p>
      </div>
    </div>

    <!-- Recherche (en bas à gauche) -->
    <div v-if="showFilters" class="bg-monokai-bg border-t border-monokai-comment p-3 mt-auto">
      <div class="flex items-center justify-between mb-2">
        <div class="text-xs font-bold text-monokai-green no-select">Recherche</div>
        <label class="flex items-center gap-2 text-xs text-monokai-text">
          <input v-model="invertSearch" type="checkbox" class="form-checkbox" />
          Inverser
        </label>
      </div>
      <div class="relative">
        <input
          v-model="searchQuery"
          type="text"
          class="w-full pl-3 pr-8 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text text-sm"
          placeholder="Rechercher dans toutes les cellules"
          title="Recherche multi-termes, insensible à la casse et aux accents"
        />
        <button
          v-if="searchQuery"
          @click="searchQuery = ''"
          class="absolute right-2 top-1/2 -translate-y-1/2 w-6 h-6 rounded-full flex items-center justify-center text-monokai-bg bg-monokai-cyan hover:bg-monokai-green shadow"
          aria-label="Effacer la recherche"
          title="Effacer la recherche"
        >
          ✕
        </button>
      </div>
      <div class="grid grid-cols-3 gap-2 mt-2">
        <div>
          <div class="text-[10px] font-semibold text-monokai-comment mb-1 no-select">Statut</div>
          <div class="flex flex-col gap-1">
            <button
              v-for="tag in tagGroups.status"
              :key="tag.value"
              @click="toggleTag(tag.value)"
              class="w-full px-1.5 py-0.5 text-[10px] leading-tight rounded-full border border-transparent transition-colors hover:opacity-80 shadow-sm text-left"
              :class="isTagActive(tag.value) ? 'ring-2 ring-monokai-text/40 shadow-inner font-semibold border-monokai-text/60' : ''"
              :style="tag.style"
            >
              {{ tag.label }}
            </button>
          </div>
        </div>
        <div>
          <div class="text-[10px] font-semibold text-monokai-comment mb-1 no-select">Type d'hote</div>
          <div class="flex flex-col gap-1">
            <button
              v-for="tag in tagGroups.host"
              :key="tag.value"
              @click="toggleTag(tag.value)"
              class="w-full px-1.5 py-0.5 text-[10px] leading-tight rounded-full border border-transparent transition-colors hover:opacity-80 shadow-sm text-left"
              :class="isTagActive(tag.value) ? 'ring-2 ring-monokai-text/40 shadow-inner font-semibold border-monokai-text/60' : ''"
              :style="tag.style"
            >
              {{ tag.label }}
            </button>
          </div>
        </div>
        <div>
          <div class="text-[10px] font-semibold text-monokai-comment mb-1 no-select">Localisation</div>
          <div class="flex flex-col gap-1">
            <button
              v-for="tag in tagGroups.location"
              :key="tag.value"
              @click="toggleTag(tag.value)"
              class="w-full px-1.5 py-0.5 text-[10px] leading-tight rounded-full border border-transparent transition-colors hover:opacity-80 shadow-sm text-left"
              :class="isTagActive(tag.value) ? 'ring-2 ring-monokai-text/40 shadow-inner font-semibold border-monokai-text/60' : ''"
              :style="tag.style"
            >
              {{ tag.label }}
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- Modal DHCP OPNsense -->
    <div
      v-if="showDhcpModal"
      class="fixed inset-0 bg-black/50 flex items-center justify-center z-50"
      @click.self="closeDhcpModal"
    >
      <div class="bg-monokai-bg border-2 border-monokai-orange rounded-lg w-[480px] max-h-[80vh] flex flex-col">
        <div class="p-4 border-b border-monokai-comment flex justify-between items-center">
          <h2 class="text-lg font-bold text-monokai-orange flex items-center gap-2">
            <span class="mdi mdi-router-wireless"></span>
            Réservation DHCP — Kea
          </h2>
          <button
            @click="closeDhcpModal"
            class="text-monokai-comment hover:text-monokai-text text-2xl leading-none"
          >
            ×
          </button>
        </div>

        <div class="flex-1 overflow-auto p-4 space-y-4">
          <div>
            <label class="text-sm text-monokai-comment mb-1 block">Adresse MAC</label>
            <input
              v-model="dhcpForm.hw_address"
              type="text"
              class="w-full px-3 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text font-mono"
              placeholder="00:00:00:00:00:00"
            />
          </div>

          <div>
            <label class="text-sm text-monokai-comment mb-1 block">Adresse IP</label>
            <input
              v-model="dhcpForm.ip_address"
              type="text"
              class="w-full px-3 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text font-mono"
              placeholder="10.0.0.x"
            />
          </div>

          <div>
            <label class="text-sm text-monokai-comment mb-1 block">Nom (hostname)</label>
            <input
              v-model="dhcpForm.hostname"
              type="text"
              class="w-full px-3 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text"
              placeholder="nom-equipement"
            />
          </div>

          <div>
            <label class="text-sm text-monokai-comment mb-1 block">Description</label>
            <input
              v-model="dhcpForm.description"
              type="text"
              class="w-full px-3 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text"
              placeholder="Ajouté par IPWatch"
            />
          </div>

          <!-- Message de statut -->
          <div v-if="dhcpStatus.message" class="text-sm px-3 py-2 rounded" :class="{
            'bg-monokai-green/20 text-monokai-green': dhcpStatus.type === 'success',
            'bg-monokai-pink/20 text-monokai-pink': dhcpStatus.type === 'error',
            'bg-monokai-cyan/20 text-monokai-cyan': dhcpStatus.type === 'info'
          }">
            {{ dhcpStatus.message }}
          </div>
        </div>

        <div class="p-4 border-t border-monokai-comment flex items-center justify-end gap-2">
          <button
            @click="closeDhcpModal"
            class="px-4 py-2 bg-monokai-comment text-monokai-bg rounded hover:bg-monokai-text transition-colors"
          >
            Annuler
          </button>
          <button
            @click="submitDhcpReservation"
            :disabled="dhcpStatus.loading"
            class="px-4 py-2 bg-monokai-orange text-monokai-bg rounded hover:bg-monokai-yellow transition-colors disabled:opacity-40 flex items-center gap-2"
          >
            <span v-if="dhcpStatus.loading" class="mdi mdi-loading mdi-spin"></span>
            <span class="mdi mdi-router-wireless" v-else></span>
            Mettre à jour OPNsense
          </button>
        </div>
      </div>
    </div>

    <!-- Modal Icône -->
    <div
      v-if="showIconModal"
      class="fixed inset-0 bg-black/50 flex items-center justify-center z-50"
      @click.self="closeIconModal"
    >
      <div class="bg-monokai-bg border-2 border-monokai-cyan rounded-lg w-[520px] max-h-[80vh] flex flex-col">
        <div class="p-4 border-b border-monokai-comment flex justify-between items-center">
          <h2 class="text-lg font-bold text-monokai-cyan">Icône & lien</h2>
          <button
            @click="closeIconModal"
            class="text-monokai-comment hover:text-monokai-text text-2xl leading-none"
          >
            ×
          </button>
        </div>

        <div class="flex-1 overflow-auto p-4 space-y-4">
          <div>
            <div class="text-sm text-monokai-comment mb-2">Icônes existantes</div>
            <div v-if="availableIcons.length === 0 && !selectedIcon" class="text-xs text-monokai-comment">
              Aucune icône disponible.
            </div>
            <div class="grid grid-cols-6 gap-2">
              <button
                v-for="icon in availableIcons"
                :key="icon"
                @click="toggleIcon(icon)"
                class="p-1 rounded border transition-colors"
                :class="selectedIcon === icon ? 'border-monokai-cyan bg-monokai-cyan/15 ring-2 ring-monokai-cyan/40' : 'border-monokai-comment/40 hover:border-monokai-comment'"
                title="Sélectionner"
              >
                <img :src="`/icons/${icon}`" alt="" class="w-10 h-10 object-contain" />
              </button>
            </div>
          </div>

          <div>
            <label class="text-sm text-monokai-comment mb-2 block">Lien associé</label>
            <input
              v-model="iconLink"
              type="url"
              class="w-full px-3 py-2 bg-monokai-bg border border-monokai-comment rounded text-monokai-text text-sm"
              placeholder="https://exemple.com"
            />
          </div>
        </div>

        <div class="p-4 border-t border-monokai-comment flex items-center justify-between gap-2">
          <div>
            <label
              for="icon-upload"
              class="inline-flex items-center px-3 py-2 text-sm rounded bg-monokai-purple text-monokai-bg hover:bg-monokai-pink transition-colors cursor-pointer"
            >
              Upload
            </label>
            <input
              id="icon-upload"
              type="file"
              accept=".svg,.png,.jpg,.jpeg,.webp"
              @change="handleIconUpload"
              class="hidden"
            />
          </div>
          <div class="flex items-center gap-2">
          <button
            @click="closeIconModal"
            class="px-4 py-2 bg-monokai-comment text-monokai-bg rounded hover:bg-monokai-text transition-colors"
          >
            Annuler
          </button>
          <button
            @click="saveIcon"
            :disabled="!selectedIcon"
            class="px-4 py-2 bg-monokai-cyan text-monokai-bg rounded hover:bg-monokai-green transition-colors disabled:opacity-40"
          >
            Valider
          </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, computed } from 'vue'
import { storeToRefs } from 'pinia'
import { useIPStore } from '@/stores/ipStore'

const props = defineProps({
  showFilters: {
    type: Boolean,
    default: true
  },
  showOnlyFilters: {
    type: Boolean,
    default: false
  }
})

const ipStore = useIPStore()
const { selectedIP, searchQuery, invertSearch, configReloadTick } = storeToRefs(ipStore)

// Données de configuration depuis config.yaml (chargées dynamiquement)
const locations = ref([])
const hosts = ref([])
const portProtocols = ref({}) // Mapping port -> protocole
const hardwareBenchUrl = ref('')
import hardwareBenchIconUrl from '@/assets/hardware_benchtools.png'
const showIconModal = ref(false)
const availableIcons = ref([])
const selectedIcon = ref('')
const iconLink = ref('')
const networkEditMode = ref(false)

// DHCP OPNsense
const showDhcpModal = ref(false)
const dhcpForm = ref({
  hw_address: '',
  ip_address: '',
  hostname: '',
  description: 'Ajouté par IPWatch'
})
const dhcpStatus = ref({
  loading: false,
  message: '',
  type: '' // 'success', 'error', 'info'
})
const copiedField = ref('')
let copiedTimer = null
const uiConfig = ref({
  details_font_size: 13,
  details_spacing: 2
})

const formData = ref({
  name: '',
  known: false,
  tracked: false,
  vm: false,
  hardware_bench: false,
  location: '',
  host: '',
  link: ''
})

const networkForm = ref({
  mac: '',
  vendor: '',
  hostname: ''
})

const tagPalette = [
  { backgroundColor: '#E3F2FD', color: '#1E3A8A', hoverColor: '#D6EAFB' },
  { backgroundColor: '#E8F5E9', color: '#2E7D32', hoverColor: '#DDEFE0' },
  { backgroundColor: '#FFF3E0', color: '#A16207', hoverColor: '#FDEAD0' },
  { backgroundColor: '#F3E5F5', color: '#6B21A8', hoverColor: '#EBD7F0' },
  { backgroundColor: '#E0F2F1', color: '#0F766E', hoverColor: '#D4EBE9' },
  { backgroundColor: '#FCE4EC', color: '#9D174D', hoverColor: '#F9D6E3' },
  { backgroundColor: '#EDE7F6', color: '#4338CA', hoverColor: '#E2DBF2' }
]

const tagGroups = computed(() => {
  const base = [
    { label: 'En ligne', value: 'en ligne' },
    { label: 'Hors ligne', value: 'hors ligne' },
    { label: 'Connue', value: 'connue' },
    { label: 'Inconnue', value: 'inconnue' },
    { label: 'Libre', value: 'libre' }
  ]
  const statusExtras = [
    { label: 'Suivie', value: 'suivie' },
    { label: 'VM', value: 'vm' },
    { label: 'Hardware', value: 'hardware' }
  ]

  const hostTags = (hosts.value || [])
    .map(host => host.name)
    .filter(Boolean)
    .map(name => ({ label: name, value: name }))

  const locationTags = (locations.value || [])
    .filter(Boolean)
    .map(location => ({ label: location, value: location }))

  const dedupe = tags => {
    const seen = new Set()
    return tags.filter(tag => {
      const key = normalizeText(tag.value)
      if (!key || seen.has(key)) return false
      seen.add(key)
      return true
    })
  }

  const applyPalette = (tags, offset = 0) => {
    return tags.map((tag, index) => {
      const palette = tagPalette[(index + offset) % tagPalette.length]
      return {
        ...tag,
        style: {
          backgroundColor: palette.backgroundColor,
          color: palette.color
        }
      }
    })
  }

  const status = applyPalette(dedupe([...base, ...statusExtras]), 0)
  const host = applyPalette(dedupe(hostTags), 2)
  const location = applyPalette(dedupe(locationTags), 4)

  return { status, host, location }
})

// État du bouton enregistrer
const saveButtonState = ref('idle') // 'idle', 'saving', 'saved'

// État du scan de ports
const portScanState = ref('idle') // 'idle', 'scanning'

// Styles dynamiques basés sur la config
const detailsStyles = computed(() => ({
  fontSize: `${uiConfig.value.details_font_size}px`
}))

const formSpacing = computed(() => ({
  display: 'flex',
  flexDirection: 'column',
  gap: `${uiConfig.value.details_spacing}px`
}))

const headerPadding = computed(() => ({
  padding: `${uiConfig.value.details_spacing * 2}px ${uiConfig.value.details_spacing * 3}px`
}))

const contentPadding = computed(() => ({
  padding: `${uiConfig.value.details_spacing * 3}px`
}))

const ipFontSize = computed(() => `${uiConfig.value.details_font_size * 1.2}px`)
const isDirty = computed(() => {
  if (!selectedIP.value) return false

  const expectedLink = selectedIP.value.link
    || (selectedIP.value.open_ports && selectedIP.value.open_ports.includes(80)
      ? `http://${selectedIP.value.ip}`
      : '')

  const expected = {
    name: selectedIP.value.name || '',
    known: selectedIP.value.known || false,
    tracked: selectedIP.value.tracked || false,
    vm: selectedIP.value.vm || false,
    hardware_bench: selectedIP.value.hardware_bench || false,
    location: selectedIP.value.location || '',
    host: selectedIP.value.host || '',
    link: expectedLink || ''
  }

  return (
    (formData.value.name || '') !== expected.name ||
    Boolean(formData.value.known) !== expected.known ||
    Boolean(formData.value.tracked) !== expected.tracked ||
    Boolean(formData.value.vm) !== expected.vm ||
    Boolean(formData.value.hardware_bench) !== expected.hardware_bench ||
    (formData.value.location || '') !== expected.location ||
    (formData.value.host || '') !== expected.host ||
    (formData.value.link || '') !== expected.link ||
    networkDirty.value
  )
})

const networkDirty = computed(() => {
  if (!selectedIP.value) return false
  return (
    (networkForm.value.mac || '') !== (selectedIP.value.mac || '') ||
    (networkForm.value.vendor || '') !== (selectedIP.value.vendor || '') ||
    (networkForm.value.hostname || '') !== (selectedIP.value.hostname || '')
  )
})

// Charger les options de configuration au montage
async function loadOptions() {
  try {
    const response = await fetch('/api/ips/config/options')
    if (response.ok) {
      const data = await response.json()
      locations.value = data.locations || []
      hosts.value = data.hosts || []
      portProtocols.value = data.port_protocols || {}
      hardwareBenchUrl.value = data.hardware_bench_url || ''
    }
  } catch (error) {
    console.error('Erreur chargement options config:', error)
  }

  // Charger la config UI depuis le store
  if (ipStore.uiConfig) {
    uiConfig.value = {
      details_font_size: ipStore.uiConfig.details_font_size || 13,
      details_spacing: ipStore.uiConfig.details_spacing || 2
    }
  }
}

onMounted(async () => {
  await loadOptions()
})

watch(configReloadTick, async () => {
  await loadOptions()
})

// Mettre à jour le formulaire quand l'IP change
watch(selectedIP, (newIP) => {
  if (newIP) {
    // Auto-remplir l'URL si vide et port 80 ouvert
    let autoLink = newIP.link || ''
    if (!autoLink && newIP.open_ports && newIP.open_ports.includes(80)) {
      autoLink = `http://${newIP.ip}`
    }

    formData.value = {
      name: newIP.name || '',
      known: newIP.known || false,
      tracked: newIP.tracked || false,
      vm: newIP.vm || false,
      hardware_bench: newIP.hardware_bench || false,
      location: newIP.location || '',
      host: newIP.host || '',
      link: autoLink,
      ip_parent: newIP.ip_parent || ''
    }

    networkForm.value = {
      mac: newIP.mac || '',
      vendor: newIP.vendor || '',
      hostname: newIP.hostname || ''
    }

    // Réinitialiser l'état du bouton
    saveButtonState.value = 'idle'
  }
}, { immediate: true })

// Auto-remplir la localisation quand l'hôte change
function onHostChange() {
  const selectedHost = hosts.value.find(h => h.name === formData.value.host)
  if (selectedHost && selectedHost.location) {
    formData.value.location = selectedHost.location
  }
  formData.value.ip_parent = selectedHost?.ip || ''
}

function resetForm() {
  if (selectedIP.value) {
    formData.value = {
      name: selectedIP.value.name || '',
      known: selectedIP.value.known || false,
      tracked: selectedIP.value.tracked || false,
      vm: selectedIP.value.vm || false,
      hardware_bench: selectedIP.value.hardware_bench || false,
      location: selectedIP.value.location || '',
      host: selectedIP.value.host || '',
      link: selectedIP.value.link || '',
      ip_parent: selectedIP.value.ip_parent || ''
    }
  }
}

async function saveChanges() {
  if (!selectedIP.value) return

  try {
    saveButtonState.value = 'saving'
    const payload = {
      ...formData.value
    }

    if (networkDirty.value) {
      payload.mac = networkForm.value.mac || null
      payload.vendor = networkForm.value.vendor || null
      payload.hostname = networkForm.value.hostname || null
    }

    await ipStore.updateIP(selectedIP.value.ip, payload)
    saveButtonState.value = 'saved'
    console.log('IP mise à jour')

    // Retour à l'état normal après 2 secondes
    setTimeout(() => {
      saveButtonState.value = 'idle'
    }, 2000)

    if (networkDirty.value) {
      networkEditMode.value = false
    }
  } catch (err) {
    console.error('Erreur mise à jour IP:', err)
    saveButtonState.value = 'idle'
  }
}

async function scanPorts() {
  if (!selectedIP.value) return

  try {
    portScanState.value = 'scanning'
    const response = await fetch(`/api/scan/ports/${selectedIP.value.ip}`, {
      method: 'POST'
    })

    if (!response.ok) {
      throw new Error('Erreur lors du scan de ports')
    }

    const result = await response.json()
    console.log('Scan de ports terminé:', result)

    // Rafraîchir les données de l'IP
    await ipStore.fetchIPs()

    portScanState.value = 'idle'
  } catch (err) {
    console.error('Erreur scan ports:', err)
    portScanState.value = 'idle'
  }
}

async function deleteIP() {
  if (!selectedIP.value) return

  if (confirm(`Voulez-vous vraiment réinitialiser les données de ${selectedIP.value.ip} ?\n\nCela inclut :\n- Métadonnées (nom, localisation, etc.)\n- Informations réseau (MAC, vendor, hostname, ports)\n- Historique de détection\n- Flag DHCP réservé\n\nNote : la réservation DHCP sur OPNsense n'est pas supprimée.`)) {
    try {
      // 1. Supprimer l'historique de détection
      const historyResponse = await fetch(`/api/ips/${selectedIP.value.ip}/history`, {
        method: 'DELETE'
      })

      if (!historyResponse.ok) {
        console.warn('Impossible de supprimer l\'historique')
      }

      // 2. Effacer TOUTES les données (métadonnées + informations réseau + timestamps)
      const resetData = {
        name: '',
        known: false,
        vm: false,
        hardware_bench: false,
        location: '',
        host: '',
        link: '',
        last_status: 'offline',
        // Effacer les informations réseau
        mac: null,
        vendor: null,
        hostname: null,
        open_ports: [],
        icon_filename: null,
        icon_url: null,
        // Effacer les timestamps
        first_seen: null,
        last_seen: null,
        // Réinitialiser le flag DHCP
        dhcp_synced: false
      }

      await ipStore.updateIP(selectedIP.value.ip, resetData)

      // 3. Réinitialiser le formulaire
      formData.value = {
        name: '',
        known: false,
        location: '',
        vm: false,
        hardware_bench: false,
        host: '',
        link: ''
      }

      // 4. Rafraîchir les IPs pour mettre à jour le volet central ET le volet "Nouvelles Détections"
      await ipStore.fetchIPs()

      // 5. Désélectionner l'IP pour revenir à l'affichage "Sélectionnez une IP"
      ipStore.selectIP(null)

      console.log('IP effacée : toutes les données et historique réinitialisés')
    } catch (err) {
      console.error('Erreur effacement IP:', err)
    }
  }
}

function openHardwareBench() {
  if (!hardwareBenchUrl.value) return
  window.open(hardwareBenchUrl.value, '_blank', 'noopener')
}

function toggleNetworkEdit() {
  networkEditMode.value = !networkEditMode.value
  if (!networkEditMode.value && selectedIP.value) {
    networkForm.value = {
      mac: selectedIP.value.mac || '',
      vendor: selectedIP.value.vendor || '',
      hostname: selectedIP.value.hostname || ''
    }
  }
}

async function copyField(fieldKey, value) {
  if (!value) return
  try {
    if (navigator.clipboard && navigator.clipboard.writeText) {
      await navigator.clipboard.writeText(value)
    } else {
      const textarea = document.createElement('textarea')
      textarea.value = value
      textarea.setAttribute('readonly', '')
      textarea.style.position = 'fixed'
      textarea.style.opacity = '0'
      document.body.appendChild(textarea)
      textarea.select()
      document.execCommand('copy')
      document.body.removeChild(textarea)
    }
    copiedField.value = fieldKey
    if (copiedTimer) clearTimeout(copiedTimer)
    copiedTimer = setTimeout(() => {
      copiedField.value = ''
    }, 1200)
  } catch (error) {
    console.error('Erreur copie:', error)
  }
}

async function openIconModal() {
  if (!selectedIP.value) return
  showIconModal.value = true
  selectedIcon.value = selectedIP.value.icon_filename || ''
  iconLink.value = formData.value.link || selectedIP.value.icon_url || ''
  await loadAvailableIcons()
}

function closeIconModal() {
  showIconModal.value = false
}

async function loadAvailableIcons() {
  try {
    const response = await fetch('/api/ips/icons')
    if (response.ok) {
      const data = await response.json()
      availableIcons.value = data.icons || []
    }
  } catch (error) {
    console.error('Erreur chargement icônes:', error)
  }
}

function toggleIcon(icon) {
  selectedIcon.value = selectedIcon.value === icon ? '' : icon
}

async function handleIconUpload(event) {
  const file = event.target.files[0]
  if (!file) return

  const formDataUpload = new FormData()
  formDataUpload.append('file', file)

  try {
    const response = await fetch('/api/ips/icons/upload', {
      method: 'POST',
      body: formDataUpload
    })
    if (response.ok) {
      const data = await response.json()
      selectedIcon.value = data.filename
      await loadAvailableIcons()
    } else {
      const error = await response.json()
      console.error('Upload icône:', error.detail || 'Erreur upload')
    }
  } catch (error) {
    console.error('Erreur upload icône:', error)
  } finally {
    event.target.value = ''
  }
}

async function saveIcon() {
  if (!selectedIP.value) return

  try {
    await ipStore.updateIP(selectedIP.value.ip, {
      icon_filename: selectedIcon.value || null,
      icon_url: iconLink.value ? iconLink.value.trim() : null
    })
    await ipStore.fetchIPs()
    closeIconModal()
  } catch (error) {
    console.error('Erreur sauvegarde icône:', error)
  }
}

// --- DHCP OPNsense ---
function openDhcpModal() {
  if (!selectedIP.value) return
  dhcpForm.value = {
    hw_address: selectedIP.value.mac || '',
    ip_address: selectedIP.value.ip || '',
    hostname: formData.value.name || selectedIP.value.hostname || '',
    description: 'Ajouté par IPWatch'
  }
  dhcpStatus.value = { loading: false, message: '', type: '' }
  showDhcpModal.value = true
}

function closeDhcpModal() {
  showDhcpModal.value = false
}

async function submitDhcpReservation() {
  if (!selectedIP.value) return

  dhcpStatus.value = { loading: true, message: 'Envoi vers OPNsense...', type: 'info' }

  try {
    const response = await fetch('/api/opnsense/dhcp/reservation', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(dhcpForm.value)
    })

    if (!response.ok) {
      const err = await response.json()
      throw new Error(err.detail || 'Erreur inconnue')
    }

    const result = await response.json()

    dhcpStatus.value = {
      loading: false,
      message: result.action === 'updated'
        ? 'Réservation mise à jour avec succès'
        : 'Réservation créée avec succès',
      type: 'success'
    }

    // Mettre à jour le store avec dhcp_synced = true
    await ipStore.fetchIPs()

    // Fermer le modal après un délai
    setTimeout(() => {
      closeDhcpModal()
    }, 1500)

  } catch (err) {
    dhcpStatus.value = {
      loading: false,
      message: `Erreur: ${err.message}`,
      type: 'error'
    }
  }
}

function formatDate(dateString) {
  if (!dateString) return 'N/A'
  const date = new Date(dateString)
  return date.toLocaleString('fr-FR')
}

function toggleTag(value) {
  if (isTagActive(value)) {
    removeTag(value)
    return
  }

  const trimmed = searchQuery.value.trim()
  searchQuery.value = trimmed ? `${trimmed} ${value}` : value
}

function isTagActive(value) {
  const queryTokens = searchQuery.value.trim().split(/\s+/).filter(Boolean)
  if (queryTokens.length === 0) return false
  const normalizedTokens = queryTokens.map(token => normalizeText(token))
  const tagTokens = normalizeText(value).split(/\s+/).filter(Boolean)
  return findTokenSequence(normalizedTokens, tagTokens) !== -1
}

function removeTag(value) {
  const queryTokens = searchQuery.value.trim().split(/\s+/).filter(Boolean)
  if (queryTokens.length === 0) return
  const normalizedTokens = queryTokens.map(token => normalizeText(token))
  const tagTokens = normalizeText(value).split(/\s+/).filter(Boolean)
  const startIndex = findTokenSequence(normalizedTokens, tagTokens)
  if (startIndex === -1) return

  const updated = queryTokens.filter((_, index) => {
    return index < startIndex || index >= startIndex + tagTokens.length
  })
  searchQuery.value = updated.join(' ').trim()
}

function findTokenSequence(tokens, sequence) {
  if (sequence.length === 0) return -1
  for (let i = 0; i <= tokens.length - sequence.length; i++) {
    let matches = true
    for (let j = 0; j < sequence.length; j++) {
      if (tokens[i + j] !== sequence[j]) {
        matches = false
        break
      }
    }
    if (matches) return i
  }
  return -1
}

function normalizeText(value) {
  return String(value ?? '')
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .toLowerCase()
    .trim()
}

// Générer une URL cliquable pour un port
function getPortUrl(port) {
  if (!selectedIP.value) return null

  // Chercher le protocole (la clé peut être un nombre ou une string)
  const protocol = portProtocols.value[port] || portProtocols.value[String(port)]
  if (!protocol) return null

  const ip = selectedIP.value.ip

  // Mapping protocole -> URL
  const urlMap = {
    'http': `http://${ip}:${port}`,
    'https': `https://${ip}:${port}`,
    'ssh': `ssh://${ip}:${port}`,
    'smb': `smb://${ip}`,
    'rdp': `rdp://${ip}:${port}`,
    'mysql': `mysql://${ip}:${port}`,
    'postgresql': `postgresql://${ip}:${port}`
  }

  return urlMap[protocol] || null
}
</script>
