<template>
  <div class="topology-page">

    <!-- Barre d'outils -->
    <div class="topo-toolbar">
      <button class="ping-btn" :class="{ pinging }" :disabled="pinging" @click="pingAll">
        <span class="ping-btn-dot" :class="pingBtnDotClass"></span>
        {{ pinging ? t('pinging') : pingDone ? t('refreshPing') : t('ping') }}
      </button>
      <span v-if="pingDone && !pinging" class="ping-summary">
        {{ pingUpCount }} ↑ &nbsp; {{ pingDownCount }} ↓
      </span>
    </div>

    <!-- Cartes spéciales en haut : WAN et Passerelle -->
    <div v-if="liveboxDevices.length || gatewayDevices.length" class="special-row">

      <div v-if="liveboxDevices.length" class="special-card special-wan">
        <div class="special-header">
          <span class="special-icon">🌐</span>
          <span class="special-title">{{ t('wan') }}</span>
        </div>
        <div class="special-body">
          <div v-for="d in liveboxDevices" :key="d.id" class="device-chip chip-livebox">
            <span class="chip-icon"><DeviceIcon :device-type="d.type" :is-livebox="d.is_livebox" :is-gateway="d.is_gateway" :name="d.name" :description="d.description" :size="16" type-only /></span>
            <div class="chip-body">
              <span class="chip-name">{{ d.name }}</span>
              <div class="chip-sub">
                <span v-for="iface in d.interfaces" :key="iface.id">
                  <code v-if="iface.ip_address" class="chip-ip">{{ iface.ip_address }}</code>
                </span>
                <svg v-for="b in detectBrands(d.name, d.description)" :key="b.title" width="11" height="11" viewBox="0 0 24 24" fill="currentColor" class="chip-brand-icon" :title="b.title" :style="{ color: '#' + b.hex }"><path :d="b.path" /></svg>
              </div>
            </div>
            <a v-if="d.url" :href="d.url" target="_blank" rel="noreferrer noopener" class="chip-tag tag-link" :title="t('openWebUI')">{{ t('tagLink') }}</a>
            <span v-if="pingStatus[d.id]" class="ping-dot" :class="'ping-' + pingStatus[d.id]" :title="pingStatus[d.id] === 'up' ? t('reachable') : t('unreachable')"></span>
          </div>
        </div>
      </div>

      <div v-if="gatewayDevices.length" class="special-card special-gw">
        <div class="special-header">
          <span class="special-icon">⬡</span>
          <span class="special-title">{{ t('gateway') }}</span>
        </div>
        <div class="special-body">
          <div v-for="d in gatewayDevices" :key="d.id" class="device-chip chip-gateway">
            <span class="chip-icon"><DeviceIcon :device-type="d.type" :is-livebox="d.is_livebox" :is-gateway="d.is_gateway" :name="d.name" :description="d.description" :size="16" type-only /></span>
            <div class="chip-body">
              <span class="chip-name">{{ d.name }}</span>
              <div class="chip-sub">
                <span v-if="d.description" class="chip-iface">{{ d.description }}</span>
                <svg v-for="b in detectBrands(d.name, d.description)" :key="b.title" width="11" height="11" viewBox="0 0 24 24" fill="currentColor" class="chip-brand-icon" :title="b.title" :style="{ color: '#' + b.hex }"><path :d="b.path" /></svg>
              </div>
            </div>
            <a v-if="d.url" :href="d.url" target="_blank" rel="noreferrer noopener" class="chip-tag tag-link" :title="t('openWebUI')">{{ t('tagLink') }}</a>
            <span v-if="pingStatus[d.id]" class="ping-dot" :class="'ping-' + pingStatus[d.id]" :title="pingStatus[d.id] === 'up' ? t('reachable') : t('unreachable')"></span>
          </div>
        </div>
      </div>

    </div>

    <!-- Grille des réseaux -->
    <div class="vlan-grid">
      <div
        v-for="vlan in props.vlans"
        :key="vlan.id"
        class="vlan-card"
        :style="{ '--vlan-color': vlan.color }"
      >
        <div class="vlan-header">
          <div class="vlan-id-badge">{{ vlan.vlan_id != null ? 'VLAN ' + vlan.vlan_id : 'LAN' }}</div>
          <div class="vlan-meta">
            <span class="vlan-name">{{ vlan.name }}</span>
            <code v-if="vlan.cidr" class="vlan-cidr">{{ vlan.cidr }}</code>
          </div>
          <span class="vlan-count">{{ vlanMembers(vlan.id).length }}</span>
        </div>

        <div class="vlan-body">
          <div v-if="vlanMembers(vlan.id).length === 0" class="empty-vlan">
            {{ t('noDevice') }}
          </div>
          <div
            v-for="item in vlanMembers(vlan.id)"
            :key="item.device.id"
            class="device-chip"
            :class="'chip-' + chipRole(item.device)"
          >
            <span class="chip-icon">
              <DeviceIcon :device-type="item.device.type" :is-livebox="item.device.is_livebox" :is-gateway="item.device.is_gateway" :name="item.device.name" :description="item.device.description" :size="16" type-only />
            </span>
            <div class="chip-body">
              <span class="chip-name">{{ item.device.name }}</span>
              <div class="chip-sub">
                <code v-if="item.ip" class="chip-ip">{{ item.ip }}</code>
                <span v-if="item.ifaceName" class="chip-iface">{{ item.ifaceName }}</span>
                <svg v-for="b in detectBrands(item.device.name, item.device.description)" :key="b.title" width="11" height="11" viewBox="0 0 24 24" fill="currentColor" class="chip-brand-icon" :title="b.title" :style="{ color: '#' + b.hex }"><path :d="b.path" /></svg>
              </div>
            </div>
            <div class="chip-tags">
              <span v-if="pingStatus[item.device.id]" class="ping-dot" :class="'ping-' + pingStatus[item.device.id]" :title="pingStatus[item.device.id] === 'up' ? t('reachable') : t('unreachable')"></span>
              <a v-if="item.device.url" :href="item.device.url" target="_blank" rel="noreferrer noopener" class="chip-tag tag-link" :title="t('openWebUI')">{{ t('tagLink') }}</a>
              <span v-if="item.device.is_gateway" class="chip-tag tag-gw">{{ t('tagGw') }}</span>
              <span v-if="item.device.virt_type === 'lxc'" class="chip-tag tag-lxc">{{ t('tagLxc') }}</span>
              <span v-if="item.device.virt_type === 'qemu'" class="chip-tag tag-vm">{{ t('tagVm') }}</span>
            </div>
          </div>
        </div>
      </div>

      <!-- Zone non assigné -->
      <div
        v-if="untaggedDevices.length"
        class="vlan-card untagged"
      >
        <div class="vlan-header">
          <div class="vlan-id-badge untagged-badge">—</div>
          <div class="vlan-meta">
            <span class="vlan-name">{{ t('unassigned') }}</span>
          </div>
          <span class="vlan-count">{{ untaggedDevices.length }}</span>
        </div>
        <div class="vlan-body">
          <div
            v-for="d in untaggedDevices"
            :key="d.id"
            class="device-chip"
            :class="'chip-' + chipRole(d)"
          >
            <span class="chip-icon">
              <DeviceIcon :device-type="d.type" :is-livebox="d.is_livebox" :is-gateway="d.is_gateway" :name="d.name" :description="d.description" :size="16" type-only />
            </span>
            <div class="chip-body">
              <span class="chip-name">{{ d.name }}</span>
              <div class="chip-sub">
                <span v-if="d.description" class="chip-iface">{{ d.description }}</span>
                <svg v-for="b in detectBrands(d.name, d.description)" :key="b.title" width="11" height="11" viewBox="0 0 24 24" fill="currentColor" class="chip-brand-icon" :title="b.title" :style="{ color: '#' + b.hex }"><path :d="b.path" /></svg>
              </div>
            </div>
            <a v-if="d.url" :href="d.url" target="_blank" rel="noreferrer noopener" class="chip-tag tag-link" :title="t('openWebUI')">{{ t('tagLink') }}</a>
            <span v-if="pingStatus[d.id]" class="ping-dot" :class="'ping-' + pingStatus[d.id]" :title="pingStatus[d.id] === 'up' ? t('reachable') : t('unreachable')"></span>
          </div>
        </div>
      </div>
    </div>

    <div v-if="props.vlans.length === 0 && props.devices.length === 0" class="empty-state">
      <div class="empty-icon">⬡</div>
      <p>{{ t('noDevices') }}</p>
      <p class="empty-hint">{{ t('noDevicesHint') }}</p>
    </div>

  </div>
