<?php
// views/pages/conexoes.php
require_once __DIR__ . '/../../app/db.php';
require_once __DIR__ . '/../../app/plans.php';  // ← NOVO: sistema dinâmico
require_once __DIR__ . '/components/tutorial.php';

$currentInstance = '';
$pdo = db();

if (!empty($_SESSION['user']['email'])) {
  $stmt = $pdo->prepare('SELECT instance_name, state FROM users WHERE email = :e LIMIT 1');
  $stmt->execute([':e' => $_SESSION['user']['email']]);
  if ($row = $stmt->fetch()) {
    $currentInstance = $row['instance_name'] ?? '';
  }
}

// ── Permissão pra ver os toggles avançados (agente + responder todos) ──
// Usa o sistema dinâmico de planos. Se o usuário pode ver "agente-atendimento",
// também vê os toggles dele aqui na tela de conexões.
$canSeeAdvancedToggles = plans_user_can_view('agente-atendimento');
?>

<style>
/* ── Modal backdrop ── */
#connectModal,
#creatingModal,
#deletingModal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
#connectModal.open,
#creatingModal.open,
#deletingModal.open { display: flex; }

/* ── Modal box ── */
.modal-box {
  background: #fff;
  border-radius: 1.25rem;
  width: 100%;
  max-width: 460px;
  box-shadow: 0 24px 60px rgba(0,0,0,0.18);
  overflow: hidden;
  animation: modal-in .22s cubic-bezier(.4,0,.2,1);
}
.dark .modal-box { background: #111827; }

@keyframes modal-in {
  from { opacity:0; transform:translateY(18px) scale(.97); }
  to   { opacity:1; transform:translateY(0) scale(1); }
}

/* ── Step cards ── */
.method-card {
  cursor: pointer;
  border: 2px solid #e5e7eb;
  border-radius: .875rem;
  padding: 1.1rem 1.25rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  transition: border-color .15s, background .15s, box-shadow .15s;
}
.method-card:hover {
  border-color: #6366f1;
  background: #f5f3ff;
  box-shadow: 0 0 0 4px rgba(99,102,241,.08);
}
.dark .method-card { border-color: #374151; }
.dark .method-card:hover { background: #1e1b4b; border-color: #6366f1; }

.method-icon {
  width: 46px;
  height: 46px;
  border-radius: .625rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* ── Phone input ── */
.phone-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.phone-flag {
  position: absolute;
  left: .875rem;
  font-size: 1.25rem;
  pointer-events: none;
  user-select: none;
}
#phoneInput {
  width: 100%;
  padding: .75rem .875rem .75rem 3rem;
  border: 2px solid #e5e7eb;
  border-radius: .75rem;
  font-size: .925rem;
  outline: none;
  transition: border-color .15s;
  background: #f9fafb;
}
#phoneInput:focus { border-color: #6366f1; background: #fff; }
.dark #phoneInput { background: #1f2937; border-color: #374151; color: #f3f4f6; }
.dark #phoneInput:focus { border-color: #6366f1; background: #111827; }

/* ── Pairing code display ── */
.pairing-code-display {
  display: flex;
  justify-content: center;
  gap: .5rem;
  flex-wrap: wrap;
}
.pairing-segment {
  font-family: 'Courier New', monospace;
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: .08em;
  background: #f3f4f6;
  border: 2px solid #e5e7eb;
  border-radius: .5rem;
  padding: .5rem .875rem;
  min-width: 70px;
  text-align: center;
  color: #111827;
}
.dark .pairing-segment { background: #1f2937; border-color: #374151; color: #f3f4f6; }

/* ── Pulse ring for connected ── */
@keyframes ping-slow {
  0%   { transform:scale(1); opacity:.8; }
  100% { transform:scale(1.6); opacity:0; }
}
.pulse-ring::after {
  content:'';
  position:absolute;
  inset:0;
  border-radius:50%;
  background:currentColor;
  animation: ping-slow .9s ease-out infinite;
}

/* ── Spinner ── */
.spin {
  width: 20px; height: 20px;
  border: 2.5px solid rgba(99,102,241,.2);
  border-top-color: #6366f1;
  border-radius: 50%;
  animation: spin .7s linear infinite;
  display: inline-block;
}
@keyframes spin { to { transform:rotate(360deg); } }

/* ── QR pulse while loading ── */
.qr-skeleton {
  width: 240px; height: 240px;
  border-radius: .75rem;
  background: linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s infinite;
}
.dark .qr-skeleton { background: linear-gradient(90deg,#1f2937 25%,#374151 50%,#1f2937 75%); background-size:200% 100%; }
@keyframes shimmer { to { background-position:-200% 0; } }

/* ── Progress bar for creating modal ── */
.creating-progress-bar {
  width: 100%;
  height: 6px;
  background: #e5e7eb;
  border-radius: 999px;
  overflow: hidden;
}
.dark .creating-progress-bar { background: #374151; }

.creating-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #6366f1, #818cf8);
  border-radius: 999px;
  width: 0%;
  transition: width 0.4s ease;
}

/* ── Animated dots ── */
@keyframes dotPulse {
  0%, 80%, 100% { opacity: 0.3; }
  40% { opacity: 1; }
}
.dot-animation span {
  animation: dotPulse 1.4s ease-in-out infinite;
  font-weight: 700;
  font-size: 1.1em;
}
.dot-animation span:nth-child(2) { animation-delay: 0.2s; }
.dot-animation span:nth-child(3) { animation-delay: 0.4s; }

/* ── Checkmark animation ── */
@keyframes checkScale {
  0% { transform: scale(0); opacity: 0; }
  60% { transform: scale(1.15); }
  100% { transform: scale(1); opacity: 1; }
}
.check-animate {
  animation: checkScale 0.4s cubic-bezier(.4,0,.2,1) forwards;
}
</style>

<div class="mb-4 sm:mb-6">
<?= tutorial_component(['page' => 'conexoes']); ?>

</div>



<!-- Card principal -->
<div class="rounded-xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 p-6">
  <div class="flex items-center justify-between mb-4">
    <h2 class="text-xl font-semibold">Conexão WhatsApp</h2>
  </div>
  
  <p class="text-xs text-gray-500 dark:text-gray-400 mb-4">
  Para melhor experiência e maior estabilidade na conexão, recomendamos utilizar o <span class="font-medium">WhatsApp Business</span>.
</p>

  <!-- Bloco: sem instância -->
  <div id="createBlock" class="<?= $currentInstance ? 'hidden' : '' ?>">
    <button id="btnCreate" class="rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 transition-colors">
      Criar conexão
    </button>
    <p class="text-xs text-gray-500 mt-1">Clique acima para criar sua conexão.</p>
  </div>

  <!-- Bloco: instância existente -->
  <div id="cardBlock" class="<?= $currentInstance ? '' : 'hidden' ?> mt-4">
    <div class="rounded-xl border border-gray-200 dark:border-gray-800 p-4 bg-gray-50 dark:bg-gray-950">
      <div class="flex items-start justify-between">
        <div>
          <div class="text-sm text-gray-500">Conexão</div>
          <div class="text-lg font-semibold" id="cardName"><?= htmlspecialchars($currentInstance ?: '—') ?></div>
        </div>
        <button id="btnDelete" class="rounded-lg bg-rose-600 hover:bg-rose-700 text-white px-3 py-2 text-sm transition-colors flex items-center gap-1.5">
          <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
          </svg>
          Excluir
        </button>
      </div>

      <!-- Status destacado com fundo colorido -->
      <div id="statusIndicator" class="mt-3 inline-flex items-center gap-3 rounded-lg px-4 py-2.5 border-2 bg-amber-50 border-amber-200 dark:bg-amber-950/40 dark:border-amber-800 transition-all duration-300">
        <span id="statusDot" class="relative flex h-3 w-3 flex-shrink-0">
          <span id="statusDotPing" class="animate-ping absolute inline-flex h-full w-full rounded-full bg-amber-400 opacity-75"></span>
          <span id="statusDotCore" class="relative inline-flex rounded-full h-3 w-3 bg-amber-500"></span>
        </span>
        <div class="flex flex-col">
          <span id="badgeState" class="text-sm font-semibold text-amber-800 dark:text-amber-300">Carregando…</span>
          <span id="badgeStateHint" class="text-xs text-amber-600/80 dark:text-amber-400/70">Verificando status…</span>
        </div>
        <span id="statusIcon" class="ml-auto flex-shrink-0 text-amber-500 dark:text-amber-400">
          <svg class="w-5 h-5 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
          </svg>
        </span>
      </div>

      <?php if ($canSeeAdvancedToggles): ?>
        <!-- Toggle agente -->
        <div class="mt-4">
          <div class="flex flex-col gap-2">
            <div class="flex items-center gap-3">
              <div class="text-sm text-gray-600 dark:text-gray-300">Agente de atendimento ligado?</div>
              <label class="inline-flex items-center cursor-pointer">
                <input type="checkbox" id="toggleWebhook" class="sr-only peer">
                <div class="w-11 h-6 bg-gray-200 rounded-full peer peer-checked:bg-emerald-600 relative transition-colors">
                  <div class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full transition-transform peer-checked:translate-x-5"></div>
                </div>
              </label>
            </div>
            <div class="flex items-center gap-2">
              <span id="webhookBadge" class="hidden text-xs px-2 py-1 rounded"></span>
              <span id="webhookInfo" class="text-xs text-gray-500">—</span>
            </div>
          </div>
        </div>

        <!-- Toggle responder todos -->
        <div class="mt-4">
          <div class="flex flex-col gap-2">
            <div class="flex items-center gap-3">
              <div class="text-sm text-gray-600 dark:text-gray-300">Responder Todos?</div>
              <label class="inline-flex items-center cursor-pointer">
                <input type="checkbox" id="toggleReplyAll" class="sr-only peer">
                <div class="w-11 h-6 bg-gray-200 rounded-full peer peer-checked:bg-indigo-600 relative transition-colors">
                  <div class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full transition-transform peer-checked:translate-x-5"></div>
                </div>
              </label>
            </div>
            <div class="flex items-center gap-2">
              <span id="replyAllBadge" class="hidden text-xs px-2 py-1 rounded"></span>
              <span id="replyAllInfo" class="text-xs text-gray-500">Se ligado responderá leads de todas origens.</span>
            </div>
          </div>
        </div>
      <?php endif; ?>

      <!-- Botão conectar -->
      <div class="mt-6 flex items-center gap-3">
        <button id="btnQR" class="rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 text-sm font-medium transition-colors flex items-center gap-2">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/>
          </svg>
          Conectar WhatsApp
        </button>
        <span id="statusBadge" class="hidden text-xs px-2 py-1 rounded"></span>
      </div>

      <!-- Área exibida durante/após conexão -->
      <div id="qrWrap" class="mt-4 hidden">
        <div class="rounded-lg border border-gray-200 dark:border-gray-800 p-4 grid md:grid-cols-[auto_1fr] gap-6 items-start">
          <div class="flex flex-col items-center">
            <!-- QR Code -->
            <div id="qrcode" class="bg-white p-2 rounded shadow-sm"></div>
            <!-- Código de pareamento formatado -->
            <div id="pairingDisplay" class="hidden mt-3 w-full">
              <p class="text-xs text-center text-gray-500 mb-2">Digite este código no seu WhatsApp</p>
              <div id="pairingSegments" class="pairing-code-display"></div>
            </div>
            <!-- Indicador de status em tempo real -->
            <div id="liveStatus" class="mt-3 flex items-center gap-2 text-xs text-gray-500">
              <span class="spin"></span>
              <span id="liveStatusText">Aguardando conexão…</span>
            </div>
          </div>
          <div id="connectInstructions" class="text-sm text-gray-600 dark:text-gray-300 leading-relaxed">
            <!-- preenchido via JS dependendo do modo -->
          </div>
        </div>
      </div>

    </div>
  </div>
</div>

<!-- ══════════════════════════════════════════════════════════
     MODAL: Criando conexão (loading com progress)
══════════════════════════════════════════════════════════ -->
<div id="creatingModal" role="dialog" aria-modal="true" aria-labelledby="creatingModalTitle">
  <div class="modal-box" style="max-width:400px;">
    <div class="px-6 py-8 flex flex-col items-center gap-5">
      <!-- Ícone animado -->
      <div id="creatingIconWrap">
        <div class="w-16 h-16 rounded-2xl bg-indigo-50 dark:bg-indigo-950 flex items-center justify-center">
          <svg id="creatingSpinnerIcon" class="w-8 h-8 text-indigo-600" style="animation: spin 1.2s linear infinite;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
          </svg>
          <svg id="creatingCheckIcon" class="w-8 h-8 text-emerald-500 hidden check-animate" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7"/>
          </svg>
        </div>
      </div>

      <!-- Texto -->
      <div class="text-center">
        <h3 id="creatingModalTitle" class="text-base font-semibold text-gray-900 dark:text-gray-100">
          Criando sua conexão<span class="dot-animation"><span>.</span><span>.</span><span>.</span></span>
        </h3>
        <p id="creatingModalSubtitle" class="text-sm text-gray-500 dark:text-gray-400 mt-1">Isso pode levar alguns segundos</p>
      </div>

      <!-- Progress bar -->
      <div class="w-full px-2">
        <div class="creating-progress-bar">
          <div id="creatingProgressFill" class="creating-progress-fill"></div>
        </div>
        <p id="creatingProgressLabel" class="text-xs text-gray-400 dark:text-gray-500 text-center mt-2">Inicializando…</p>
      </div>
    </div>
  </div>
</div>

<!-- ══════════════════════════════════════════════════════════
     MODAL: Confirmação de exclusão
══════════════════════════════════════════════════════════ -->
<div id="deletingModal" role="dialog" aria-modal="true" aria-labelledby="deletingModalTitle">
  <div class="modal-box" style="max-width:420px;">

    <!-- Step 1: Confirmação -->
    <div id="deleteStepConfirm" class="px-6 py-6">
      <div class="flex flex-col items-center gap-4">
        <!-- Ícone de alerta -->
        <div class="w-14 h-14 rounded-2xl bg-rose-50 dark:bg-rose-950 flex items-center justify-center">
          <svg class="w-7 h-7 text-rose-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
          </svg>
        </div>

        <div class="text-center">
          <h3 id="deletingModalTitle" class="text-base font-semibold text-gray-900 dark:text-gray-100">Excluir conexão?</h3>
          <p class="text-sm text-gray-500 dark:text-gray-400 mt-1.5 leading-relaxed">
            Sua instância será removida permanentemente.<br>
            Você poderá criar uma nova depois.
          </p>
        </div>

        <div class="flex gap-3 w-full mt-1">
          <button id="deleteCancel" class="flex-1 rounded-lg border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 px-4 py-2.5 text-sm font-medium hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors">
            Cancelar
          </button>
          <button id="deleteConfirm" class="flex-1 rounded-lg bg-rose-600 hover:bg-rose-700 text-white px-4 py-2.5 text-sm font-medium transition-colors flex items-center justify-center gap-2">
            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
            </svg>
            Excluir
          </button>
        </div>
      </div>
    </div>

    <!-- Step 2: Loading / Resultado -->
    <div id="deleteStepLoading" class="hidden px-6 py-8">
      <div class="flex flex-col items-center gap-5">
        <div>
          <div class="w-16 h-16 rounded-2xl bg-rose-50 dark:bg-rose-950 flex items-center justify-center">
            <svg id="deleteSpinnerIcon" class="w-8 h-8 text-rose-500" style="animation: spin 1.2s linear infinite;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
            </svg>
            <svg id="deleteCheckIcon" class="w-8 h-8 text-emerald-500 hidden check-animate" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7"/>
            </svg>
            <svg id="deleteErrorIcon" class="w-8 h-8 text-rose-500 hidden check-animate" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M6 18L18 6M6 6l12 12"/>
            </svg>
          </div>
        </div>
        <div class="text-center">
          <h3 id="deleteLoadingTitle" class="text-base font-semibold text-gray-900 dark:text-gray-100">
            Excluindo conexão<span class="dot-animation"><span>.</span><span>.</span><span>.</span></span>
          </h3>
          <p id="deleteLoadingSubtitle" class="text-sm text-gray-500 dark:text-gray-400 mt-1">Removendo instância do servidor</p>
        </div>
        <div class="w-full px-2">
          <div class="creating-progress-bar">
            <div id="deleteProgressFill" class="creating-progress-fill" style="background: linear-gradient(90deg, #e11d48, #fb7185);"></div>
          </div>
        </div>
      </div>
    </div>

  </div>
</div>
<div id="connectModal" role="dialog" aria-modal="true" aria-labelledby="modalTitle">
  <div class="modal-box">
    <!-- Header -->
    <div class="flex items-center justify-between px-6 pt-5 pb-4 border-b border-gray-100 dark:border-gray-800">
      <div>
        <h2 id="modalTitle" class="text-base font-semibold text-gray-900 dark:text-gray-100">Conectar WhatsApp</h2>
        <p class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">Escolha como deseja vincular sua conta</p>
      </div>
      <button id="modalClose" class="rounded-lg p-1.5 hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-400 hover:text-gray-600 transition-colors" aria-label="Fechar">
        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
        </svg>
      </button>
    </div>

    <!-- Step 1: escolha método -->
    <div id="stepChoose" class="px-6 py-5 flex flex-col gap-3">

      <!-- QR Code -->
      <button class="method-card text-left" id="chooseQR">
        <div class="method-icon bg-indigo-50 dark:bg-indigo-950 text-indigo-600">
          <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
              d="M12 4H7a3 3 0 00-3 3v5m0 0h5m-5 0v5a3 3 0 003 3h5m0 0v-5m0 5h5a3 3 0 003-3v-5m0 0h-5m5 0V7a3 3 0 00-3-3h-5"/>
          </svg>
        </div>
        <div>
          <div class="font-medium text-gray-900 dark:text-gray-100 text-sm">QR Code</div>
          <div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">Escaneie com a câmera do celular</div>
        </div>
        <svg class="w-4 h-4 text-gray-400 ml-auto flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
        </svg>
      </button>

      <!-- Código de Pareamento -->
      <button class="method-card text-left" id="choosePairing">
        <div class="method-icon bg-emerald-50 dark:bg-emerald-950 text-emerald-600">
          <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
              d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"/>
          </svg>
        </div>
        <div>
          <div class="font-medium text-gray-900 dark:text-gray-100 text-sm">Código de Pareamento</div>
          <div class="text-xs text-gray-500 dark:text-gray-400 mt-0.5">Insira um código no WhatsApp pelo número</div>
        </div>
        <svg class="w-4 h-4 text-gray-400 ml-auto flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
        </svg>
      </button>
    </div>

    <!-- Step 2a: QR – loading interno -->
    <div id="stepQR" class="hidden px-6 pb-6 flex flex-col items-center gap-4">
      <div id="qrModalSkeleton" class="relative flex items-center justify-center" style="width:220px;height:220px;">
        <!-- Grid pattern background -->
        <div class="absolute inset-0 rounded-xl bg-gray-50 dark:bg-gray-800 border-2 border-dashed border-gray-200 dark:border-gray-700 overflow-hidden">
          <div class="absolute inset-0" style="background-image: repeating-linear-gradient(0deg, transparent, transparent 19px, rgba(0,0,0,0.03) 19px, rgba(0,0,0,0.03) 20px), repeating-linear-gradient(90deg, transparent, transparent 19px, rgba(0,0,0,0.03) 19px, rgba(0,0,0,0.03) 20px);"></div>
          <!-- Shimmer sweep -->
          <div class="absolute inset-0" style="background: linear-gradient(105deg, transparent 40%, rgba(99,102,241,0.06) 50%, transparent 60%); background-size: 200% 100%; animation: shimmer 1.8s ease-in-out infinite;"></div>
        </div>
        <!-- Center icon -->
        <div class="relative flex flex-col items-center gap-2">
          <div class="w-12 h-12 rounded-xl bg-white dark:bg-gray-900 shadow-sm flex items-center justify-center">
            <svg class="w-6 h-6 text-indigo-500" style="animation: spin 2.5s linear infinite;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4H7a3 3 0 00-3 3v5m0 0h5m-5 0v5a3 3 0 003 3h5m0 0v-5m0 5h5a3 3 0 003-3v-5m0 0h-5m5 0V7a3 3 0 00-3-3h-5"/>
            </svg>
          </div>
        </div>
      </div>
      <!-- Progress + text -->
      <div class="w-full max-w-[220px]">
        <div class="creating-progress-bar">
          <div id="qrModalProgressFill" class="creating-progress-fill" style="width:0%;"></div>
        </div>
        <p id="qrModalProgressLabel" class="text-xs text-gray-400 dark:text-gray-500 text-center mt-2">Gerando QR Code…</p>
      </div>
    </div>

    <!-- Step 2b: Código de Pareamento – inserir número -->
    <div id="stepPairing" class="hidden px-6 pb-6">
      <p class="text-sm text-gray-600 dark:text-gray-400 mb-3">
        Digite o número do WhatsApp que deseja conectar (com DDD e código do país):
      </p>
      <div class="phone-input-wrap mb-3">
        <span class="phone-flag">🇧🇷</span>
        <input id="phoneInput" type="tel" placeholder="55 11 99999-9999" autocomplete="tel" inputmode="numeric">
      </div>
      <div id="pairingError" class="hidden text-xs text-rose-600 mb-3"></div>
      <div class="flex gap-2">
        <button id="btnBackMethod" class="flex-1 rounded-lg border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 px-4 py-2 text-sm hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors">
          Voltar
        </button>
        <button id="btnSendPairing" class="flex-2 rounded-lg bg-emerald-600 hover:bg-emerald-700 text-white px-5 py-2 text-sm font-medium transition-colors flex items-center gap-2">
          Gerar Código
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"/>
          </svg>
        </button>
      </div>
    </div>

    <!-- Footer com botão voltar ao escolher método (quando em step QR/Pairing) -->
    <div id="modalFooter" class="hidden px-6 pb-5 pt-3 border-t border-gray-100 dark:border-gray-800">
      <button id="btnBackToChoose" class="text-sm text-gray-500 hover:text-indigo-600 dark:hover:text-indigo-400 flex items-center gap-1.5 transition-colors rounded-lg px-3 py-1.5 -ml-3 hover:bg-gray-50 dark:hover:bg-gray-800">
        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
        </svg>
        Escolher outro método
      </button>
    </div>
  </div>
</div>

<script src="assets/js/qrcode.js"></script>

<script>
const API     = 'api/conexoes.php';
const HAS_ADVANCED = <?= json_encode($canSeeAdvancedToggles) ?>;

// ── Elementos principais ──────────────────────────────────────
const createBlock  = document.getElementById('createBlock');
const cardBlock    = document.getElementById('cardBlock');
const cardName     = document.getElementById('cardName');
const badgeState   = document.getElementById('badgeState');
const btnCreate    = document.getElementById('btnCreate');
const btnQR        = document.getElementById('btnQR');
const statusBd     = document.getElementById('statusBadge');
const qrWrap       = document.getElementById('qrWrap');
const qrBox        = document.getElementById('qrcode');
const pairingDisplay   = document.getElementById('pairingDisplay');
const pairingSegments  = document.getElementById('pairingSegments');
const liveStatus       = document.getElementById('liveStatus');
const liveStatusText   = document.getElementById('liveStatusText');
const connectInstructions = document.getElementById('connectInstructions');
const btnDelete    = document.getElementById('btnDelete');

const toggleWebhook = document.getElementById('toggleWebhook');
const webhookInfo   = document.getElementById('webhookInfo');
const webhookBadge  = document.getElementById('webhookBadge');
const toggleReplyAll = document.getElementById('toggleReplyAll');
const replyAllBadge  = document.getElementById('replyAllBadge');

// ── Elementos do modal de conexão ─────────────────────────────
const connectModal   = document.getElementById('connectModal');
const modalClose     = document.getElementById('modalClose');
const stepChoose     = document.getElementById('stepChoose');
const stepQR         = document.getElementById('stepQR');
const stepPairing    = document.getElementById('stepPairing');
const modalFooter    = document.getElementById('modalFooter');
const chooseQR       = document.getElementById('chooseQR');
const choosePairing  = document.getElementById('choosePairing');
const btnBackMethod  = document.getElementById('btnBackMethod');
const btnBackToChoose = document.getElementById('btnBackToChoose');
const btnSendPairing = document.getElementById('btnSendPairing');
const phoneInput     = document.getElementById('phoneInput');
const pairingError   = document.getElementById('pairingError');
const qrModalSkeleton = document.getElementById('qrModalSkeleton');

// ── Elementos do modal de criação ─────────────────────────────
const creatingModal         = document.getElementById('creatingModal');
const creatingProgressFill  = document.getElementById('creatingProgressFill');
const creatingProgressLabel = document.getElementById('creatingProgressLabel');
const creatingModalTitle    = document.getElementById('creatingModalTitle');
const creatingModalSubtitle = document.getElementById('creatingModalSubtitle');
const creatingSpinnerIcon   = document.getElementById('creatingSpinnerIcon');
const creatingCheckIcon     = document.getElementById('creatingCheckIcon');

// ── Elementos do modal de exclusão ────────────────────────────
const deletingModal        = document.getElementById('deletingModal');
const deleteStepConfirm    = document.getElementById('deleteStepConfirm');
const deleteStepLoading    = document.getElementById('deleteStepLoading');
const deleteCancel         = document.getElementById('deleteCancel');
const deleteConfirmBtn     = document.getElementById('deleteConfirm');
const deleteSpinnerIcon    = document.getElementById('deleteSpinnerIcon');
const deleteCheckIcon      = document.getElementById('deleteCheckIcon');
const deleteErrorIcon      = document.getElementById('deleteErrorIcon');
const deleteLoadingTitle   = document.getElementById('deleteLoadingTitle');
const deleteLoadingSubtitle = document.getElementById('deleteLoadingSubtitle');
const deleteProgressFill   = document.getElementById('deleteProgressFill');

// ── QR loading skeleton ──────────────────────────────────────
const qrLoadingSkeleton    = document.getElementById('qrLoadingSkeleton');

let pollInterval = null;
let currentMode  = null; // 'qr' | 'pairing'

// ── Helpers ───────────────────────────────────────────────────
function setBadge(el, type, text) {
  if (!el) return;

  // ── Special handling for the prominent status banner ──
  if (el.id === 'badgeState') {
    const indicator = document.getElementById('statusIndicator');
    const dotPing   = document.getElementById('statusDotPing');
    const dotCore   = document.getElementById('statusDotCore');
    const hint      = document.getElementById('badgeStateHint');
    const icon      = document.getElementById('statusIcon');

    el.textContent = text;
    el.className = 'text-sm font-semibold';

    // Base classes for indicator container
    const base = 'mt-3 inline-flex items-center gap-3 rounded-lg px-4 py-2.5 border-2 transition-all duration-300';

    const styles = {
      loading: {
        container: `${base} bg-gray-50 border-gray-200 dark:bg-gray-800/50 dark:border-gray-700`,
        label: ['text-gray-600', 'dark:text-gray-300'],
        dotPing: 'animate-ping absolute inline-flex h-full w-full rounded-full bg-gray-400 opacity-75',
        dotCore: 'relative inline-flex rounded-full h-3 w-3 bg-gray-400',
        hint: 'Verificando status…',
        icon: `<svg class="w-5 h-5 animate-spin" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>`,
        iconColor: 'text-gray-400'
      },
      ok: {
        container: `${base} bg-emerald-50 border-emerald-200 dark:bg-emerald-950/40 dark:border-emerald-800`,
        label: ['text-emerald-800', 'dark:text-emerald-300'],
        dotPing: 'animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75',
        dotCore: 'relative inline-flex rounded-full h-3 w-3 bg-emerald-500',
        hint: 'WhatsApp vinculado e operando normalmente',
        icon: `<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7"/></svg>`,
        iconColor: 'text-emerald-500'
      },
      warn: {
        container: `${base} bg-amber-50 border-amber-200 dark:bg-amber-950/40 dark:border-amber-800`,
        label: ['text-amber-800', 'dark:text-amber-300'],
        dotPing: 'absolute inline-flex h-full w-full rounded-full bg-amber-400 opacity-0',
        dotCore: 'relative inline-flex rounded-full h-3 w-3 bg-amber-500',
        hint: 'Clique em "Conectar WhatsApp" para vincular',
        icon: `<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4.5c-.77-.833-2.694-.833-3.464 0L3.34 16.5c-.77.833.192 2.5 1.732 2.5z"/></svg>`,
        iconColor: 'text-amber-500'
      },
      err: {
        container: `${base} bg-rose-50 border-rose-200 dark:bg-rose-950/40 dark:border-rose-800`,
        label: ['text-rose-800', 'dark:text-rose-300'],
        dotPing: 'absolute inline-flex h-full w-full rounded-full bg-rose-400 opacity-0',
        dotCore: 'relative inline-flex rounded-full h-3 w-3 bg-rose-500',
        hint: 'Não foi possível verificar a conexão',
        icon: `<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>`,
        iconColor: 'text-rose-500'
      }
    };

    const s = styles[type] || styles.loading;
    if (indicator) indicator.className = s.container;
    el.classList.add(...s.label);
    if (dotPing) dotPing.className = s.dotPing;
    if (dotCore) dotCore.className = s.dotCore;
    if (hint) {
      hint.textContent = s.hint;
      const hintColors = {
        loading: 'text-xs text-gray-500/80 dark:text-gray-400/60',
        ok:      'text-xs text-emerald-600/80 dark:text-emerald-400/60',
        warn:    'text-xs text-amber-600/80 dark:text-amber-400/60',
        err:     'text-xs text-rose-600/80 dark:text-rose-400/60'
      };
      hint.className = hintColors[type] || hintColors.loading;
    }
    if (icon) { icon.className = 'ml-auto flex-shrink-0 ' + s.iconColor; icon.innerHTML = s.icon; }
    return;
  }

  // ── Default badge behavior for other badges ──
  el.textContent = text;
  el.className = 'text-xs px-2 py-1 rounded';
  if (el.id === 'webhookBadge' || el.id === 'replyAllBadge') el.classList.add('inline-flex','items-center');
  if (type === 'loading') el.classList.add('bg-gray-100','text-gray-700');
  if (type === 'ok')      el.classList.add('bg-emerald-100','text-emerald-800');
  if (type === 'warn')    el.classList.add('bg-amber-100','text-amber-800');
  if (type === 'err')     el.classList.add('bg-rose-100','text-rose-800');
  el.classList.remove('hidden');
}

async function fetchJSON(url, opts) {
  const r = await fetch(url, opts);
  const t = await r.text();
  let d = null;
  try { d = JSON.parse(t); } catch {}
  if (!r.ok || !d) return { ok: false, status: r.status || 0, error: d?.error || t || 'Falha' };
  return d;
}

function stopPolling() {
  if (pollInterval) { clearInterval(pollInterval); pollInterval = null; }
}

// ── Modal de criação: controle ────────────────────────────────
let creatingProgressTimer = null;

function openCreatingModal() {
  // Reset state
  creatingProgressFill.style.width = '0%';
  creatingProgressLabel.textContent = 'Inicializando…';
  creatingModalTitle.innerHTML = 'Criando sua conexão<span class="dot-animation"><span>.</span><span>.</span><span>.</span></span>';
  creatingModalSubtitle.textContent = 'Isso pode levar alguns segundos';
  creatingSpinnerIcon.classList.remove('hidden');
  creatingCheckIcon.classList.add('hidden');
  creatingModal.classList.add('open');
  document.body.style.overflow = 'hidden';

  // Simulated progress steps
  const steps = [
    { pct: 15,  label: 'Inicializando…',            delay: 0    },
    { pct: 35,  label: 'Configurando instância…',    delay: 800  },
    { pct: 55,  label: 'Registrando no servidor…',   delay: 1800 },
    { pct: 75,  label: 'Aplicando configurações…',   delay: 3000 },
    { pct: 88,  label: 'Quase lá…',                  delay: 4500 },
  ];

  steps.forEach(s => {
    const t = setTimeout(() => {
      creatingProgressFill.style.width = s.pct + '%';
      creatingProgressLabel.textContent = s.label;
    }, s.delay);
    // Store timeout for cleanup
    if (!creatingProgressTimer) creatingProgressTimer = [];
    creatingProgressTimer.push(t);
  });
}

function completeCreatingModal(success, errorMsg) {
  // Clear pending timers
  if (Array.isArray(creatingProgressTimer)) {
    creatingProgressTimer.forEach(t => clearTimeout(t));
    creatingProgressTimer = null;
  }

  if (success) {
    creatingProgressFill.style.width = '100%';
    creatingProgressLabel.textContent = 'Conexão criada!';
    creatingModalTitle.innerHTML = 'Conexão criada com sucesso!';
    creatingModalSubtitle.textContent = '';
    creatingSpinnerIcon.classList.add('hidden');
    creatingCheckIcon.classList.remove('hidden');

    setTimeout(() => {
      creatingModal.classList.remove('open');
      document.body.style.overflow = '';
    }, 1200);
  } else {
    creatingProgressFill.style.width = '100%';
    creatingProgressFill.style.background = 'linear-gradient(90deg, #ef4444, #f87171)';
    creatingProgressLabel.textContent = errorMsg || 'Erro ao criar conexão';
    creatingModalTitle.innerHTML = 'Falha ao criar conexão';
    creatingModalSubtitle.textContent = 'Tente novamente em instantes';
    creatingSpinnerIcon.classList.add('hidden');

    setTimeout(() => {
      creatingModal.classList.remove('open');
      document.body.style.overflow = '';
      // Reset fill color for next use
      creatingProgressFill.style.background = '';
    }, 2500);
  }
}

// ── Polling em tempo real (checa a cada 2s) ───────────────────

// ── Modal de exclusão: controle ───────────────────────────────
function openDeleteModal() {
  deleteStepConfirm.classList.remove('hidden');
  deleteStepLoading.classList.add('hidden');
  deleteSpinnerIcon.classList.remove('hidden');
  deleteCheckIcon.classList.add('hidden');
  deleteErrorIcon.classList.add('hidden');
  deleteProgressFill.style.width = '0%';
  deletingModal.classList.add('open');
  document.body.style.overflow = 'hidden';
}

function closeDeleteModal() {
  deletingModal.classList.remove('open');
  document.body.style.overflow = '';
}

function startDeleteLoading() {
  deleteStepConfirm.classList.add('hidden');
  deleteStepLoading.classList.remove('hidden');
  deleteSpinnerIcon.classList.remove('hidden');
  deleteCheckIcon.classList.add('hidden');
  deleteErrorIcon.classList.add('hidden');
  deleteLoadingTitle.innerHTML = 'Excluindo conexão<span class="dot-animation"><span>.</span><span>.</span><span>.</span></span>';
  deleteLoadingSubtitle.textContent = 'Removendo instância do servidor';

  // Simulated progress
  setTimeout(() => { deleteProgressFill.style.width = '30%'; }, 200);
  setTimeout(() => { deleteProgressFill.style.width = '60%'; }, 1000);
  setTimeout(() => { deleteProgressFill.style.width = '80%'; }, 2500);
}

function completeDeleteModal(success, errorMsg) {
  deleteProgressFill.style.width = '100%';
  deleteSpinnerIcon.classList.add('hidden');

  if (success) {
    deleteCheckIcon.classList.remove('hidden');
    deleteLoadingTitle.innerHTML = 'Conexão removida!';
    deleteLoadingSubtitle.textContent = 'Você pode criar uma nova conexão';
    deleteProgressFill.style.background = 'linear-gradient(90deg, #10b981, #34d399)';
    setTimeout(() => {
      closeDeleteModal();
      deleteProgressFill.style.background = '';
    }, 1200);
  } else {
    deleteErrorIcon.classList.remove('hidden');
    deleteLoadingTitle.innerHTML = 'Falha ao excluir';
    deleteLoadingSubtitle.textContent = errorMsg || 'Tente novamente em instantes';
    setTimeout(() => {
      closeDeleteModal();
    }, 2500);
  }
}

// ── QR Skeleton helpers ───────────────────────────────────────
function showQRSkeleton() {
  if (qrLoadingSkeleton) {
    qrLoadingSkeleton.classList.remove('hidden');
  }
}

function hideQRSkeleton() {
  if (qrLoadingSkeleton) {
    qrLoadingSkeleton.classList.add('hidden');
  }
}

// ── Polling em tempo real (checa a cada 2s) ───────────────────
function startRealTimePolling() {
  stopPolling();
  setLiveStatus('loading', 'Aguardando conexão…');

  pollInterval = setInterval(async () => {
    const st = await fetchJSON(`${API}?action=qrpoll`);

    if (!st.ok) return; // ignora erros transientes

    if (st.connected) {
      stopPolling();
      onConnected();
      return;
    }

    // Se chegou um QR novo, atualiza silenciosamente (sem resetar timer)
    if (st.qr && currentMode === 'qr') {
      showQRImage(st.qr);
    }
  }, 2000);
}

function setLiveStatus(type, text) {
  if (!liveStatus || !liveStatusText) return;
  liveStatus.classList.remove('hidden');
  liveStatusText.textContent = text;
  const spinEl = liveStatus.querySelector('.spin');
  if (type === 'loading' && spinEl) spinEl.style.display = 'inline-block';
  if (type !== 'loading' && spinEl) spinEl.style.display = 'none';
  if (type === 'ok') {
    liveStatus.innerHTML = `
      <svg class="w-4 h-4 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7"/>
      </svg>
      <span class="text-emerald-600 font-medium">${text}</span>`;
  }
  if (type === 'err') {
    liveStatus.innerHTML = `
      <svg class="w-4 h-4 text-rose-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
      </svg>
      <span class="text-rose-600">${text}</span>`;
  }
}

function onConnected() {
  closeModal();
  qrWrap.classList.remove('hidden');
  setLiveStatus('ok', 'Conectado com sucesso!');
  setBadge(badgeState, 'ok', 'Conectado');
  setBadge(statusBd, 'ok', 'Conectado!');
  setTimeout(() => location.reload(), 1800);
}

// ── Modal: abrir / fechar ─────────────────────────────────────
function openModal() {
  showStep('choose');
  connectModal.classList.add('open');
  document.body.style.overflow = 'hidden';
}

function closeModal() {
  stopPolling();
  connectModal.classList.remove('open');
  document.body.style.overflow = '';
  currentMode = null;
}

function showStep(step) {
  stepChoose.classList.add('hidden');
  stepQR.classList.add('hidden');
  stepPairing.classList.add('hidden');
  modalFooter.classList.add('hidden');
  pairingError.classList.add('hidden');

  if (step === 'choose') {
    stepChoose.classList.remove('hidden');
  } else if (step === 'qr') {
    stepQR.classList.remove('hidden');
    modalFooter.classList.remove('hidden');
  } else if (step === 'pairing') {
    stepPairing.classList.remove('hidden');
    modalFooter.classList.remove('hidden');
  }
}

function goToStep(step) {
  stepChoose.classList.add('hidden');
  stepQR.classList.add('hidden');
  stepPairing.classList.add('hidden');
  modalFooter.classList.add('hidden');
  pairingError.classList.add('hidden');

  if (step === 'choose') {
    stepChoose.classList.remove('hidden');
    stopPolling();
    currentMode = null;
  } else if (step === 'qr') {
    stepQR.classList.remove('hidden');
    modalFooter.classList.remove('hidden');
  } else if (step === 'pairing') {
    stepPairing.classList.remove('hidden');
    modalFooter.classList.remove('hidden');
  }
}

// ── QR Code: exibir imagem ────────────────────────────────────
function showQRImage(qr) {
  // Ensure qrBox is visible (may be hidden in pairing mode)
  qrBox.classList.remove('hidden');
  qrBox.style.minWidth = '244px';
  qrBox.style.minHeight = '244px';

  // Remove skeleton if present
  const skel = qrBox.querySelector('#qrLoadingSkeleton');
  if (skel) skel.remove();

  if (qr.image || qr.img) {
    const src = qr.image || qr.img;
    if (qrBox.querySelector('img')?.src !== src) {
      qrBox.innerHTML = `<img src="${src}" alt="QR Code" style="width:240px;height:240px;" class="rounded-lg">`;
    }
    return true;
  }
  if (qr.code || qr.qrString) {
    const code = qr.code || qr.qrString;
    if (code.startsWith('data:image')) {
      if (qrBox.querySelector('img')?.src !== code) {
        qrBox.innerHTML = `<img src="${code}" alt="QR Code" style="width:240px;height:240px;" class="rounded-lg">`;
      }
      return true;
    }
    qrBox.innerHTML = '';
    if (typeof QRCode !== 'undefined') {
      new QRCode(qrBox, { text: code, width: 240, height: 240, correctLevel: QRCode.CorrectLevel.M });
    } else {
      qrBox.innerHTML = `<div class="p-3 text-xs break-all bg-gray-100 rounded">${code}</div>`;
    }
    return true;
  }
  return false;
}

// ── Exibir código de pareamento formatado ─────────────────────
function showPairingCode(code) {
  const clean = String(code).replace(/[^A-Za-z0-9]/g, '').toUpperCase();

  if (clean.length < 4 || clean.length > 20) {
    console.error('[pairingCode] Valor inválido ignorado:', code, '→ limpo:', clean);
    setLiveStatus('err', 'Código de pareamento inválido. Veja o console.');
    return;
  }

  // Remove skeleton if present
  const skel = qrBox.querySelector('#qrLoadingSkeleton');
  if (skel) skel.remove();

  const groups = clean.match(/.{1,4}/g) || [clean];
  pairingSegments.innerHTML = groups.map(g => `<div class="pairing-segment">${g}</div>`).join('');
  pairingDisplay.classList.remove('hidden');
  qrBox.innerHTML = '';
}

// ── Instruções por modo ───────────────────────────────────────
function setInstructions(mode) {
  if (mode === 'qr') {
    connectInstructions.innerHTML = `
      <h3 class="font-medium text-gray-900 dark:text-gray-100 mb-2">Como conectar via QR Code</h3>
      <ol class="list-decimal pl-5 space-y-1.5 text-sm">
        <li>Abra o <strong>WhatsApp</strong> ou <strong>WhatsApp Business</strong> no celular.</li>
        <li>Vá em <strong>Dispositivos Conectados</strong> → <strong>Conectar um dispositivo</strong>.</li>
        <li>Aponte a câmera para o QR Code ao lado.</li>
        <li>Aguarde a confirmação automática.</li>
      </ol>`;
  } else {
    connectInstructions.innerHTML = `
      <h3 class="font-medium text-gray-900 dark:text-gray-100 mb-2">Como conectar via Código de Pareamento</h3>
      <ol class="list-decimal pl-5 space-y-1.5 text-sm">
        <li>Abra o <strong>WhatsApp</strong> ou <strong>WhatsApp Business</strong> no celular.</li>
        <li>Vá em <strong>Dispositivos Conectados</strong> → <strong>Conectar um dispositivo</strong>.</li>
        <li>Toque em <strong>"Usar número de telefone"</strong>.</li>
        <li>Digite o código exibido ao lado.</li>
        <li>Aguarde a confirmação automática.</li>
      </ol>`;
  }
}

// ── Iniciar conexão via QR ────────────────────────────────────
async function startQRConnect() {
  currentMode = 'qr';
  goToStep('qr');
  qrModalSkeleton.classList.remove('hidden');

  // Animate progress in modal
  const fill = document.getElementById('qrModalProgressFill');
  const label = document.getElementById('qrModalProgressLabel');
  if (fill) { fill.style.width = '0%'; }
  if (label) label.textContent = 'Conectando ao servidor…';
  setTimeout(() => { if (fill) fill.style.width = '30%'; }, 150);
  setTimeout(() => { if (fill) fill.style.width = '55%'; if (label) label.textContent = 'Gerando QR Code…'; }, 600);
  setTimeout(() => { if (fill) fill.style.width = '80%'; if (label) label.textContent = 'Quase pronto…'; }, 1400);

  const d = await fetchJSON(`${API}?action=connect`, { method: 'POST', body: new FormData() });

  // Complete progress before closing
  if (fill) fill.style.width = '100%';
  if (label) label.textContent = 'QR Code pronto!';
  await delay(300);

  closeModal();
  prepareQRWrap('qr');

  if (d.ok && d.connected) { onConnected(); return; }
  if (d.ok && d.qr) {
    showQRImage(d.qr);
    setLiveStatus('loading', 'Aguardando leitura do QR Code…');
    startRealTimePolling();
    return;
  }

  // pending – faz poll até obter QR
  setLiveStatus('loading', 'Gerando QR Code…');
  const t0 = Date.now();
  while (Date.now() - t0 < 30000) {
    const p = await fetchJSON(`${API}?action=qrpoll`);
    if (p.ok && p.connected) { onConnected(); return; }
    if (p.ok && p.qr) {
      showQRImage(p.qr);
      setLiveStatus('loading', 'Aguardando leitura do QR Code…');
      startRealTimePolling();
      return;
    }
    await delay(2000);
  }
  setLiveStatus('err', 'Tempo esgotado. Tente novamente.');
}

// ── Iniciar conexão via Pareamento ────────────────────────────
async function startPairingConnect(phone) {
  currentMode = 'pairing';
  const fd = new FormData();
  fd.append('phone', phone);

  const d = await fetchJSON(`${API}?action=connect`, { method: 'POST', body: fd });

  console.log('[connect/pairing] Resposta completa da API:', JSON.stringify(d, null, 2));

  closeModal();
  prepareQRWrap('pairing');

  if (d.ok && d.connected) { onConnected(); return; }
  if (d.ok && d.qr) {
    if (d.qr.pairingCode) {
      showPairingCode(d.qr.pairingCode);
    } else if (d.qr.code) {
      showPairingCode(d.qr.code);
    }
    setLiveStatus('loading', 'Aguardando digitação do código…');
    startRealTimePolling();
    return;
  }

  // pending
  setLiveStatus('loading', 'Gerando código de pareamento…');
  const t0 = Date.now();
  while (Date.now() - t0 < 30000) {
    const p = await fetchJSON(`${API}?action=qrpoll`);
    if (p.ok && p.connected) { onConnected(); return; }
    if (p.ok && p.qr && (p.qr.pairingCode || p.qr.code)) {
      showPairingCode(p.qr.pairingCode || p.qr.code);
      setLiveStatus('loading', 'Aguardando digitação do código…');
      startRealTimePolling();
      return;
    }
    await delay(2000);
  }
  setLiveStatus('err', 'Tempo esgotado. Tente novamente.');
}

function prepareQRWrap(mode) {
  qrWrap.classList.remove('hidden');
  qrBox.innerHTML = '';
  pairingDisplay.classList.add('hidden');
  pairingSegments.innerHTML = '';
  liveStatus.innerHTML = `<span class="spin"></span><span id="liveStatusText">Aguardando…</span>`;
  setInstructions(mode);

  if (mode === 'qr') {
    // Show qrBox with skeleton loader
    qrBox.classList.remove('hidden');
    qrBox.style.minWidth = '244px';
    qrBox.style.minHeight = '244px';
    const skel = document.createElement('div');
    skel.id = 'qrLoadingSkeleton';
    skel.className = 'flex flex-col items-center justify-center';
    skel.style.cssText = 'width:240px;height:240px;';
    skel.innerHTML = '<div class="qr-skeleton"></div>';
    qrBox.appendChild(skel);
  } else {
    // Pairing mode: hide the empty white QR box completely
    qrBox.classList.add('hidden');
    qrBox.style.minWidth = '';
    qrBox.style.minHeight = '';
  }
}

function delay(ms) { return new Promise(r => setTimeout(r, ms)); }

// ── Eventos do modal ──────────────────────────────────────────
btnQR?.addEventListener('click', openModal);
modalClose?.addEventListener('click', closeModal);
connectModal?.addEventListener('click', e => { if (e.target === connectModal) closeModal(); });

chooseQR?.addEventListener('click', startQRConnect);

choosePairing?.addEventListener('click', () => goToStep('pairing'));

btnBackMethod?.addEventListener('click', () => goToStep('choose'));
btnBackToChoose?.addEventListener('click', () => goToStep('choose'));

btnSendPairing?.addEventListener('click', async () => {
  const phone = phoneInput.value.replace(/\D/g,'');
  if (phone.length < 10) {
    pairingError.textContent = 'Digite um número válido com DDD e código do país (ex: 5511999999999)';
    pairingError.classList.remove('hidden');
    return;
  }
  pairingError.classList.add('hidden');
  btnSendPairing.disabled = true;
  btnSendPairing.innerHTML = `<span class="spin"></span> Gerando…`;
  await startPairingConnect(phone);
  btnSendPairing.disabled = false;
  btnSendPairing.innerHTML = `Gerar Código <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"/></svg>`;
});

phoneInput?.addEventListener('keydown', e => { if (e.key === 'Enter') btnSendPairing?.click(); });

// Fechar modais com Escape
document.addEventListener('keydown', e => {
  if (e.key === 'Escape') {
    if (connectModal.classList.contains('open')) closeModal();
    if (deletingModal.classList.contains('open') && !deleteStepConfirm.classList.contains('hidden')) closeDeleteModal();
  }
});

// ── Criar instância (com modal de loading) ────────────────────
btnCreate?.addEventListener('click', async () => {
  btnCreate.disabled = true;
  openCreatingModal();

  const fd = new FormData();
  const d = await fetchJSON(`${API}?action=create`, { method: 'POST', body: fd });

  if (d.ok) {
    completeCreatingModal(true);
    // Wait for modal success animation, then update UI
    await delay(1300);
    cardName.textContent = d.instance;
    createBlock.classList.add('hidden');
    cardBlock.classList.remove('hidden');
    setBadge(statusBd, 'ok', 'Instância criada!');
    await refreshStatus();
    if (HAS_ADVANCED) { await refreshWebhookStatus(); await refreshReplyAllStatus(); }
  } else if (d.status === 409) {
    completeCreatingModal(true);
    await delay(1300);
    setBadge(statusBd, 'warn', 'Você já possui uma instância.');
    await boot();
  } else {
    completeCreatingModal(false, d.error || 'Erro ao criar');
  }

  btnCreate.disabled = false;
});

// ── Excluir instância (modal de confirmação) ─────────────────
btnDelete?.addEventListener('click', () => openDeleteModal());

deleteCancel?.addEventListener('click', () => closeDeleteModal());
deletingModal?.addEventListener('click', e => { if (e.target === deletingModal && !deleteStepLoading.classList.contains('hidden') === false) closeDeleteModal(); });

deleteConfirmBtn?.addEventListener('click', async () => {
  stopPolling();
  startDeleteLoading();

  const d = await fetchJSON(`${API}?action=delete`, { method: 'POST' });

  if (d.ok) {
    completeDeleteModal(true);
    await delay(1300);
    createBlock.classList.remove('hidden');
    cardBlock.classList.add('hidden');
    qrWrap.classList.add('hidden');
    qrBox.innerHTML = '';
    setBadge(statusBd, 'warn', 'Instância removida.');
    await boot();
  } else {
    completeDeleteModal(false, d.error || 'Falha ao excluir');
  }
});

// ── Toggles de webhook e responder todos ─────────────────────
toggleWebhook?.addEventListener('change', async (e) => {
  const fd = new FormData();
  fd.append('enabled', e.target.checked ? '1' : '0');
  setBadge(webhookBadge, 'loading', 'Aplicando...');
  const r = await fetchJSON(`${API}?action=webhook_toggle`, { method: 'POST', body: fd });
  if (r.ok) await refreshWebhookStatus();
  else { setBadge(webhookBadge, 'err', r.error || 'Falha'); e.target.checked = !e.target.checked; }
});

toggleReplyAll?.addEventListener('change', async (e) => {
  const fd = new FormData();
  fd.append('enabled', e.target.checked ? '1' : '0');
  setBadge(replyAllBadge, 'loading', 'Aplicando...');
  const r = await fetchJSON(`${API}?action=responder_todos_toggle`, { method: 'POST', body: fd });
  if (r.ok) await refreshReplyAllStatus();
  else { setBadge(replyAllBadge, 'err', r.error || 'Falha'); e.target.checked = !e.target.checked; }
});

// ── Refresh helpers ───────────────────────────────────────────
async function refreshStatus() {
  const st = await fetchJSON(`${API}?action=status`);
  if (st.ok) {
    const connected = st.connected;
    setBadge(badgeState, connected ? 'ok' : 'warn', connected ? 'Conectado' : 'Desconectado');
    if (btnQR) btnQR.style.display = connected ? 'none' : '';
    if (connected) {
      qrWrap?.classList.add('hidden');
      statusBd?.classList.add('hidden');
    }
  } else {
    setBadge(badgeState, 'err', 'Erro ao verificar');
  }
}

async function refreshWebhookStatus() {
  if (!HAS_ADVANCED || !webhookBadge) return;
  const r = await fetchJSON(`${API}?action=webhook_status`);
  if (!r.ok) return;
  const meta = r.meta || {};
  if (toggleWebhook) toggleWebhook.checked = !!meta.enabled;
  setBadge(webhookBadge, meta.enabled ? 'ok' : 'warn', meta.enabled ? 'Agente ligado' : 'Agente desligado');
  if (webhookInfo) webhookInfo.textContent = meta.url ? 'Desative para apenas disparos, sem agente de IA.' : '—';
}

async function refreshReplyAllStatus() {
  if (!HAS_ADVANCED || !replyAllBadge) return;
  const r = await fetchJSON(`${API}?action=responder_todos_status`);
  if (!r.ok) return;
  const on = !!r.responder_todos;
  if (toggleReplyAll) toggleReplyAll.checked = on;
  setBadge(replyAllBadge, on ? 'ok' : 'warn', on ? 'Responder Todos: ligado' : 'Responder Todos: desligado');
}

// ── Boot ──────────────────────────────────────────────────────
async function boot() {
  const me = await fetchJSON(`${API}?action=me`);
  if (!me.ok) { setBadge(statusBd, 'err', `Falha ao carregar`); return; }

  if (me.user?.instance_name) {
    createBlock.classList.add('hidden');
    cardBlock.classList.remove('hidden');
    cardName.textContent = me.user.instance_name;
    await refreshStatus();
    if (HAS_ADVANCED) { await refreshWebhookStatus(); await refreshReplyAllStatus(); }
  } else {
    createBlock.classList.remove('hidden');
    cardBlock.classList.add('hidden');
  }
}

window.addEventListener('beforeunload', stopPolling);
boot();
</script>