<?php
$title = 'Dashboard Dispositivos';
ob_start();
?>

  <!-- Header con título y acciones -->
  <div class="mb-6">
    <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
      <div>
        <h1 class="text-3xl font-bold text-slate-900">Dispositivos</h1>
        <p class="text-slate-600 mt-1">Gestiona tus dispositivos ESP conectados</p>
      </div>
      <div class="flex items-center gap-3">
        <label class="flex items-center gap-2 cursor-pointer select-none bg-white px-3 py-2 rounded-lg border border-slate-200 shadow-sm">
          <input type="checkbox" id="hideOfflineDevices" class="w-4 h-4 text-emerald-600 rounded focus:ring-emerald-500">
          <span class="text-sm font-medium text-slate-700">Ocultar Inactivos (offline)</span>
        </label>
        <button id="pageCreateDevice" class="inline-flex items-center gap-2 px-4 py-2.5 text-sm font-semibold rounded-lg bg-emerald-600 text-white hover:bg-emerald-700 shadow-sm transition-all" type="button">
          <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
          </svg>
          Nuevo dispositivo
        </button>
        <button id="pageCreateSector" class="inline-flex items-center gap-2 px-4 py-2.5 text-sm font-medium rounded-lg bg-white text-slate-700 hover:bg-slate-50 border border-slate-200 shadow-sm transition-all" type="button">
          <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" />
          </svg>
          Gestionar sectores
        </button>
      </div>
    </div>
  </div>

  <!-- Lista de dispositivos -->
  <div id="lista-dispositivos"></div>

  <!-- Modal Crear Dispositivo -->
  <div id="modalCrearDispositivo" class="fixed inset-0 z-50 hidden">
    <div data-modal-overlay class="absolute inset-0 bg-black/50 backdrop-blur-sm"></div>
    <div class="relative mx-auto mt-20 max-w-lg rounded-xl bg-white shadow-2xl">
      <div class="flex items-center justify-between px-6 py-4 border-b border-slate-200 bg-gradient-to-r from-emerald-50 to-emerald-100">
        <h5 class="m-0 font-bold text-slate-900 text-lg">Crear nuevo dispositivo</h5>
        <button type="button" class="text-slate-400 hover:text-slate-600 transition-colors" data-modal-close aria-label="Cerrar">
          <svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
          </svg>
        </button>
      </div>
      <div class="p-6">
        <form id="form-add" class="grid grid-cols-1 md:grid-cols-3 gap-4">
          <div><input name="chipid" placeholder="ChipID" class="w-full px-4 py-2.5 border-2 border-slate-200 rounded-lg focus:outline-none focus:border-emerald-500 focus:ring-2 focus:ring-emerald-200 transition-all" required></div>
          <div><input name="tag" placeholder="Tag" class="w-full px-4 py-2.5 border-2 border-slate-200 rounded-lg focus:outline-none focus:border-emerald-500 focus:ring-2 focus:ring-emerald-200 transition-all" required></div>
          <div><input name="nombre" placeholder="Modelo" class="w-full px-4 py-2.5 border-2 border-slate-200 rounded-lg focus:outline-none focus:border-emerald-500 focus:ring-2 focus:ring-emerald-200 transition-all"></div>
          <div><input name="ciudad" placeholder="Ciudad" class="w-full px-4 py-2.5 border-2 border-slate-200 rounded-lg focus:outline-none focus:border-emerald-500 focus:ring-2 focus:ring-emerald-200 transition-all"></div>
          <div class="md:col-span-2">
            <select name="sector" class="w-full px-4 py-2.5 border-2 border-slate-200 rounded-lg focus:outline-none focus:border-emerald-500 focus:ring-2 focus:ring-emerald-200 transition-all" required>
              <option value="">Seleccione un sector</option>
            </select>
          </div>
          <div class="md:col-span-1"><button class="w-full inline-flex items-center justify-center px-4 py-2.5 text-sm font-semibold rounded-lg bg-emerald-600 text-white hover:bg-emerald-700 shadow-sm transition-all" type="submit">Agregar</button></div>
        </form>
      </div>
    </div>
  </div>

  <!-- Modal Gestión de Sectores -->
  <div id="modalGestionSectores" class="fixed inset-0 z-50 hidden">
    <div data-modal-overlay class="absolute inset-0 bg-black/50 backdrop-blur-sm"></div>
    <div class="relative mx-auto mt-20 max-w-lg rounded-xl bg-white shadow-2xl">
      <div class="flex items-center justify-between px-4 py-3 border-b border-gray-200">
        <h5 class="m-0 font-semibold">🏷️ Gestión de Sectores</h5>
        <button type="button" class="text-gray-500 hover:text-gray-700" data-modal-close aria-label="Cerrar">✕</button>
      </div>
      <form id="form-sector">
        <div class="p-4">
          <div class="grid grid-cols-1 md:grid-cols-3 gap-3 mb-3">
            <div class="md:col-span-2">
              <input id="input-nuevo-sector" name="sector" placeholder="Nombre del sector" class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring focus:ring-blue-200" required>
            </div>
          </div>
          <ul id="lista-sectores" class="list-group divide-y divide-gray-100"></ul>
        </div>
        <div class="px-4 py-3 border-t border-gray-200 flex items-center justify-end gap-2">
          <button type="button" class="inline-flex items-center px-4 py-2 text-sm font-medium rounded border border-gray-300 text-gray-700 hover:bg-gray-100" data-modal-close>Cancelar</button>
          <button class="inline-flex items-center px-4 py-2 text-sm font-medium rounded bg-emerald-600 text-white hover:bg-emerald-700" type="submit">Crear sector</button>
        </div>
      </form>
    </div>
  </div>

  <!-- Modal Confirmar Eliminación de Sector (Tailwind) -->
  <div id="modalConfirmEliminarSector" class="fixed inset-0 z-50 hidden">
    <div data-modal-overlay class="absolute inset-0 bg-black/40"></div>
    <div class="relative mx-auto mt-24 max-w-sm rounded-md bg-white shadow-lg">
      <div class="px-5 py-4 border-b border-gray-200">
        <h5 class="m-0 font-semibold text-gray-900">Confirmar eliminación</h5>
      </div>
      <div class="px-5 py-4 text-sm text-gray-700">
        ¿Eliminar el sector <span class="font-semibold" id="sectorAEliminar"></span>? Esta acción no se puede deshacer.
      </div>
      <div class="px-5 py-3 border-t border-gray-200 flex items-center justify-end gap-2">
        <button type="button" class="inline-flex items-center px-3 py-1.5 text-sm font-medium rounded border border-gray-300 text-gray-700 hover:bg-gray-100" data-modal-close>Cancelar</button>
        <button type="button" id="confirmDeleteSectorBtn" class="inline-flex items-center px-3 py-1.5 text-sm font-medium rounded bg-red-600 text-white hover:bg-red-700">Eliminar</button>
      </div>
    </div>
  </div>

  <!-- Modal Editar Dispositivo (Tailwind) -->
  <div id="modalEditarDispositivo" class="fixed inset-0 z-50 hidden">
    <div data-modal-overlay class="absolute inset-0 bg-black/40"></div>
    <div class="relative mx-auto mt-20 max-w-lg rounded-md bg-white shadow-lg">
      <form id="form-edit">
        <div class="flex items-center justify-between px-4 py-3 border-b border-gray-200">
          <h5 class="m-0 font-semibold">✏️ Editar dispositivo</h5>
          <button type="button" class="text-gray-500 hover:text-gray-700" data-modal-close aria-label="Cerrar">✕</button>
        </div>
        <div class="p-4 grid grid-cols-2 gap-3">
          <input type="hidden" name="chipid">
          <div><input name="tag" placeholder="Tag" class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring focus:ring-blue-200" required></div>
          <div><input name="nombre" placeholder="Modelo" class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring focus:ring-blue-200"></div>
          <div><input name="ciudad" placeholder="Ciudad" class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring focus:ring-blue-200"></div>
          <div>
            <select name="sector" class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring focus:ring-blue-200" required>
              <option value="">Seleccione un sector</option>
            </select>
          </div>
        </div>
        <div class="px-4 py-3 border-t border-gray-200 text-right">
          <button class="inline-flex items-center px-4 py-2 text-sm font-medium rounded bg-blue-600 text-white hover:bg-blue-700" type="submit">Guardar cambios</button>
        </div>
      </form>
    </div>
  </div>

  <script>
    // Estados actuales por chipid (solo en RAM, provistos por API)
    const puertosDispositivos = {}; // chipid -> { pin: { estado, modo, disp } }
    let latestFirmwareVersion = null; // Versión más reciente del firmware
    
    // Cargar versión de firmware del manifest
    function loadLatestFirmwareVersion() {
      fetch('/assets/flash/esp8266-manifest.json')
        .then(r => r.json())
        .then(data => {
          latestFirmwareVersion = data.version || null;
          console.log('Versión de firmware más reciente:', latestFirmwareVersion);
        })
        .catch(err => {
          console.error('Error cargando versión de firmware:', err);
        });
    }
    
    // Comparar versiones de firmware
    function compareFirmwareVersion(deviceVersion) {
      if (!latestFirmwareVersion || !deviceVersion) return 'unknown';
      return deviceVersion === latestFirmwareVersion ? 'updated' : 'outdated';
    }

    // Íconos: se proveen globalmente desde layout.php (window.loadIcons / window.applyIcons)
    // Fallback: si los SVG no cargaron aún, mostrar el texto también en XS
    function ensureActionIcons(context) {
      try {
        const root = document.querySelector(context);
        if (!root) return;
        // Columna Acción (sm+)
        root.querySelectorAll('#lista-dispositivos td:nth-last-child(2) a, #lista-dispositivos td:nth-last-child(2) button')
          .forEach(btn => {
            const icon = btn.querySelector('.icon');
            const label = btn.querySelector('span:not(.icon)');
            if (!(icon && icon.querySelector('svg')) && label) label.classList.remove('hidden');
          });
        // Toolbar móvil (XS) dentro de la primera celda
        root.querySelectorAll('#lista-dispositivos td .sm\\:hidden a, #lista-dispositivos td .sm\\:hidden button')
          .forEach(btn => {
            const icon = btn.querySelector('.icon');
            let srLabel = btn.querySelector('span.sr-only');
            if (!(icon && icon.querySelector('svg'))) {
              // Si no hay SVG, mostrar texto corto en lugar de sr-only
              if (srLabel) srLabel.classList.remove('sr-only');
              // Si no hay etiqueta, crear una abreviada
              if (!srLabel) {
                const abbr = document.createElement('span');
                abbr.textContent = btn.getAttribute('aria-label') || 'Acción';
                abbr.className = 'ml-1';
                btn.appendChild(abbr);
              }
            }
          });
      } catch {}
    }

    // Botones de acciones del header
    document.addEventListener('DOMContentLoaded', function(){
      const btnCreateDevice = document.getElementById('pageCreateDevice');
      if (btnCreateDevice) btnCreateDevice.addEventListener('click', function(){
        if (window.openModal) window.openModal('modalCrearDispositivo');
      });
      const btnCreateSector = document.getElementById('pageCreateSector');
      if (btnCreateSector) btnCreateSector.addEventListener('click', function(){
        if (window.openModal) window.openModal('modalGestionSectores');
      });
      
      // Checkbox para ocultar inactivos
      const hideOfflineCheckbox = document.getElementById('hideOfflineDevices');
      if (hideOfflineCheckbox) {
        // Restaurar estado desde localStorage
        try {
          const savedState = localStorage.getItem('devices_hideOffline');
          if (savedState !== null) {
            hideOfflineCheckbox.checked = savedState === 'true';
          }
        } catch(e) {}
        
        // Event listener para filtrar dispositivos
        hideOfflineCheckbox.addEventListener('change', function() {
          // Guardar preferencia
          try {
            localStorage.setItem('devices_hideOffline', this.checked);
          } catch(e) {}
          
          // Aplicar filtro a las tarjetas existentes
          filterDevices();
        });
      }
    });

    // Helper: aplica clases Tailwind destacadas al badge de estado (responsivo)
    function applyEstadoClasses(badge, estado) {
      if (!badge) return;
      // Remover clases previas del badge
      badge.classList.remove('bg-emerald-600', 'bg-gray-500', 'bg-amber-600', 'text-white', 'shadow-sm');
      
      // Aplicar fondo al card según estado
      const card = badge.closest('.device-card');
      if (card) {
        card.classList.remove('bg-white', 'bg-emerald-50', 'bg-gray-100');
        if (estado === 'online') {
          card.classList.add('bg-emerald-50');
        } else if (estado === 'offline') {
          card.classList.add('bg-gray-100');
        } else {
          card.classList.add('bg-white');
        }
      }
      
      // Asegurar estructura interna del badge
      let dot = badge.querySelector('.estado-dot');
      if (!dot) {
        dot = document.createElement('span');
        dot.className = 'estado-dot inline-block w-3 h-3 md:w-2.5 md:h-2.5 rounded-full mr-1 ring-2 ring-white/60 shrink-0';
        badge.insertBefore(dot, badge.firstChild);
      }
      let textSpan = badge.querySelector('.estado-text');
      if (!textSpan) {
        textSpan = document.createElement('span');
        textSpan.className = 'estado-text';
        badge.appendChild(textSpan);
      }
      // Colores del dot
      const dotOnline = 'bg-emerald-200';
      const dotOffline = 'bg-gray-500';
      const dotUnknown = 'bg-amber-200';
      dot.classList.remove('bg-emerald-200', 'bg-gray-500', 'bg-amber-200');
      dot.classList.add(estado === 'online' ? dotOnline : (estado === 'offline' ? dotOffline : dotUnknown));
      // Texto visible solo en sm+
      textSpan.textContent = estado === 'online' ? 'Online' : (estado === 'offline' ? 'Offline' : 'Desconocido');
    }

    // Estados actuales por chipid para filtrado
    const estadosDispositivos = {};
    // Estados de pines en tiempo real
    const pinesEstados = {};


    // Helper: retorna clases y texto para estado al construir filas (evita repetición)
    function estadoUI(estado) {
      const st = String(estado || '').toLowerCase();
      const badgeCls = (st === 'online')
        ? 'bg-emerald-600 text-white shadow-sm'
        : (st === 'offline')
          ? 'bg-gray-500 text-white shadow-sm'
          : 'bg-amber-600 text-white shadow-sm';
      const dotCls = (st === 'online') ? 'bg-emerald-200' : (st === 'offline') ? 'bg-gray-500' : 'bg-amber-200';
      const estadoTxt = (st === 'online') ? 'Online' : (st === 'offline' ? 'Offline' : 'Desconocido');
      return { badgeCls, dotCls, estadoTxt };
    }


    function updateDispositivoEstado(chipid, estado) {
      estadosDispositivos[chipid] = estado; // Guardar estado
      const cards = document.querySelectorAll(`.device-card[data-chipid="${chipid}"]`);
      cards.forEach(card => {
        const badge = card.querySelector('.badge-estado');
        if (badge) applyEstadoClasses(badge, String(estado || '').toLowerCase());
      });
      
      // Reaplicar filtro después de actualizar estado
      filterDevices();
    }

    function updateDispositivoIP(chipid, ip) {
      const cards = document.querySelectorAll(`.device-card[data-chipid="${chipid}"]`);
      cards.forEach(card => {
        const ipEl = card.querySelector('.device-ip');
        if (ipEl) ipEl.textContent = ip || '-';
      });
    }

    function updateDispositivoPines(chipid, pines) {
      if (!pinesEstados[chipid]) pinesEstados[chipid] = {};
      Object.assign(pinesEstados[chipid], pines);
      renderPortsPreview(chipid); // Re-renderizar pines
    } 

    // Generar badge de firmware
    function getFirmwareBadge(deviceFirmware) {
      const status = compareFirmwareVersion(deviceFirmware);
      if (status === 'unknown') return '';
      
      if (status === 'updated') {
        return `<span class="inline-flex items-center gap-1 px-2 py-0.5 text-[10px] font-semibold rounded bg-emerald-100 text-emerald-700 border border-emerald-300" title="Firmware actualizado: ${deviceFirmware}">
          <svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
            <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
          </svg>
          <span>FW OK</span>
        </span>`;
      } else {
        return `<span class="inline-flex items-center gap-1 px-2 py-0.5 text-[10px] font-semibold rounded bg-amber-100 text-amber-700 border border-amber-300" title="Firmware desactualizado: ${deviceFirmware} (Disponible: ${latestFirmwareVersion})">
          <svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
            <path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
          </svg>
          <span>Actualizar</span>
        </span>`;
      }
    }
    
    function cargarDispositivos() { 
      api.get('/api/get_dispositivos', { _: Date.now() }).then(data => {
        let html = '<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">';

        for (const chipid in data) {
          const d = data[chipid];
          const chip = d.chipid || chipid;
          const estado = d.online ? 'online' : 'offline';
          estadosDispositivos[chip] = estado;
          if (d.pines && typeof d.pines === 'object') {
            pinesEstados[chip] = Object.assign(pinesEstados[chip] || {}, d.pines);
          }
          const { badgeCls, dotCls, estadoTxt } = estadoUI(estado);
          
          const cardBgClass = (estado === 'online') ? 'bg-emerald-50' : (estado === 'offline') ? 'bg-gray-100' : 'bg-white';
          
          html += `
          <div class="device-card ${cardBgClass} rounded-xl shadow-sm border-2 border-slate-200 hover:shadow-lg hover:border-emerald-300 transition-all duration-300 p-5 relative overflow-hidden" data-chipid="${d.chipid}">
            <!-- Barra lateral de estado -->
            <div class="absolute left-0 top-0 bottom-0 w-1 ${estado === 'online' ? 'bg-emerald-500' : 'bg-slate-300'}"></div>
            <!-- Header con Tag y Estado -->
            <div class="flex items-start justify-between mb-3">
              <div class="flex-1">
                <div class="flex items-center gap-2">
                  <h3 class="text-lg font-semibold text-gray-900">${d.tag || 'Sin tag'}</h3>
                  ${d.firmware ? getFirmwareBadge(d.firmware) : ''}
                </div>
                <p class="text-xs text-gray-500 mt-1"><code class="bg-gray-100 px-1.5 py-0.5 rounded">${d.chipid}</code></p>
              </div>
              <span class="badge-estado inline-flex items-center px-2.5 py-1 text-xs font-semibold rounded-full transition ${badgeCls}" title="${estadoTxt}">
                <span class="estado-dot inline-block w-2.5 h-2.5 rounded-full mr-1.5 ring-2 ring-white/60 ${dotCls}"></span>
                <span class="estado-text">${estadoTxt}</span>
              </span>
            </div>
            
            <!-- Info del dispositivo -->
            <div class="space-y-2 mb-4 text-sm">
              <div class="flex items-center text-gray-600">
                <span class="font-medium w-20">Modelo:</span>
                <span class="text-gray-900">${d.nombre || '-'}</span>
              </div>
              <div class="flex items-center text-gray-600">
                <span class="font-medium w-20">Ciudad:</span>
                <span class="text-gray-900">${d.ciudad || '-'}</span>
              </div>
              <div class="flex items-center text-gray-600">
                <span class="font-medium w-20">Sector:</span>
                <span class="text-gray-900">${d.sector || '-'}</span>
              </div>
              <div class="flex items-center text-gray-600">
                <span class="font-medium w-20">IP:</span>
                <span class="text-gray-900 device-ip">${d.ip || '-'}</span>
              </div>
            </div>
            
            <!-- Resumen de Puertos -->
            <div class="mb-4 pb-3 border-b border-slate-200">
              <div class="text-xs font-semibold text-slate-600 mb-2 uppercase">Estados</div>
              <div id="ports-preview-${d.chipid}" class="flex flex-wrap gap-1.5">
                <span class="text-xs text-slate-400">Cargando...</span>
              </div>
            </div>
            
            <!-- Botones de acción -->
            <div class="grid grid-cols-2 gap-2">
              <a href="/dashboard?chipid=${d.chipid}" class="inline-flex items-center justify-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md border border-blue-600 text-blue-700 hover:bg-blue-50 transition">
                <span class="icon icon-dashboard" aria-hidden="true"></span>
                <span>Dashboard</span>
              </a>
              <button class="editar-dispositivo inline-flex items-center justify-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md border border-blue-600 text-blue-700 hover:bg-blue-50 transition" data-chipid="${d.chipid}">
                <span class="icon icon-edit" aria-hidden="true"></span>
                <span>Editar</span>
              </button>
              <a href="/puertos?chipid=${d.chipid}" class="inline-flex items-center justify-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md border border-amber-600 text-amber-700 hover:bg-amber-50 transition">
                <span class="icon icon-puzzle" aria-hidden="true"></span>
                <span>Puertos</span>
              </a>
              <button class="reiniciar-dispositivo inline-flex items-center justify-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md border border-red-600 text-red-700 hover:bg-red-50 transition" data-chipid="${d.chipid}">
                <span class="icon icon-reboot" aria-hidden="true"></span>
                <span>Reiniciar</span>
              </button>
            </div>
          </div>`;
        }

        html += '</div>';
        const listaEl = document.getElementById('lista-dispositivos');
        if (listaEl) listaEl.innerHTML = html;
        try { if (window.applyIcons) window.applyIcons('#lista-dispositivos'); } catch {}
        ensureActionIcons('#lista-dispositivos');

        // Aplicar filtro de ocultar offline si está activado
        filterDevices();
        
        // Cargar estados de puertos para cada dispositivo
        for (const chipid in data) {
          loadDevicePorts(chipid);
        }
      }).catch(err => {
        console.error('Error cargando dispositivos:', err);
        mostrarToast('Error al cargar dispositivos', { type: 'danger' });
      });
    }
    
    // Función para filtrar dispositivos offline
    function filterDevices() {
      const hideOffline = document.getElementById('hideOfflineDevices')?.checked || false;
      const deviceCards = document.querySelectorAll('.device-card');
      
      deviceCards.forEach(card => {
        const chipid = card.dataset.chipid;
        const estado = estadosDispositivos[chipid] || 'offline'; // Usar estado actual o offline por defecto
        
        if (hideOffline && estado === 'offline') {
          card.style.display = 'none';
        } else {
          card.style.display = '';
        }
      });
    }
    
    // Cargar estados de puertos de un dispositivo
    function loadDevicePorts(chipid) {
      api.get('/api/get_puertos', { chipid: chipid })
        .then(data => {
          if (data && !data.error) {
            puertosDispositivos[chipid] = data;
            renderPortsPreview(chipid);
          }
        })
        .catch(err => {
          console.error(`Error cargando puertos de ${chipid}:`, err);
        });
    }
    
    // Renderizar preview de puertos en la tarjeta
    function renderPortsPreview(chipid) {
      const container = document.getElementById(`ports-preview-${chipid}`);
      if (!container) return;
      
      const ports = puertosDispositivos[chipid];
      if (!ports) {
        container.innerHTML = '<span class="text-xs text-slate-400">Sin datos</span>';
        return;
      }
      
      let html = '';
      let count = 0;
      const maxShow = 6; // Máximo de puertos a mostrar
      
      for (let pin in ports) {
        if (pin === 'update') continue;
        if (count >= maxShow) break;
        
        const p = ports[pin];
        if (p.modo === 'OUTPUT' && p.disp) {
          const state = (pinesEstados[chipid] && pinesEstados[chipid][pin]) || 'OFF';
          const isOn = (String(state).toUpperCase() === 'ON');
          
          html += `
            <div class="inline-flex items-center gap-1 px-2 py-1 rounded text-xs font-medium ${isOn ? 'bg-emerald-100 text-emerald-700 border border-emerald-300' : 'bg-red-50 text-red-700 border border-red-200'}" title="${p.disp} - ${pin} (${isOn ? 'ON' : 'OFF'})">
              <div class="w-1.5 h-1.5 rounded-full ${isOn ? 'bg-emerald-500' : 'bg-red-500'}"></div>
              <span class="truncate max-w-[70px]">${p.disp}</span>
              <span class="font-mono text-[10px] opacity-75">${pin}</span>
            </div>`;
          count++;
        }
      }
      
      if (html === '') {
        html = '<span class="text-xs text-slate-400">Sin salidas</span>';
      }
      
      container.innerHTML = html;
    }

    document.addEventListener('click', function(e) {
      const editBtn = e.target.closest('.editar-dispositivo');
      if (!editBtn) return;

      const chipid = editBtn.dataset.chipid;
      api.get('/api/get_dispositivos').then(data => {
        const d = data[chipid];
        if (!d) return alert("Dispositivo no encontrado");

        const form = document.getElementById('form-edit');
        if (form) {
          const fields = {
            chipid: d.chipid || '',
            tag: d.tag || '',
            nombre: d.nombre || '',
            ciudad: d.ciudad || '',
            sector: d.sector || ''
          };
          Object.keys(fields).forEach(key => {
            const input = form.querySelector(`[name="${key}"]`);
            if (input) input.value = fields[key];
          });
          window.openModal('modalEditarDispositivo');
        }
      }).catch(err => {
        console.error('Error cargando dispositivo:', err);
        mostrarToast('Error al cargar datos del dispositivo', { type: 'danger' });
      });
    });

    const formEdit = document.getElementById('form-edit');
    if (formEdit) {
      formEdit.addEventListener('submit', function (e) {
        e.preventDefault();
        const formData = new FormData(this);
        const editado = {};
        formData.forEach((value, key) => editado[key] = value);
        console.log('Enviando datos al servidor:', editado);
        
        // Mostrar indicador de carga
        const submitBtn = this.querySelector('button[type="submit"]');
        const originalBtnText = submitBtn.innerHTML;
        submitBtn.disabled = true;
        submitBtn.innerHTML = '<span class="inline-block animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full"></span> Procesando...';
        
        api.postJSON('/api/edit_dispositivo', editado)
          .then(resp => {
            console.log('Respuesta del servidor:', resp);
            if (resp && resp.success) {
              window.closeModal('modalEditarDispositivo');
              cargarDispositivos();
              mostrarToast('Dispositivo actualizado correctamente', { type: 'success' });
            } else {
              const errorMsg = resp && resp.msg ? resp.msg : 'Error desconocido al editar el dispositivo';
              console.error('Error en la respuesta:', errorMsg);
              mostrarToast(errorMsg, { type: 'danger' });
            }
          })
          .catch(err => {
            console.error('Error en la petición:', err);
            const errorMsg = err.data?.msg || err.data?.message || err.message || 'Error al comunicarse con el servidor';
            mostrarToast(errorMsg, { type: 'danger' });
          })
          .finally(() => {
            // Restaurar el botón
            submitBtn.disabled = false;
            submitBtn.innerHTML = originalBtnText;
          });
      });
    }

    // ==================== Sectores ====================

    // Cargar sectores al iniciar
    function cargarSectores() {
      api.get('/api/get_sectores').then(data => {
        let html = '';
        data.forEach(sector => {
          html += `
          <li class="flex items-center justify-between px-3 py-2">
            <span class="sector-nombre text-sm text-gray-800">${sector}</span>
            <div class="flex items-center gap-2">
              <button class="editar-sector inline-flex items-center px-2.5 py-1 text-xs font-medium rounded border border-amber-600 text-amber-700 hover:bg-amber-50" data-sector="${sector}">✏️ <span class="hidden sm:inline">Editar</span></button>
              <button class="eliminar-sector inline-flex items-center px-2.5 py-1 text-xs font-medium rounded border border-red-600 text-red-700 hover:bg-red-50" data-sector="${sector}">🗑️ <span class="hidden sm:inline">Eliminar</span></button>
            </div>
          </li>`;
        });
        const listaEl = document.getElementById('lista-sectores');
        if (listaEl) listaEl.innerHTML = html;
      }).catch(err => {
        console.error('Error cargando sectores:', err);
        mostrarToast('Error al cargar sectores', { type: 'danger' });
      });
    }

    // Manejo de la edición de sectores
    document.addEventListener('click', function(e) {
      const editBtn = e.target.closest('.editar-sector');
      if (!editBtn) return;

      const sector = editBtn.dataset.sector;
      const li = editBtn.closest('li');
      const span = li.querySelector('.sector-nombre');
      const nombreOriginal = span.textContent;

      // Cambiar el nombre a un campo de texto editable
      span.innerHTML = `<input type="text" class="w-full px-2 py-1 border border-gray-300 rounded text-sm focus:outline-none focus:ring focus:ring-blue-200" value="${nombreOriginal}" />`;

      // Cambiar el texto del botón de editar a guardar
      editBtn.innerHTML = '💾 <span class="hidden sm:inline">Guardar</span>';
      editBtn.classList.remove('border-amber-600', 'text-amber-700', 'hover:bg-amber-50');
      editBtn.classList.add('border-emerald-600', 'text-emerald-700', 'hover:bg-emerald-50');

      // Cambiar el manejador para guardar
      const saveHandler = function(evt) {
        evt.stopPropagation();
        const input = li.querySelector('input');
        const nuevoNombre = input ? input.value : '';
        
        if (nuevoNombre !== nombreOriginal) {
          if (nuevoNombre.trim() === "") {
            mostrarToast("El nombre del sector no puede estar vacío.", { type: 'danger' });
            return;
          }

          api.postJSON('/api/update_sector', {
            old_sector: nombreOriginal,
            new_sector: nuevoNombre
          }).then(resp => {
            console.log(resp);
            if (resp.success) {
              cargarSectores();
              mostrarToast('Sector actualizado correctamente', { type: 'success' });
            } else {
              mostrarToast(resp.msg || 'Error al actualizar sector', { type: 'danger' });
            }
          }).catch(err => {
            console.error("Error en la actualización del sector:", err);
            mostrarToast("Hubo un error al intentar actualizar el sector.", { type: 'danger' });
          });
        } else {
          cargarSectores();
        }
        editBtn.removeEventListener('click', saveHandler);
      };

      editBtn.addEventListener('click', saveHandler);
    });

    // Manejo de la eliminación de sectores con modal de confirmación
    let sectorPendienteEliminar = null;
    
    document.addEventListener('click', function(e) {
      const deleteBtn = e.target.closest('.eliminar-sector');
      if (!deleteBtn) return;

      sectorPendienteEliminar = deleteBtn.dataset.sector;
      const sectorNameEl = document.getElementById('sectorAEliminar');
      if (sectorNameEl) sectorNameEl.textContent = sectorPendienteEliminar;
      if (window.openModal) window.openModal('modalConfirmEliminarSector');
    });

    const confirmDelBtn = document.getElementById('confirmDeleteSectorBtn');
    if (confirmDelBtn) {
      confirmDelBtn.addEventListener('click', function(){
        if (!sectorPendienteEliminar) return;
        
        api.postJSON('/api/delete_sector', { sector: sectorPendienteEliminar })
          .then(resp => {
            if (resp.success) {
              mostrarToast('Sector eliminado', { type: 'success' });
              cargarSectores();
            } else {
              mostrarToast(resp.msg || 'No se pudo eliminar', { type: 'danger' });
            }
          })
          .catch(err => {
            console.error('Error eliminando sector:', err);
            mostrarToast('Error al eliminar sector', { type: 'danger' });
          })
          .finally(() => {
            if (window.closeModal) window.closeModal('modalConfirmEliminarSector');
            sectorPendienteEliminar = null;
          });
      });
    }

    // Agregar un sector
    const formSector = document.getElementById('form-sector');
    if (formSector) {
      formSector.addEventListener('submit', function (e) {
        e.preventDefault();
        const formData = new FormData(this);
        const datos = {};
        formData.forEach((value, key) => datos[key] = value);
        
        api.postJSON('/api/add_sector', datos)
          .then(resp => {
            if (resp.success) {
              this.reset();
              cargarSectores();
              mostrarToast('Sector agregado correctamente', { type: 'success' });
            } else {
              mostrarToast(resp.msg || 'Error al agregar sector', { type: 'danger' });
            }
          })
          .catch(err => {
            console.error('Error:', err);
            mostrarToast('Error al agregar sector', { type: 'danger' });
          });
      });
    }

    // Cargar sectores en los combos de los modales (Crear y Editar Dispositivo)
    function cargarSectoresEnSelectModal() {
      api.get('/api/get_sectores').then(data => {
        let html = '<option value="">Seleccione un sector</option>';
        data.forEach(sector => {
          html += `<option value="${sector}">${sector}</option>`;
        });
        const selects = document.querySelectorAll('#modalEditarDispositivo select[name="sector"], #modalCrearDispositivo select[name="sector"]');
        selects.forEach(select => select.innerHTML = html);
      }).catch(err => {
        console.error('Error cargando sectores:', err);
      });
    }

    // Al abrir el modal de creación (legacy bootstrap hook removido). Usar hook global.

    document.addEventListener('click', function(e) {
      const rebootBtn = e.target.closest('.reiniciar-dispositivo');
      if (!rebootBtn) return;

      const chipid = rebootBtn.dataset.chipid;
      if (!chipid) return mostrarToast('No se encontró el ChipID.');
      if (!confirm(`¿Confirmas reiniciar el dispositivo ${chipid}?`)) return;

      const topic = `dispositivo/${chipid}/comando/reboot`;
      const payload = '1';

      const publisher = window.mqttRealtime
        ? window.mqttRealtime.publish(topic, payload)
        : api.postJSON('/api/mqtt_publish', { topic, payload });

      publisher
        .then(resp => {
          mostrarToast(`Comando de reinicio enviado al dispositivo ${chipid}.`);
          rebootBtn.disabled = true;
        })
        .catch(err => {
          mostrarToast('Error al enviar el comando de reinicio.', { type: 'danger' });
          console.error(err);
        });
    });

    // Inicialización
    document.addEventListener('DOMContentLoaded', function() {
      loadLatestFirmwareVersion();
      cargarDispositivos();
      cargarSectores();
      cargarSectoresEnSelectModal();
      if (window.mqttRealtime) {
        window.mqttRealtime.onMessage(function(evt) {
          if (evt.type === 'state') updateDispositivoEstado(evt.chipid, evt.estado);
          if (evt.type === 'ip') updateDispositivoIP(evt.chipid, evt.ip);
          if (evt.type === 'pin') updateDispositivoPines(evt.chipid, { [evt.alias]: evt.valor });
        });
      }
    });

  </script>

<?php
$content = ob_get_clean();
// Si no se está renderizando como parcial, incluir el layout principal
if (!defined('RENDER_PARTIAL')) {
  include __DIR__ . '/../layouts/layout.php';
}