</template>

<script setup>
import { computed, ref } from 'vue'
import DeviceIcon from './DeviceIcon.vue'
import { detectBrands } from '../brandIcons.js'
import { discoveryApi } from '../api.js'
import { t } from '../i18n.js'

function ipToInt(ip) {
  if (!ip) return Infinity
  const p = ip.split('.').map(Number)
  return p.length === 4 ? (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]) >>> 0 : Infinity
}

const props = defineProps({
  devices: { type: Array, default: () => [] },
  vlans:   { type: Array, default: () => [] },
})

const liveboxDevices = computed(() => props.devices.filter(d => d.is_livebox))
const gatewayDevices = computed(() => props.devices.filter(d => d.is_gateway))

function vlanMembers(vlanId) {
  const result = []
  for (const device of props.devices) {
    const iface = device.interfaces.find(i => i.vlan_id === vlanId)
    if (iface) {
      result.push({
        device,
        ip: iface.ip_address || '',
        ifaceName: iface.name || '',
      })
    }
  }
  return result.sort((a, b) => ipToInt(a.ip) - ipToInt(b.ip))
}

const untaggedDevices = computed(() =>
  props.devices.filter(d => {
    if (d.is_livebox || d.is_gateway) return false
    return !d.interfaces.some(i => i.vlan_id)
  }).sort((a, b) => ipToInt(a.interfaces[0]?.ip_address) - ipToInt(b.interfaces[0]?.ip_address))
)

