<?php
// views/pages/leads.php
require_once __DIR__ . '/../../app/csrf.php';
require_once __DIR__ . '/components/tutorial.php';

$csrf = htmlspecialchars(csrf_token(), ENT_QUOTES, 'UTF-8');
?>
<style>
  /* ── Pastas compactas ── */
  .folder-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 14px; border-radius: 9999px;
    font-size: 0.8125rem; font-weight: 500;
    border: 1.5px solid transparent;
    cursor: pointer; user-select: none;
    transition: all .15s;
    white-space: nowrap;
  }
  .folder-chip:hover { border-color: var(--chip-hover, #818cf8); }
  .folder-chip.active {
    border-color: #6366f1;
    background: rgba(99,102,241,.08);
    color: #6366f1;
  }
  .dark .folder-chip.active {
    background: rgba(99,102,241,.18);
    color: #a5b4fc;
  }
  .folder-chip .chip-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 20px; height: 20px; padding: 0 5px;
    border-radius: 9999px;
    font-size: 0.6875rem; font-weight: 600;
    background: rgba(0,0,0,.06);
  }
  .dark .folder-chip .chip-count { background: rgba(255,255,255,.08); }
  .folder-chip.active .chip-count {
    background: rgba(99,102,241,.15);
  }

  /* ── Chip draggable ── */
  .folder-chip[draggable="true"] { cursor: grab; }
  .folder-chip.dragging { opacity: .5; transform: scale(.95); }
  .folder-chip.drag-over { border-color: #6366f1 !important; box-shadow: 0 0 0 2px rgba(99,102,241,.25); }

  /* ── Banner "selecionar todos" ── */
  .select-all-banner {
    display: flex; align-items: center; justify-content: center;
    gap: 8px; padding: 8px 16px;
    background: #eef2ff; border: 1px solid #c7d2fe;
    border-radius: 8px; font-size: .8125rem; color: #4338ca;
  }
  .dark .select-all-banner {
    background: rgba(99,102,241,.12);
    border-color: rgba(99,102,241,.25);
    color: #a5b4fc;
  }
  .select-all-banner button {
    font-weight: 600; text-decoration: underline;
    cursor: pointer; background: none; border: none; color: inherit;
  }

  /* ── Toolbar flutuante ── */
  .bulk-toolbar {
    position: sticky; bottom: 16px; z-index: 30;
    display: flex; align-items: center; justify-content: center; gap: 8px;
    margin: 12px auto 0; padding: 10px 20px;
    max-width: fit-content;
    background: #1e1b4b; color: #e0e7ff;
    border-radius: 14px; box-shadow: 0 8px 30px rgba(0,0,0,.25);
    font-size: .8125rem;
    animation: slideUp .2s ease;
  }
  @keyframes slideUp { from { transform: translateY(20px); opacity: 0; } }
  .bulk-toolbar button {
    padding: 6px 14px; border-radius: 8px; font-size: .8125rem; font-weight: 500;
    border: none; cursor: pointer; transition: background .15s;
  }
  .bulk-toolbar .bt-move   { background: #3b82f6; color: #fff; }
  .bulk-toolbar .bt-move:hover { background: #2563eb; }
  .bulk-toolbar .bt-export { background: #10b981; color: #fff; }
  .bulk-toolbar .bt-export:hover { background: #059669; }
  .bulk-toolbar .bt-delete { background: #ef4444; color: #fff; }
  .bulk-toolbar .bt-delete:hover { background: #dc2626; }
  .bulk-toolbar .bt-cancel { background: transparent; color: #c7d2fe; border: 1px solid rgba(255,255,255,.15); }
  .bulk-toolbar .bt-cancel:hover { background: rgba(255,255,255,.08); }

  /* ── Modal de progresso ── */
  .progress-overlay {
    position: fixed; inset: 0; z-index: 80;
    align-items: center; justify-content: center;
    background: rgba(0,0,0,.5); backdrop-filter: blur(4px);
  }
  .progress-overlay:not(.hidden) {
    display: flex;
  }
  .progress-card {
    width: 100%; max-width: 400px; margin: 16px;
    padding: 28px 32px; border-radius: 16px;
    background: #fff; box-shadow: 0 20px 60px rgba(0,0,0,.2);
    text-align: center;
  }
  .dark .progress-card { background: #111827; }
  .progress-card .pc-icon {
    width: 48px; height: 48px; margin: 0 auto 16px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
  }
  .progress-card .pc-icon.deleting { background: #fef2f2; color: #ef4444; }
  .progress-card .pc-icon.moving   { background: #eff6ff; color: #3b82f6; }
  .progress-card .pc-icon.success  { background: #ecfdf5; color: #10b981; }
  .dark .progress-card .pc-icon.deleting { background: rgba(239,68,68,.12); }
  .dark .progress-card .pc-icon.moving   { background: rgba(59,130,246,.12); }
  .dark .progress-card .pc-icon.success  { background: rgba(16,185,129,.12); }
  .progress-card h3 { font-size: 1rem; font-weight: 600; margin-bottom: 4px; }
  .progress-card .pc-sub { font-size: .8125rem; color: #6b7280; margin-bottom: 16px; }
  .progress-bar-track {
    width: 100%; height: 8px; border-radius: 999px;
    background: #f3f4f6; overflow: hidden;
  }
  .dark .progress-bar-track { background: #1f2937; }
  .progress-bar-fill {
    height: 100%; border-radius: 999px;
    transition: width .3s ease;
  }
  .progress-bar-fill.deleting { background: linear-gradient(90deg, #ef4444, #f87171); }
  .progress-bar-fill.moving   { background: linear-gradient(90deg, #3b82f6, #60a5fa); }
  .progress-bar-fill.success  { background: linear-gradient(90deg, #10b981, #34d399); }
  .progress-card .pc-percent {
    font-size: .75rem; font-weight: 600; color: #6b7280;
    margin-top: 8px;
  }
  .progress-card .pc-done-btn {
    margin-top: 16px; padding: 8px 24px;
    border-radius: 8px; font-size: .8125rem; font-weight: 500;
    background: #6366f1; color: #fff; border: none; cursor: pointer;
    display: none;
  }
  .progress-card .pc-done-btn:hover { background: #4f46e5; }

  @keyframes pulseIcon {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.08); }
  }
  .progress-card .pc-icon.animating { animation: pulseIcon .8s ease infinite; }

  /* ── Tabela melhorada ── */
  #leadsTable th { font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; color: #6b7280; }
  #leadsTable td { padding-top: .625rem; padding-bottom: .625rem; }
  #leadsTable tr.row-selected { background: rgba(99,102,241,.06); }
  .dark #leadsTable tr.row-selected { background: rgba(99,102,241,.12); }

  /* ── Destaque de busca ── */
  #leadsTable mark.search-hl {
    background: #fde68a; color: inherit;
    border-radius: 3px; padding: 0 1px;
  }
  .dark #leadsTable mark.search-hl {
    background: rgba(250,204,21,.35); color: inherit;
  }

  /* ── Botão editar na linha ── */
  .lead-edit-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; border-radius: 6px;
    color: #9ca3af; cursor: pointer;
    transition: background .15s, color .15s;
  }
  .lead-edit-btn:hover { background: rgba(99,102,241,.1); color: #6366f1; }
  .dark .lead-edit-btn:hover { background: rgba(99,102,241,.18); color: #a5b4fc; }

  /* ── "criado há X" ── */
  .lead-created { cursor: default; }

  /* ── Contador semanal no header ── */
  .week-badge {
    display: inline-flex; align-items: center; gap: 4px;
    margin-left: 6px; padding: 2px 8px;
    border-radius: 9999px; font-size: .6875rem; font-weight: 600;
    background: #ecfdf5; color: #059669;
  }
  .dark .week-badge { background: rgba(16,185,129,.15); color: #34d399; }
</style>

<div class="mb-4 sm:mb-6">
  <?= tutorial_component([
    'id'     => 'leads',
    'title'  => 'Leads',
    'button' => 'Ver tutorial Leads',
    'video'  => 'https://youtu.be/Po-HZixAhP4',
    'spotlight' => true
  ]); ?>
</div>

<div class="rounded-xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 p-4 sm:p-6">

  <!-- ═══ HEADER ═══ -->
  <div class="flex items-center justify-between gap-3 flex-wrap mb-4">
    <div>
      <h2 class="text-xl font-semibold">Leads</h2>
      <p class="text-sm text-gray-500 dark:text-gray-400">Organize e gerencie seus leads por pastas.</p>
    </div>
    <div class="flex items-center gap-2 flex-wrap">
      <button id="btnToggleImport"
        class="inline-flex items-center gap-1.5 rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white px-3.5 py-2 text-sm font-medium transition">
        <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 16V4m0 0L7 9m5-5 5 5M4 20h16"/></svg>
        Importar
      </button>
      <button id="btnExport"
        class="inline-flex items-center gap-1.5 rounded-lg border border-gray-300 dark:border-gray-700 px-3.5 py-2 text-sm font-medium hover:bg-gray-50 dark:hover:bg-gray-800 transition">
        <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 8v12m0 0 5-5m-5 5-5-5M20 4H4"/></svg>
        Exportar CSV
      </button>
    </div>
  </div>

  <!-- ═══ PASTAS (chips compactas) ═══ -->
  <div class="mb-4">
    <div class="flex items-center justify-between mb-2">
      <span class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">Pastas</span>
      <div class="flex items-center gap-1.5">
        <button id="btnNewFolder" class="inline-flex items-center gap-1 rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white px-3 py-1.5 text-xs font-medium transition">
          <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M12 5v14m-7-7h14"/></svg>
          Nova pasta
        </button>
        <button id="btnRenameFolder" class="rounded-lg border border-gray-300 dark:border-gray-700 px-3 py-1.5 text-xs font-medium hover:bg-gray-50 dark:hover:bg-gray-800 transition disabled:opacity-40 disabled:pointer-events-none" disabled>Renomear</button>
        <button id="btnDeleteFolder" class="rounded-lg border border-gray-300 dark:border-gray-700 px-3 py-1.5 text-xs font-medium text-rose-600 dark:text-rose-400 hover:bg-rose-50 dark:hover:bg-rose-950/30 transition disabled:opacity-40 disabled:pointer-events-none" disabled>Excluir</button>
      </div>
    </div>
    <div id="foldersBar" class="flex flex-wrap gap-2 items-center"></div>
  </div>

  <!-- ═══ IMPORTAÇÃO (colapsável) ═══ -->
  <div id="importWrap" class="mb-4 hidden rounded-xl border border-gray-200 dark:border-gray-800 p-4 bg-gray-50 dark:bg-gray-950">
    <div class="flex items-center justify-between mb-3">
      <h3 class="font-medium text-sm">Importar leads</h3>
      <button id="btnCloseImport" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 text-lg leading-none">&times;</button>
    </div>
    <form id="formImport" class="grid gap-3">
      <input type="hidden" name="csrf" value="<?= $csrf ?>">
      <div class="grid md:grid-cols-2 gap-3">
        <div>
          <label class="block text-xs mb-1 font-medium">Arquivo CSV</label>
          <input type="file" name="file" accept=".csv" class="w-full rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2 text-sm">
          <p class="text-xs text-gray-400 mt-1">Cabeçalho opcional: <code class="bg-gray-200 dark:bg-gray-800 px-1 rounded">company,phone,status</code></p>
        </div>
        <div>
          <label class="block text-xs mb-1 font-medium">Ou cole aqui</label>
          <textarea name="csv" rows="4"
            class="w-full rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2 text-sm"
            placeholder="Empresa X,11999990000&#10;Empresa Y,11988887777"></textarea>
        </div>
      </div>
      <div class="flex items-end gap-3">
        <div class="w-48">
          <label class="block text-xs mb-1 font-medium">Pasta destino</label>
          <select name="folder_id" id="importFolder" class="w-full rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2 text-sm">
            <option value="">Sem pasta</option>
          </select>
        </div>
        <button class="rounded-lg bg-emerald-600 hover:bg-emerald-700 text-white px-4 py-2 text-sm font-medium" type="submit">Importar</button>
        <span id="importMsg" class="text-xs"></span>
      </div>
    </form>
  </div>

  <!-- ═══ CADASTRO RÁPIDO ═══ -->
  <div class="mb-4 rounded-xl border border-gray-200 dark:border-gray-800 p-4 bg-gray-50 dark:bg-gray-950">
    <h3 class="font-medium text-sm mb-3">Cadastrar lead</h3>
    <form id="formCreate" class="flex flex-wrap items-end gap-3">
      <input type="hidden" name="csrf" value="<?= $csrf ?>">
      <div class="flex-1 min-w-[160px]">
        <label class="block text-xs mb-1 font-medium">Empresa</label>
        <input name="company" class="w-full rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2 text-sm" placeholder="Empresa ABC" required>
      </div>
      <div class="flex-1 min-w-[140px]">
        <label class="block text-xs mb-1 font-medium">Telefone</label>
        <input name="phone" class="w-full rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2 text-sm" placeholder="11999999999" required>
      </div>
      <div class="w-44">
        <label class="block text-xs mb-1 font-medium">Pasta</label>
        <select name="folder_id" id="createFolder" class="w-full rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2 text-sm">
          <option value="">Sem pasta</option>
        </select>
      </div>
      <button class="rounded-lg bg-emerald-600 hover:bg-emerald-700 text-white px-5 py-2 text-sm font-medium" type="submit">Salvar</button>
      <span id="createMsg" class="text-xs"></span>
    </form>
  </div>

  <!-- ═══ BUSCA ═══ -->
  <div class="mb-3 flex items-center gap-2">
    <div class="relative flex-1">
      <svg class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>
      <input id="searchInput" placeholder="Buscar por nome, número ou últimos 4 dígitos..."
             class="w-full rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 pl-9 pr-20 py-2 text-sm">
      <button id="searchClear"
              class="absolute right-2 top-1/2 -translate-y-1/2 text-xs px-2 py-0.5 rounded border border-gray-300 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 hidden">
        Limpar
      </button>
    </div>
    <span id="searchInfo" class="text-xs text-gray-500 whitespace-nowrap"></span>
  </div>

  <!-- ═══ BANNER "SELECIONAR TODOS" ═══ -->
  <div id="selectAllBanner" class="mb-3 hidden"></div>

  <!-- ═══ TABELA ═══ -->
  <div class="overflow-x-auto">
    <table id="leadsTable" class="min-w-full text-sm">
      <thead>
        <tr class="border-b border-gray-200 dark:border-gray-800">
          <th class="py-2 pr-3 w-10 text-left"><input id="checkAll" type="checkbox" class="size-4 rounded"></th>
          <th class="py-2 pr-3 text-left">Empresa</th>
          <th class="py-2 pr-3 text-left">Telefone</th>
          <th class="py-2 pr-3 text-left">Criado</th>
          <th class="py-2 pr-3 text-left w-44">Pasta</th>
          <th class="py-2 pr-3 text-left w-12"></th>
        </tr>
      </thead>
      <tbody id="leadRows" class="text-gray-800 dark:text-gray-100"></tbody>
    </table>
    <p id="emptyHint" class="mt-6 text-center text-sm text-gray-400 dark:text-gray-500 hidden">Nenhum lead encontrado.</p>
  </div>

  <!-- ═══ PAGINAÇÃO ═══ -->
  <div class="mt-4 flex items-center justify-between gap-3 text-sm">
    <div class="text-xs text-gray-500 dark:text-gray-400">
      Página <span id="pageInfo">1</span> &middot; <span id="totalInfo">0 leads</span>
    </div>
    <div class="flex items-center gap-2">
      <select id="pageSize" class="rounded-md border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-2 py-1 text-sm">
        <option value="20">20</option>
        <option value="50">50</option>
        <option value="100">100</option>
      </select>
      <span class="text-xs text-gray-400">por página</span>
      <button id="btnPrev" class="rounded-lg border border-gray-300 dark:border-gray-700 px-3 py-1.5 text-sm disabled:opacity-40 transition" disabled>&laquo; Anterior</button>
      <button id="btnNext" class="rounded-lg border border-gray-300 dark:border-gray-700 px-3 py-1.5 text-sm disabled:opacity-40 transition" disabled>Próxima &raquo;</button>
    </div>
  </div>
</div>

<!-- ═══ BULK TOOLBAR (aparece quando tem seleção) ═══ -->
<div id="bulkToolbar" class="bulk-toolbar hidden">
  <span id="bulkCount">0 selecionados</span>
  <button class="bt-move"   id="btMove">Mover</button>
  <button class="bt-export" id="btExport">Exportar</button>
  <button class="bt-delete" id="btDelete">Excluir</button>
  <button class="bt-cancel" id="btCancel">Cancelar</button>
</div>

<!-- ═══ MODAL DE PROGRESSO ═══ -->
<div id="progressModal" class="progress-overlay hidden">
  <div class="progress-card">
    <div id="pcIcon" class="pc-icon deleting animating">
      <svg id="pcIconSvg" class="w-6 h-6" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
        <path id="pcIconPath" 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>
    <h3 id="pcTitle">Excluindo leads...</h3>
    <div id="pcSub" class="pc-sub">Processando 0 de 0</div>
    <div class="progress-bar-track">
      <div id="pcBar" class="progress-bar-fill deleting" style="width:0%"></div>
    </div>
    <div id="pcPercent" class="pc-percent">0%</div>
    <button id="pcDoneBtn" class="pc-done-btn">Fechar</button>
  </div>
</div>

<!-- ═══ MODAL MOVER ═══ -->
<div id="moveModal" class="fixed inset-0 z-[60] hidden">
  <div class="absolute inset-0 bg-black/50 backdrop-blur-sm"></div>
  <div class="absolute inset-0 flex items-center justify-center p-4">
    <div class="w-full max-w-lg rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 shadow-xl">
      <div class="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-800">
        <h3 class="text-lg font-semibold">Mover para pasta</h3>
        <button id="mmClose" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 text-lg leading-none">&times;</button>
      </div>
      <div class="p-4">
        <div class="mb-3 flex items-center justify-between">
          <span class="text-sm text-gray-500" id="mmCountLabel">0 leads selecionados</span>
          <button id="mmNewFolder" class="text-xs text-indigo-600 dark:text-indigo-400 hover:underline font-medium">+ Nova pasta</button>
        </div>
        <div id="mmGrid" class="flex flex-wrap gap-2"></div>
      </div>
      <div class="p-4 border-t border-gray-200 dark:border-gray-800 flex justify-end">
        <button id="mmCancel" class="rounded-lg border border-gray-300 dark:border-gray-700 px-4 py-1.5 text-sm">Cancelar</button>
      </div>
    </div>
  </div>
</div>

<!-- ═══ MODAL NOVA PASTA ═══ -->
<div id="newFolderModal" class="fixed inset-0 z-[70] hidden">
  <div class="absolute inset-0 bg-black/50 backdrop-blur-sm"></div>
  <div class="absolute inset-0 flex items-center justify-center p-4">
    <div class="w-full max-w-md rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 shadow-xl">
      <div class="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-800">
        <h3 class="text-lg font-semibold">Criar pasta</h3>
        <button id="nfClose" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 text-lg leading-none">&times;</button>
      </div>
      <form id="nfForm" class="p-4 grid gap-3">
        <label class="text-sm font-medium">
          Nome da pasta
          <input id="nfInput" class="mt-1 w-full rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2" placeholder="Ex.: Leads Odontologia" required>
        </label>
        <div id="nfError" class="text-xs text-rose-600 hidden"></div>
        <div class="flex items-center justify-end gap-2 pt-1">
          <button type="button" id="nfCancel" class="rounded-lg border border-gray-300 dark:border-gray-700 px-4 py-1.5 text-sm">Cancelar</button>
          <button type="submit" class="rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white px-5 py-1.5 text-sm font-medium">Criar</button>
        </div>
      </form>
    </div>
  </div>
</div>

<!-- ═══ MODAL EDITAR LEAD ═══ -->
<div id="editModal" class="fixed inset-0 z-[70] hidden">
  <div class="absolute inset-0 bg-black/50 backdrop-blur-sm"></div>
  <div class="absolute inset-0 flex items-center justify-center p-4">
    <div class="w-full max-w-md rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 shadow-xl">
      <div class="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-800">
        <h3 class="text-lg font-semibold">Editar lead</h3>
        <button id="edClose" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 text-lg leading-none">&times;</button>
      </div>
      <form id="edForm" class="p-4 grid gap-3">
        <input type="hidden" id="edId">
        <label class="text-sm font-medium">
          Empresa
          <input id="edCompany" class="mt-1 w-full rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2" placeholder="Empresa ABC">
        </label>
        <label class="text-sm font-medium">
          Telefone
          <input id="edPhone" class="mt-1 w-full rounded-lg border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2" placeholder="11999999999" required>
        </label>
        <div id="edError" class="text-xs text-rose-600 hidden"></div>
        <div class="flex items-center justify-end gap-2 pt-1">
          <button type="button" id="edCancel" class="rounded-lg border border-gray-300 dark:border-gray-700 px-4 py-1.5 text-sm">Cancelar</button>
          <button type="submit" class="rounded-lg bg-indigo-600 hover:bg-indigo-700 text-white px-5 py-1.5 text-sm font-medium">Salvar</button>
        </div>
      </form>
    </div>
  </div>
</div>

<script>
const API = 'api/leads.php';

/* ── Refs ── */
const formCreate  = document.getElementById('formCreate');
const createMsg   = document.getElementById('createMsg');
const leadRows    = document.getElementById('leadRows');
const emptyHint   = document.getElementById('emptyHint');
const checkAll    = document.getElementById('checkAll');
const pageInfo    = document.getElementById('pageInfo');
const totalInfo   = document.getElementById('totalInfo');
const btnPrev     = document.getElementById('btnPrev');
const btnNext     = document.getElementById('btnNext');
const pageSize    = document.getElementById('pageSize');

const btnToggleImport = document.getElementById('btnToggleImport');
const btnCloseImport  = document.getElementById('btnCloseImport');
const importWrap  = document.getElementById('importWrap');
const formImport  = document.getElementById('formImport');
const importMsg   = document.getElementById('importMsg');

const btnNewFolder    = document.getElementById('btnNewFolder');
const btnRenameFolder = document.getElementById('btnRenameFolder');
const btnDeleteFolder = document.getElementById('btnDeleteFolder');

const createFolderSel = document.getElementById('createFolder');
const importFolderSel = document.getElementById('importFolder');
const foldersBar      = document.getElementById('foldersBar');

const searchInput = document.getElementById('searchInput');
const searchClear = document.getElementById('searchClear');
const searchInfo  = document.getElementById('searchInfo');

const selectAllBanner = document.getElementById('selectAllBanner');

/* Bulk toolbar */
const bulkToolbar = document.getElementById('bulkToolbar');
const bulkCount   = document.getElementById('bulkCount');
const btMove      = document.getElementById('btMove');
const btExport    = document.getElementById('btExport');
const btDelete    = document.getElementById('btDelete');
const btCancel    = document.getElementById('btCancel');
const btnExport   = document.getElementById('btnExport');

/* Progress modal */
const progressModal = document.getElementById('progressModal');
const pcIcon     = document.getElementById('pcIcon');
const pcIconPath = document.getElementById('pcIconPath');
const pcTitle    = document.getElementById('pcTitle');
const pcSub      = document.getElementById('pcSub');
const pcBar      = document.getElementById('pcBar');
const pcPercent  = document.getElementById('pcPercent');
const pcDoneBtn  = document.getElementById('pcDoneBtn');

/* Edit modal */
const editModal  = document.getElementById('editModal');
const edForm     = document.getElementById('edForm');
const edId       = document.getElementById('edId');
const edCompany  = document.getElementById('edCompany');
const edPhone    = document.getElementById('edPhone');
const edError    = document.getElementById('edError');
const edClose    = document.getElementById('edClose');
const edCancel   = document.getElementById('edCancel');

const ICON_PATHS = {
  delete: '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',
  move:   'M3 7c0-1.1.9-2 2-2h3.93a2 2 0 011.66.88l.82 1.24a2 2 0 001.66.88H19a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2V7Z',
  check:  'M5 13l4 4L19 7',
};

function showProgress(type, title, total) {
  const cls = type === 'delete' ? 'deleting' : 'moving';
  pcIcon.className = `pc-icon ${cls} animating`;
  pcIconPath.setAttribute('d', ICON_PATHS[type]);
  pcBar.className = `progress-bar-fill ${cls}`;
  pcBar.style.width = '0%';
  pcTitle.textContent = title;
  pcSub.textContent = `Processando 0 de ${total}`;
  pcPercent.textContent = '0%';
  pcDoneBtn.style.display = 'none';
  progressModal.classList.remove('hidden');
}

function updateProgress(processed, total) {
  const pct = Math.min(100, Math.round((processed / total) * 100));
  pcBar.style.width = pct + '%';
  pcSub.textContent = `Processando ${processed} de ${total}`;
  pcPercent.textContent = pct + '%';
}

function finishProgress(type, message) {
  pcIcon.className = 'pc-icon success';
  pcIcon.classList.remove('animating');
  pcIconPath.setAttribute('d', ICON_PATHS.check);
  pcBar.className = 'progress-bar-fill success';
  pcBar.style.width = '100%';
  pcTitle.textContent = message;
  pcSub.textContent = '';
  pcPercent.textContent = '100%';
  pcDoneBtn.style.display = 'inline-block';
}

pcDoneBtn.addEventListener('click', () => progressModal.classList.add('hidden'));

/* Modais */
const moveModal = document.getElementById('moveModal');
const mmGrid    = document.getElementById('mmGrid');
const mmClose   = document.getElementById('mmClose');
const mmCancel  = document.getElementById('mmCancel');
const mmNew     = document.getElementById('mmNewFolder');
const mmCountLabel = document.getElementById('mmCountLabel');

const nfModal  = document.getElementById('newFolderModal');
const nfForm   = document.getElementById('nfForm');
const nfInput  = document.getElementById('nfInput');
const nfError  = document.getElementById('nfError');
const nfClose  = document.getElementById('nfClose');
const nfCancel = document.getElementById('nfCancel');

/* ── Estado ── */
let curPage = 1;
let curSize = parseInt(pageSize.value, 10);
let totalRows = 0;
let curFolder = '';
let foldersCache = [];
let noneCount = 0;
let curRows = [];          // cache da página atual (para o editar lead)

let isSearching = false;
let searchTimer = null;
const DEBOUNCE = 300;

/*
 * ── SELEÇÃO ROBUSTA ──
 * selected: Set com IDs de leads selecionados (pode conter IDs de qualquer página)
 * selectAllMode: quando true, TODOS os leads do filtro atual estão selecionados
 * allFilterIds: cache de todos os IDs do filtro (carregado sob demanda)
 */
let selected = new Set();
let selectAllMode = false;
let allFilterIds = null; // null = não carregado; array = carregado

/* ── Utilidades ── */
function esc(s) { return (s||'').replace(/[&<>"']/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":"&#39;"}[m])); }
function fmtPhone(s) { return s || '—'; }

/* ── Data relativa: "há 3 dias", "há 2 h", "agora" ── */
function relativeDate(iso) {
  if (!iso) return '—';
  const d = new Date(iso);
  if (isNaN(d)) return '—';
  const diff = Math.floor((Date.now() - d.getTime()) / 1000); // segundos
  if (diff < 60)        return 'agora';
  if (diff < 3600)      { const m = Math.floor(diff/60);    return `há ${m} min`; }
  if (diff < 86400)     { const h = Math.floor(diff/3600);  return `há ${h} h`; }
  if (diff < 2592000)   { const dd = Math.floor(diff/86400); return `há ${dd} dia${dd!==1?'s':''}`; }
  if (diff < 31536000)  { const mm = Math.floor(diff/2592000); return `há ${mm} ${mm!==1?'meses':'mês'}`; }
  const yy = Math.floor(diff/31536000);
  return `há ${yy} ano${yy!==1?'s':''}`;
}
function fullDate(iso) {
  if (!iso) return '';
  const d = new Date(iso);
  return isNaN(d) ? '' : d.toLocaleString('pt-BR');
}

/* ── Destaque do termo de busca (recebe texto já escapado) ── */
function highlight(escapedText, term) {
  if (!term || term.length < 2) return escapedText;
  // escapa o termo para uso em regex
  const safe = term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  try {
    return escapedText.replace(new RegExp(`(${safe})`, 'gi'), '<mark class="search-hl">$1</mark>');
  } catch {
    return escapedText;
  }
}

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, error: d?.error || t || 'Falha' };
  return d;
}

/* ════════════════════════════════════════════
   PASTAS
   ════════════════════════════════════════════ */
async function loadFolders() {
  const d = await fetchJSON(`${API}?action=folders.list`);
  if (!d.ok) return;

  const counts = d.counts || {};
  foldersCache = (d.folders || []).map(f => ({
    id: String(f.id),
    name: f.name,
    count: counts[String(f.id)] || 0,
    sort_order: f.sort_order ?? null
  }));
  noneCount = d.none || 0;

  const repop = (sel) => {
    if (!sel) return;
    while (sel.options.length) sel.remove(0);
    sel.add(new Option('Sem pasta', ''));
    foldersCache.forEach(f => sel.add(new Option(f.name, f.id)));
  };
  repop(createFolderSel);
  repop(importFolderSel);

  // ── Pré-seleciona a pasta atual no cadastro rápido ──
  syncCreateFolder();

  renderFoldersBar();
  updateFolderButtons();
}

/* Faz o select de cadastro refletir a pasta filtrada (se for uma pasta real) */
function syncCreateFolder() {
  if (!createFolderSel) return;
  if (curFolder && curFolder !== 'none' && foldersCache.some(f => f.id === String(curFolder))) {
    createFolderSel.value = String(curFolder);
  } else {
    createFolderSel.value = '';
  }
}

/* ── Render pastas como chips ── */
function renderFoldersBar() {
  foldersBar.innerHTML = '';

  const total = foldersCache.reduce((s, f) => s + f.count, 0) + noneCount;

  const makeChip = (label, count, value, draggable = false) => {
    const btn = document.createElement('button');
    btn.className = 'folder-chip' + (curFolder === value ? ' active' : '');
    btn.setAttribute('data-value', value);
    if (draggable) {
      btn.setAttribute('data-id', value);
      btn.setAttribute('draggable', 'true');
    }
    btn.innerHTML = `
      <svg class="w-3.5 h-3.5 shrink-0 opacity-60" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M3 7c0-1.1.9-2 2-2h3.93a2 2 0 0 1 1.66.88l.82 1.24a2 2 0 0 0 1.66.88H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z"/>
      </svg>
      ${esc(label)}
      <span class="chip-count">${count}</span>
    `;
    btn.addEventListener('click', async () => {
      curFolder = value;
      clearSelection();
      renderFoldersBar();
      updateFolderButtons();
      syncCreateFolder();
      await reloadData();
    });
    return btn;
  };

  foldersBar.appendChild(makeChip('Todas', total, ''));
  foldersBar.appendChild(makeChip('Sem pasta', noneCount, 'none'));

  foldersCache.forEach(f => {
    const chip = makeChip(f.name, f.count, f.id, true);
    enableChipDrag(chip);
    foldersBar.appendChild(chip);
  });
}

/* ── Drag & Drop para chips ── */
let dragChip = null;

function enableChipDrag(chip) {
  chip.addEventListener('dragstart', (e) => {
    dragChip = chip;
    chip.classList.add('dragging');
    e.dataTransfer.effectAllowed = 'move';
  });
  chip.addEventListener('dragend', async () => {
    if (!dragChip) return;
    dragChip.classList.remove('dragging');
    dragChip = null;
    // Sync order from DOM
    const ordered = [...foldersBar.querySelectorAll('[data-id]')].map(n => n.getAttribute('data-id'));
    foldersCache = ordered.map(id => foldersCache.find(f => f.id === id)).filter(Boolean);
    await postReorder();
  });
  chip.addEventListener('dragover', (e) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    chip.classList.add('drag-over');
  });
  chip.addEventListener('dragleave', () => chip.classList.remove('drag-over'));
  chip.addEventListener('drop', (e) => {
    e.preventDefault();
    chip.classList.remove('drag-over');
    if (!dragChip || dragChip === chip) return;
    const rect = chip.getBoundingClientRect();
    const before = (e.clientX - rect.left) < rect.width / 2;
    if (before) foldersBar.insertBefore(dragChip, chip);
    else foldersBar.insertBefore(dragChip, chip.nextSibling);
  });
}

async function postReorder() {
  const ids = foldersCache.map(f => parseInt(f.id, 10));
  const fd = new FormData();
  ids.forEach(id => fd.append('ids[]', id));
  await fetch(`${API}?action=folders.reorder`, { method: 'POST', body: fd });
}

function getCurrentFolder() {
  if (!curFolder || curFolder === 'none') return null;
  return foldersCache.find(f => String(f.id) === String(curFolder)) || null;
}
function updateFolderButtons() {
  const valid = !!getCurrentFolder();
  btnRenameFolder.disabled = !valid;
  btnDeleteFolder.disabled = !valid;
}

/* ── Ações de pasta ── */
btnRenameFolder.addEventListener('click', async () => {
  const f = getCurrentFolder();
  if (!f) return;
  const newName = prompt('Novo nome da pasta:', f.name || '');
  if (newName == null) return;
  const name = newName.trim();
  if (!name) { alert('Digite um nome.'); return; }

  const fd = new FormData();
  fd.append('id', f.id);
  fd.append('name', name);
  const d = await fetchJSON(`${API}?action=folders.rename`, { method: 'POST', body: fd });
  if (!d.ok) { alert(d.error || 'Falha ao renomear'); return; }
  await loadFolders();
  await reloadData();
});

btnDeleteFolder.addEventListener('click', async () => {
  const f = getCurrentFolder();
  if (!f) return;
  const msg = `Excluir a pasta "${f.name}"?` + (f.count > 0 ? `\n(${f.count} lead(s) serão movidos para "Sem pasta").` : '');
  if (!confirm(msg)) return;

  const fd = new FormData();
  fd.append('id', f.id);
  const d = await fetchJSON(`${API}?action=folders.delete`, { method: 'POST', body: fd });
  if (!d.ok) { alert(d.error || 'Falha'); return; }

  curFolder = '';
  await loadFolders();
  await reloadData();
});

/* ════════════════════════════════════════════
   MODAL NOVA PASTA
   ════════════════════════════════════════════ */
function openNewFolderModal(defaultName = '') {
  nfError.classList.add('hidden');
  nfInput.value = defaultName;
  nfModal.classList.remove('hidden');
  setTimeout(() => { nfInput.focus(); nfInput.select(); }, 0);
}
function closeNewFolderModal() { nfModal.classList.add('hidden'); }

btnNewFolder.addEventListener('click', () => openNewFolderModal());
nfClose.addEventListener('click', closeNewFolderModal);
nfCancel.addEventListener('click', closeNewFolderModal);
nfModal.addEventListener('click', (e) => { if (e.target === nfModal) closeNewFolderModal(); });
document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && !nfModal.classList.contains('hidden')) closeNewFolderModal(); });

nfForm.addEventListener('submit', async (ev) => {
  ev.preventDefault();
  const name = (nfInput.value || '').trim();
  if (!name) { nfError.textContent = 'Digite um nome.'; nfError.classList.remove('hidden'); nfInput.focus(); return; }

  const fd = new FormData();
  fd.append('name', name);
  const d = await fetchJSON(`${API}?action=folders.create`, { method: 'POST', body: fd });
  if (!d.ok) { nfError.textContent = d.error || 'Falha'; nfError.classList.remove('hidden'); return; }

  closeNewFolderModal();
  await loadFolders();
  if (d.folder?.id != null) {
    curFolder = String(d.folder.id);
  }
  syncCreateFolder();
  renderFoldersBar();
  updateFolderButtons();
  await reloadData();
});

/* ════════════════════════════════════════════
   MODAL EDITAR LEAD
   ════════════════════════════════════════════ */
function openEditModal(lead) {
  edError.classList.add('hidden');
  edId.value      = lead.id;
  edCompany.value = lead.company || '';
  edPhone.value   = lead.phone || '';
  editModal.classList.remove('hidden');
  setTimeout(() => { edCompany.focus(); edCompany.select(); }, 0);
}
function closeEditModal() { editModal.classList.add('hidden'); }

edClose.addEventListener('click', closeEditModal);
edCancel.addEventListener('click', closeEditModal);
editModal.addEventListener('click', (e) => { if (e.target === editModal) closeEditModal(); });
document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && !editModal.classList.contains('hidden')) closeEditModal(); });

edForm.addEventListener('submit', async (ev) => {
  ev.preventDefault();
  edError.classList.add('hidden');

  const id      = edId.value;
  const company = (edCompany.value || '').trim();
  const phone   = (edPhone.value || '').trim();

  if (!phone) { edError.textContent = 'Telefone é obrigatório.'; edError.classList.remove('hidden'); edPhone.focus(); return; }

  const fd = new FormData();
  fd.append('id', id);
  fd.append('company', company);
  fd.append('phone', phone);

  const d = await fetchJSON(`${API}?action=update`, { method: 'POST', body: fd });
  if (!d.ok) { edError.textContent = d.error || 'Falha ao salvar'; edError.classList.remove('hidden'); return; }

  closeEditModal();
  await reloadData();
});

/* ════════════════════════════════════════════
   IMPORTAÇÃO
   ════════════════════════════════════════════ */
btnToggleImport.addEventListener('click', () => importWrap.classList.toggle('hidden'));
btnCloseImport.addEventListener('click', () => importWrap.classList.add('hidden'));

formImport.addEventListener('submit', async (ev) => {
  ev.preventDefault();
  importMsg.textContent = 'Importando...';
  const fd = new FormData(formImport);
  const d = await fetchJSON(`${API}?action=import`, { method: 'POST', body: fd });
  importMsg.textContent = d.ok
    ? `${d.inserted} novos, ${d.updated} atualizados, ${d.skipped} ignorados.`
    : (d.error || 'Erro ao importar');
  if (d.ok) { await loadFolders(); await reloadData(); }
});

/* ════════════════════════════════════════════
   SELEÇÃO + CHECKBOX
   ════════════════════════════════════════════ */

function clearSelection() {
  selected.clear();
  selectAllMode = false;
  allFilterIds = null;
  checkAll.checked = false;
  checkAll.indeterminate = false;
  hideBanner();
  updateBulkUI();
}

function getSelectedIds() {
  return [...selected];
}

function getSelectedCount() {
  return selected.size;
}

/* Buscar TODOS os IDs do filtro atual */
async function fetchAllFilterIds() {
  if (allFilterIds !== null) return allFilterIds;
  const qs = new URLSearchParams({ action: 'all_ids' });
  if (curFolder !== '') qs.set('folder_id', curFolder);
  const qStr = searchInput.value.trim();
  if (qStr.length >= 2) qs.set('q', qStr);
  const d = await fetchJSON(`${API}?${qs.toString()}`);
  if (d.ok) {
    allFilterIds = d.ids || [];
  } else {
    allFilterIds = [];
  }
  return allFilterIds;
}

/* Banner "Selecionar todos os X leads" */
function showBanner(pageCount, totalCount) {
  if (totalCount <= pageCount) { hideBanner(); return; }
  if (selectAllMode) {
    selectAllBanner.innerHTML = `
      <div class="select-all-banner">
        <span>Todos os <strong>${totalCount}</strong> leads do filtro estão selecionados.</span>
        <button id="bannerClear">Limpar seleção</button>
      </div>`;
    selectAllBanner.classList.remove('hidden');
    document.getElementById('bannerClear')?.addEventListener('click', () => {
      clearSelection();
      syncCheckboxes();
    });
  } else {
    selectAllBanner.innerHTML = `
      <div class="select-all-banner">
        <span>${pageCount} leads desta página estão selecionados.</span>
        <button id="bannerSelectAll">Selecionar todos os ${totalCount} leads do filtro</button>
      </div>`;
    selectAllBanner.classList.remove('hidden');
    document.getElementById('bannerSelectAll')?.addEventListener('click', async () => {
      const ids = await fetchAllFilterIds();
      selected = new Set(ids);
      selectAllMode = true;
      syncCheckboxes();
      showBanner(pageCount, totalCount);
      updateBulkUI();
    });
  }
}
function hideBanner() { selectAllBanner.innerHTML = ''; selectAllBanner.classList.add('hidden'); }

function syncCheckboxes() {
  const cbs = leadRows.querySelectorAll('.rowcheck');
  cbs.forEach(cb => {
    const id = parseInt(cb.getAttribute('data-id'), 10);
    cb.checked = selected.has(id);
    cb.closest('tr')?.classList.toggle('row-selected', cb.checked);
  });
  updateMasterCheckbox();
}

function updateMasterCheckbox() {
  const all = leadRows.querySelectorAll('.rowcheck');
  if (!all.length) { checkAll.checked = false; checkAll.indeterminate = false; return; }
  const checked = [...all].filter(cb => cb.checked).length;
  checkAll.checked = (checked === all.length);
  checkAll.indeterminate = (checked > 0 && checked < all.length);
}

function updateBulkUI() {
  const count = getSelectedCount();
  if (count > 0) {
    bulkToolbar.classList.remove('hidden');
    bulkCount.textContent = `${count} selecionado${count !== 1 ? 's' : ''}`;
  } else {
    bulkToolbar.classList.add('hidden');
    hideBanner();
  }
}

checkAll.addEventListener('change', () => {
  const cbs = leadRows.querySelectorAll('.rowcheck');
  if (checkAll.checked) {
    // Selecionar todos da página
    cbs.forEach(cb => {
      const id = parseInt(cb.getAttribute('data-id'), 10);
      selected.add(id);
      cb.checked = true;
      cb.closest('tr')?.classList.add('row-selected');
    });
    // Se esta página = todos os leads, ativa selectAllMode
    const pageCount = cbs.length;
    if (pageCount > 0 && totalRows > pageCount) {
      showBanner(pageCount, totalRows);
    } else if (pageCount > 0) {
      selectAllMode = true;
    }
  } else {
    // Deselecionar tudo
    clearSelection();
    cbs.forEach(cb => {
      cb.checked = false;
      cb.closest('tr')?.classList.remove('row-selected');
    });
  }
  updateBulkUI();
});

/* ════════════════════════════════════════════
   TABELA
   ════════════════════════════════════════════ */
function renderRows(items) {
  leadRows.innerHTML = '';
  curRows = items || [];
  // NÃO limpar selected aqui — manter seleção cross-page
  checkAll.checked = false;
  checkAll.indeterminate = false;

  if (!items || !items.length) { emptyHint.classList.remove('hidden'); updateBulkUI(); return; }
  emptyHint.classList.add('hidden');

  // termo de busca ativo (para destaque)
  const term = isSearching ? searchInput.value.trim() : '';

  items.forEach(it => {
    const isChecked = selected.has(it.id) || selected.has(parseInt(it.id));
    const tr = document.createElement('tr');
    tr.className = 'border-t border-gray-200 dark:border-gray-800' + (isChecked ? ' row-selected' : '');

    const companyHtml = highlight(esc(it.company || '—'), term);
    const phoneHtml   = highlight(esc(fmtPhone(it.phone)), term);

    tr.innerHTML = `
      <td class="py-2 pr-3"><input data-id="${it.id}" type="checkbox" class="rowcheck size-4 rounded" ${isChecked ? 'checked' : ''}></td>
      <td class="py-2 pr-3">${companyHtml}</td>
      <td class="py-2 pr-3 font-mono text-xs">${phoneHtml}</td>
      <td class="py-2 pr-3 text-xs text-gray-500">
        <span class="lead-created" title="${esc(fullDate(it.created_at))}">${esc(relativeDate(it.created_at))}</span>
      </td>
      <td class="py-2 pr-3">
        <select data-id="${it.id}" class="move-one rounded-md border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-2 py-1 text-xs w-full">
          ${renderFolderOptions(it.folder_id)}
        </select>
      </td>
      <td class="py-2 pr-3">
        <span class="lead-edit-btn" data-id="${it.id}" title="Editar lead">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
            <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
            <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
          </svg>
        </span>
      </td>
    `;
    leadRows.appendChild(tr);
  });

  leadRows.querySelectorAll('.rowcheck').forEach(cb => {
    cb.addEventListener('change', e => {
      const id = parseInt(e.target.getAttribute('data-id'), 10);
      if (e.target.checked) {
        selected.add(id);
        e.target.closest('tr')?.classList.add('row-selected');
      } else {
        selected.delete(id);
        selectAllMode = false;
        e.target.closest('tr')?.classList.remove('row-selected');
      }
      updateMasterCheckbox();
      updateBulkUI();

      // Banner
      const cbs = leadRows.querySelectorAll('.rowcheck');
      const checkedCount = [...cbs].filter(c => c.checked).length;
      if (checkedCount === cbs.length && totalRows > cbs.length) {
        showBanner(checkedCount, totalRows);
      } else {
        hideBanner();
      }
    });
  });

  leadRows.querySelectorAll('.move-one').forEach(sel => {
    sel.addEventListener('change', async e => {
      const id = parseInt(e.target.getAttribute('data-id'), 10);
      const folderId = e.target.value === '' ? 'none' : e.target.value;
      const fd = new FormData();
      fd.append('ids[]', id);
      fd.append('folder_id', folderId);
      await fetchJSON(`${API}?action=move`, { method: 'POST', body: fd });
      await loadFolders();
    });
  });

  // ── Botão editar ──
  leadRows.querySelectorAll('.lead-edit-btn').forEach(btn => {
    btn.addEventListener('click', () => {
      const id = parseInt(btn.getAttribute('data-id'), 10);
      const lead = curRows.find(r => parseInt(r.id, 10) === id);
      if (lead) openEditModal(lead);
    });
  });

  updateMasterCheckbox();
  updateBulkUI();
}

function renderFolderOptions(currentFolderId) {
  let html = `<option value="" ${currentFolderId == null ? 'selected' : ''}>Sem pasta</option>`;
  foldersCache.forEach(f => {
    const sel = String(currentFolderId || '') === f.id ? 'selected' : '';
    html += `<option value="${f.id}" ${sel}>${esc(f.name)}</option>`;
  });
  return html;
}

/* ════════════════════════════════════════════
   LISTAGEM / BUSCA
   ════════════════════════════════════════════ */
async function loadPage(page = 1) {
  curPage = page;
  allFilterIds = null; // invalidar cache
  const q = new URLSearchParams({ action: 'list', page: String(curPage), limit: String(curSize) });
  if (curFolder !== '') q.set('folder_id', curFolder);
  const d = await fetchJSON(`${API}?${q.toString()}`);
  if (!d.ok) { alert(d.error || 'Erro'); return; }
  totalRows = d.total || 0;
  renderRows(d.data);
  const totalPages = Math.max(1, Math.ceil(totalRows / curSize));
  pageInfo.textContent = `${d.page} / ${totalPages}`;

  // ── total + contador "+X esta semana" ──
  const week = d.week || 0;
  let totalHtml = `${totalRows} lead${totalRows !== 1 ? 's' : ''}`;
  if (week > 0) {
    totalHtml += ` <span class="week-badge">+${week} esta semana</span>`;
  }
  totalInfo.innerHTML = totalHtml;

  btnPrev.disabled = (d.page <= 1) || isSearching;
  btnNext.disabled = (d.page >= totalPages) || isSearching;
}

async function runSearch(qStr) {
  allFilterIds = null;
  if (qStr.length < 2) {
    isSearching = false;
    searchInfo.textContent = '';
    searchClear.classList.add('hidden');
    await loadPage(1);
    return;
  }
  isSearching = true;
  searchInfo.textContent = 'Buscando...';
  const qs = new URLSearchParams({ action: 'search', q: qStr, limit: '200' });
  if (curFolder !== '') qs.set('folder_id', curFolder);
  const d = await fetchJSON(`${API}?${qs.toString()}`);
  if (!d.ok) { searchInfo.textContent = d.error || 'Erro'; return; }
  totalRows = d.total || 0;
  renderRows(d.data);
  pageInfo.textContent = `busca: ${d.total} resultado(s)`;
  totalInfo.textContent = '';
  btnPrev.disabled = true;
  btnNext.disabled = true;
  searchInfo.textContent = `${d.total} encontrado(s)`;
  searchClear.classList.remove('hidden');
}

async function reloadData() {
  const qStr = searchInput.value.trim();
  if (qStr.length >= 2) return runSearch(qStr);
  return loadPage(curPage);
}

searchInput.addEventListener('input', () => {
  clearTimeout(searchTimer);
  searchTimer = setTimeout(() => runSearch(searchInput.value.trim()), DEBOUNCE);
});
searchClear.addEventListener('click', async () => { searchInput.value = ''; await runSearch(''); });

/* ════════════════════════════════════════════
   BULK ACTIONS (toolbar flutuante)
   ════════════════════════════════════════════ */
btCancel.addEventListener('click', () => { clearSelection(); syncCheckboxes(); });

btDelete.addEventListener('click', async () => {
  const ids = getSelectedIds();
  if (!ids.length) return;
  if (!confirm(`Excluir ${ids.length} lead(s)? Esta ação não pode ser desfeita.`)) return;

  const total = ids.length;
  showProgress('delete', 'Excluindo leads...', total);

  const chunkSize = 500;
  let totalDeleted = 0;
  let processed = 0;

  for (let i = 0; i < ids.length; i += chunkSize) {
    const chunk = ids.slice(i, i + chunkSize);
    const fd = new FormData();
    chunk.forEach(id => fd.append('ids[]', id));
    const d = await fetchJSON(`${API}?action=delete`, { method: 'POST', body: fd });
    if (d.ok) totalDeleted += (d.deleted || 0);
    processed += chunk.length;
    updateProgress(processed, total);
  }

  finishProgress('delete', `${totalDeleted} lead${totalDeleted !== 1 ? 's' : ''} excluído${totalDeleted !== 1 ? 's' : ''} com sucesso!`);

  clearSelection();
  await loadFolders();
  await reloadData();
});

btMove.addEventListener('click', () => openMoveModal());

btExport.addEventListener('click', () => {
  const ids = getSelectedIds();
  if (!ids.length) return;
  const form = document.createElement('form');
  form.method = 'POST';
  form.action = `${API}?action=export.selected&delim=%3B`;
  form.target = '_blank';
  ids.forEach(id => {
    const inp = document.createElement('input');
    inp.type = 'hidden'; inp.name = 'ids[]'; inp.value = String(id);
    form.appendChild(inp);
  });
  document.body.appendChild(form);
  form.submit();
  document.body.removeChild(form);
});

/* Export do filtro (header) */
btnExport.addEventListener('click', () => {
  const qStr = searchInput.value.trim();
  const qs = new URLSearchParams({ action: 'export', delim: ';' });
  if (curFolder !== '') qs.set('folder_id', curFolder);
  if (qStr.length >= 2) qs.set('q', qStr);
  window.location.href = `${API}?${qs.toString()}`;
});

/* ════════════════════════════════════════════
   MODAL MOVER
   ════════════════════════════════════════════ */
function openMoveModal() {
  const count = getSelectedCount();
  mmCountLabel.textContent = `${count} lead${count !== 1 ? 's' : ''} selecionado${count !== 1 ? 's' : ''}`;
  mmGrid.innerHTML = '';

  const makeChip = (label, count, dataId) => {
    const btn = document.createElement('button');
    btn.className = 'folder-chip';
    btn.innerHTML = `
      <svg class="w-3.5 h-3.5 shrink-0 opacity-60" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <path d="M3 7c0-1.1.9-2 2-2h3.93a2 2 0 0 1 1.66.88l.82 1.24a2 2 0 0 0 1.66.88H19a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z"/>
      </svg>
      ${esc(label)}
      <span class="chip-count">${count}</span>
    `;
    btn.addEventListener('click', () => moveBulkTo(dataId));
    return btn;
  };

  mmGrid.appendChild(makeChip('Sem pasta', noneCount, 'none'));
  foldersCache.forEach(f => mmGrid.appendChild(makeChip(f.name, f.count, f.id)));
  moveModal.classList.remove('hidden');
}

async function moveBulkTo(target) {
  const ids = getSelectedIds();
  if (!ids.length) return;

  moveModal.classList.add('hidden');

  const total = ids.length;
  showProgress('move', 'Movendo leads...', total);

  const chunkSize = 500;
  let totalMoved = 0;
  let processed = 0;

  for (let i = 0; i < ids.length; i += chunkSize) {
    const chunk = ids.slice(i, i + chunkSize);
    const fd = new FormData();
    chunk.forEach(id => fd.append('ids[]', id));
    fd.append('folder_id', target);
    const d = await fetchJSON(`${API}?action=move`, { method: 'POST', body: fd });
    if (d.ok) totalMoved += (d.moved || 0);
    processed += chunk.length;
    updateProgress(processed, total);
  }

  finishProgress('move', `${totalMoved} lead${totalMoved !== 1 ? 's' : ''} movido${totalMoved !== 1 ? 's' : ''} com sucesso!`);

  clearSelection();
  await loadFolders();
  await reloadData();
}

mmClose.addEventListener('click', () => moveModal.classList.add('hidden'));
mmCancel.addEventListener('click', () => moveModal.classList.add('hidden'));
moveModal.addEventListener('click', (e) => { if (e.target === moveModal) moveModal.classList.add('hidden'); });
mmNew.addEventListener('click', () => { moveModal.classList.add('hidden'); openNewFolderModal(); });

/* ════════════════════════════════════════════
   CADASTRO
   ════════════════════════════════════════════ */
formCreate.addEventListener('submit', async (ev) => {
  ev.preventDefault();
  createMsg.textContent = 'Salvando...';
  const fd = new FormData(formCreate);
  fd.append('status', 'novo');
  const d = await fetchJSON(`${API}?action=create`, { method: 'POST', body: fd });
  createMsg.textContent = d.ok ? 'Salvo!' : (d.error || 'Erro');
  if (d.ok) {
    formCreate.reset();
    // mantém a pasta atual pré-selecionada após o reset
    syncCreateFolder();
    setTimeout(() => createMsg.textContent = '', 1500);
    await loadFolders();
    await reloadData();
  }
});

/* ════════════════════════════════════════════
   PAGINAÇÃO
   ════════════════════════════════════════════ */
btnPrev.addEventListener('click', () => loadPage(curPage - 1));
btnNext.addEventListener('click', () => loadPage(curPage + 1));
pageSize.addEventListener('change', () => { curSize = parseInt(pageSize.value, 10); loadPage(1); });

/* ════════════════════════════════════════════
   INIT
   ════════════════════════════════════════════ */
(async () => {
  await loadFolders();
  await loadPage();
})();
</script>