function chipRole(device) {
  if (device.is_livebox) return 'livebox'
  if (device.is_gateway) return 'gateway'
  return device.type || 'other'
}

// ── Ping ──────────────────────────────────────────────────────────────────────
const pingStatus = ref({})
const pinging    = ref(false)
const pingDone   = ref(false)

const pingUpCount   = computed(() => Object.values(pingStatus.value).filter(s => s === 'up').length)
const pingDownCount = computed(() => Object.values(pingStatus.value).filter(s => s === 'down').length)
const pingBtnDotClass = computed(() => {
  if (pinging.value) return 'dot-pinging'
  if (!pingDone.value) return 'dot-idle'
  return pingDownCount.value > 0 ? 'dot-warn' : 'dot-ok'
})

async function pingAll() {
  const ipToDevices = {}
  for (const d of props.devices) {
    for (const i of d.interfaces) {
      if (i.ip_address) {
        if (!ipToDevices[i.ip_address]) ipToDevices[i.ip_address] = []
        ipToDevices[i.ip_address].push(d.id)
      }
    }
  }
  const ips = Object.keys(ipToDevices)
  if (!ips.length) return

  pinging.value = true
  try {
    const { data } = await discoveryApi.ping(ips)
    const next = {}
    for (const { ip, alive } of data) {
      for (const id of (ipToDevices[ip] || [])) {
        if (alive || next[id] !== 'up') next[id] = alive ? 'up' : 'down'
      }
    }
    pingStatus.value = next
    pingDone.value = true
  } finally {
    pinging.value = false
  }
}
</script>

<style scoped>
.topology-page {
  height: 100vh;
  overflow-y: auto;
  background: var(--bg-page);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* ── Toolbar ─────────────────────────────────────────────────────────────── */
.topo-toolbar {
  display: flex; align-items: center; gap: 10px;
}

.ping-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 14px; height: 30px;
  background: var(--bg-card); border: 1.5px solid var(--border);
  border-radius: 8px; font-size: 12px; font-weight: 600; color: var(--text-secondary);
  cursor: pointer;
}
.ping-btn:hover:not(:disabled) { border-color: var(--border-strong); background: var(--bg-card-hover); }
.ping-btn:disabled { opacity: 0.6; cursor: default; }
.ping-btn.pinging { border-color: #93C5FD; color: #1D4ED8; }

.ping-btn-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.dot-idle    { background: #CBD5E1; }
.dot-pinging { background: #60A5FA; animation: pulse 1s infinite; }
.dot-ok      { background: #22C55E; }
.dot-warn    { background: #F97316; }

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.3; }
}

.ping-summary { font-size: 12px; color: var(--text-muted); }

/* ── Dot ping ────────────────────────────────────────────────────────────── */
.ping-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.ping-up   { background: #22C55E; }
.ping-down { background: #EF4444; }

/* ── Cartes spéciales (WAN + Passerelle) ─────────────────────────────────── */
.special-row {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}

.special-card {
  background: var(--bg-card);
  border-radius: 12px;
  border: 1.5px solid;
  overflow: hidden;
  box-shadow: var(--shadow-card);
  min-width: 220px;
  flex: 1;
}
.special-wan { border-color: #FCA5A5; }
.special-gw  { border-color: #FCD34D; }

.special-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.special-wan .special-header { background: #FEF2F2; color: #B91C1C; border-bottom: 1px solid #FECACA; }
.special-gw  .special-header { background: #FFFBEB; color: #92400E; border-bottom: 1px solid #FDE68A; }

:global(html.dark .special-wan) { border-color: #7F1D1D; }
:global(html.dark .special-gw)  { border-color: #78350F; }
:global(html.dark .special-wan .special-header) { background: #2A1515; color: #FCA5A5; border-bottom-color: #3D1F1F; }
:global(html.dark .special-gw  .special-header) { background: #2A200A; color: #FCD34D; border-bottom-color: #3D3010; }

.special-body {
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* ── Grille des réseaux ──────────────────────────────────────────────────── */
.vlan-grid {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ── Card réseau ─────────────────────────────────────────────────────────── */
.vlan-card {
  background: var(--bg-card);
  border-radius: 12px;
  border: 1.5px solid var(--border);
  border-top: 3px solid var(--vlan-color, #CBD5E1);
  overflow: hidden;
  box-shadow: var(--shadow-card);
}
.vlan-card.untagged {
  --vlan-color: #CBD5E1;
  border-style: dashed;
  border-top-style: solid;
}

.vlan-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--bg-thead);
  border-bottom: 1px solid var(--border);
}

.vlan-id-badge {
  background: var(--vlan-color, #CBD5E1);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  padding: 2px 9px;
  border-radius: 20px;
  white-space: nowrap;
  letter-spacing: 0.03em;
}
.untagged-badge { background: #94A3B8; }

.vlan-meta {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.vlan-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vlan-cidr {
  font-size: 11px;
  color: var(--text-faint);
  font-family: monospace;
  white-space: nowrap;
}

.vlan-count {
  font-size: 13px;
  font-weight: 700;
  color: var(--vlan-color, #CBD5E1);
  background: color-mix(in srgb, var(--vlan-color) 10%, transparent);
  border-radius: 20px;
  padding: 1px 8px;
  min-width: 24px;
  text-align: center;
}

.vlan-body {
  padding: 10px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 6px;
}

@media (max-width: 600px) {
  .vlan-body { grid-template-columns: 1fr; }
}

.empty-vlan {
  font-size: 12px;
  color: var(--text-faint);
  text-align: center;
  padding: 16px 0;
  font-style: italic;
  grid-column: 1 / -1;
}

/* ── Device chip ─────────────────────────────────────────────────────────── */
.device-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 8px;
  background: var(--bg-chip);
  border: 1px solid var(--border);
  transition: background 0.12s, box-shadow 0.12s;
}
.device-chip:hover {
  background: var(--bg-chip-hover);
  box-shadow: var(--shadow-card);
}

.chip-icon {
  width: 28px; height: 28px;
  border-radius: 7px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}

.chip-server      .chip-icon { background: #DBEAFE; color: #1D4ED8; }
.chip-nas         .chip-icon { background: #EDE9FE; color: #6D28D9; }
.chip-switch      .chip-icon { background: #D1FAE5; color: #065F46; }
.chip-router      .chip-icon { background: #FFEDD5; color: #C2410C; }
.chip-access_point .chip-icon { background: #CCFBF1; color: #0F766E; }
.chip-gateway     .chip-icon { background: #FEF3C7; color: #B45309; }
.chip-livebox     .chip-icon { background: #FEE2E2; color: #B91C1C; }
.chip-camera      .chip-icon { background: #E0F2FE; color: #0369A1; }
.chip-temperature .chip-icon { background: #F0F9FF; color: #0284C7; }
.chip-sensor      .chip-icon { background: #ECFCCB; color: #3F6212; }
.chip-hub         .chip-icon { background: #EEF2FF; color: #3730A3; }
.chip-smart_plug  .chip-icon { background: #FFF7ED; color: #C2410C; }
.chip-alarm       .chip-icon { background: #FEF2F2; color: #B91C1C; }
.chip-light       .chip-icon { background: #FEFCE8; color: #854D0E; }
.chip-doorbell    .chip-icon { background: #FDF4FF; color: #7E22CE; }
.chip-desktop     .chip-icon { background: #E0E7FF; color: #4338CA; }
.chip-laptop      .chip-icon { background: #DCFCE7; color: #15803D; }
.chip-other       .chip-icon { background: #F1F5F9; color: #64748B; }

.chip-body { flex: 1; min-width: 0; }
.chip-name {
  font-size: 12px; font-weight: 600; color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block;
}
.chip-sub {
  display: flex; align-items: center; gap: 5px; margin-top: 1px; flex-wrap: wrap;
}
.chip-brand-icon { display: inline-block; flex-shrink: 0; opacity: 0.85; }
.chip-ip {
  font-size: 11px; color: var(--chip-ip-color);
  font-family: monospace; background: var(--chip-ip-bg);
  padding: 0px 4px; border-radius: 3px;
}
.chip-iface {
  font-size: 10px; color: var(--text-faint);
  font-family: monospace; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.chip-tags { display: flex; flex-direction: column; gap: 2px; flex-shrink: 0; }
.chip-tag {
  font-size: 9px; font-weight: 800; padding: 1px 5px;
  border-radius: 4px; text-align: center; letter-spacing: 0.03em;
}
.tag-gw   { background: #FEF3C7; color: #B45309; }
.tag-lxc  { background: #DBEAFE; color: #1D4ED8; }
.tag-vm   { background: #EDE9FE; color: #6D28D9; }
.tag-link { background: #F0FDF4; color: #15803D; text-decoration: none; }
.tag-link:hover { background: #DCFCE7; }

/* ── Empty state ─────────────────────────────────────────────────────────── */
.empty-state {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; color: var(--text-faint);
}
.empty-icon { font-size: 64px; margin-bottom: 16px; opacity: 0.3; }
.empty-state p { font-size: 16px; margin-bottom: 6px; }
.empty-hint { font-size: 13px; color: var(--text-faint); }
</style>
