<?php
// public/api/leads.php
require_once __DIR__ . '/../../app/config.php';
require_once __DIR__ . '/../../app/db.php';

header('Content-Type: application/json; charset=utf-8');

function jexit(array $payload, int $status = 200) {
  http_response_code($status);
  echo json_encode($payload);
  exit;
}

if (empty($_SESSION['user']['id']) || empty($_SESSION['user']['email'])) {
  jexit(['ok' => false, 'error' => 'Não autenticado'], 401);
}

$pdo = db();

/** Normaliza telefone (mantém só dígitos) */
function normalizePhone($s) {
  return preg_replace('/\D+/', '', $s ?? '');
}

/**
 * Garante que exista uma linha em `users` para o e-mail atual e retorna o `id` de `users`.
 */
function getOrCreateUsersId(PDO $pdo, string $sessionId, string $email, ?string $name = null): string {
  $q = $pdo->prepare('select id from users where email = :e limit 1');
  $q->execute([':e' => $email]);
  $id = $q->fetchColumn();
  if ($id) return $id;

  $ins = $pdo->prepare('
    insert into users (id, email, name)
    values (:id, :e, :n)
    on conflict (email) do nothing
  ');
  $ins->execute([':id' => $sessionId, ':e' => $email, ':n' => $name]);

  $q->execute([':e' => $email]);
  $id = $q->fetchColumn();
  if (!$id) throw new RuntimeException('Falha ao sincronizar usuário em `users`.');
  return $id;
}

try {
  $authId    = $_SESSION['user']['id'];
  $authEmail = $_SESSION['user']['email'];
  $authName  = $_SESSION['user']['name'] ?? null;
  $userId    = getOrCreateUsersId($pdo, $authId, $authEmail, $authName);
  $action    = $_GET['action'] ?? '';

  switch ($action) {

    /* ====================== EXPORT ======================= */

    case 'export': {
      $folderParam = $_GET['folder_id'] ?? '';
      $q           = trim((string)($_GET['q'] ?? ''));
      $delim       = ($_GET['delim'] ?? ';') === ',' ? ',' : ';';
      $withBOM     = !isset($_GET['bom']) || $_GET['bom'] !== '0';

      $folderSql = '';
      $params = [':u' => $userId];

      if ($folderParam === 'none') {
        $folderSql = 'and l.folder_id is null';
      } elseif ($folderParam !== '') {
        $fid = (int)$folderParam;
        if ($fid > 0) {
          $folderSql = 'and l.folder_id = :f';
          $params[':f'] = $fid;
        }
      }

      $whereParts = [];
      if ($q !== '') {
        $digits = normalizePhone($q);
        $whereParts[] = 'l.company_name ILIKE :q';
        $params[':q'] = '%'.$q.'%';
        if ($digits !== '') {
          $whereParts[] = 'l.phone LIKE :dlike';
          $params[':dlike'] = '%'.$digits.'%';
          if (strlen($digits) === 4) {
            $whereParts[] = 'right(l.phone,4) = :last4';
            $params[':last4'] = $digits;
          }
        }
      }
      $whereSql = $whereParts ? (' and ('.implode(' OR ', $whereParts).')') : '';
      $hardLimit = 50000;

      $sql = "
        select
          l.company_name                 as company,
          l.phone                        as phone,
          coalesce(f.name, 'Sem pasta')  as folder
        from leads l
        left join lead_folders f
          on f.id = l.folder_id
         and f.user_id = l.user_id
        where l.user_id = :u $folderSql $whereSql
        order by l.created_at desc
        limit $hardLimit
      ";

      $fname = 'leads';
      if ($folderParam === 'none')       $fname .= '_sem-pasta';
      elseif ($folderParam !== '')       $fname .= '_pasta-'.$folderParam;
      if ($q !== '')                     $fname .= '_busca';
      $fname .= '_'.date('Y-m-d_H-i-s').'.csv';

      header('Content-Type: text/csv; charset=utf-8');
      header('Content-Disposition: attachment; filename="'.$fname.'"');

      $out = fopen('php://output', 'w');
      if ($withBOM) fwrite($out, "\xEF\xBB\xBF");
      fputcsv($out, ['company','phone','folder'], $delim);

      $stmt = $pdo->prepare($sql);
      foreach ($params as $k=>$v) {
        $stmt->bindValue($k, $v, is_int($v)?PDO::PARAM_INT:PDO::PARAM_STR);
      }
      $stmt->execute();

      while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        fputcsv($out, [$row['company'], $row['phone'], $row['folder']], $delim);
      }
      fclose($out);
      exit;
    }

    case 'export.selected': {
      $ids = $_POST['ids'] ?? [];
      if (!is_array($ids) || empty($ids)) jexit(['ok'=>false,'error'=>'Nenhum lead selecionado'], 400);
      $ids = array_filter(array_map('intval', $ids));
      if (!$ids) jexit(['ok'=>false,'error'=>'IDs inválidos'], 422);

      $delim   = ($_GET['delim'] ?? ';') === ',' ? ',' : ';';
      $withBOM = !isset($_GET['bom']) || $_GET['bom'] !== '0';

      $in  = implode(',', array_fill(0, count($ids), '?'));
      $sql = "
        select
          l.company_name                 as company,
          l.phone                        as phone,
          coalesce(f.name, 'Sem pasta')  as folder
        from leads l
        left join lead_folders f
          on f.id = l.folder_id
         and f.user_id = l.user_id
        where l.user_id = ?
          and l.id in ($in)
        order by l.created_at desc
      ";
      $stmt = $pdo->prepare($sql);
      $stmt->execute(array_merge([$userId], $ids));

      header('Content-Type: text/csv; charset=utf-8');
      header('Content-Disposition: attachment; filename="leads_selecionados_'.date('Y-m-d_H-i-s').'.csv"');

      $out = fopen('php://output', 'w');
      if ($withBOM) fwrite($out, "\xEF\xBB\xBF");
      fputcsv($out, ['company','phone','folder'], $delim);
      while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        fputcsv($out, [$row['company'], $row['phone'], $row['folder']], $delim);
      }
      fclose($out);
      exit;
    }

    /* ====================== PASTAS ======================= */

    case 'folders.list': {
      $stmt = $pdo->prepare('
        select id, name, sort_order
        from lead_folders
        where user_id = :u
        order by sort_order asc nulls last, lower(name)
      ');
      $stmt->execute([':u' => $userId]);
      $folders = $stmt->fetchAll(PDO::FETCH_ASSOC);

      $cnt = $pdo->prepare('
        select folder_id, count(*) as total
        from leads
        where user_id = :u
        group by folder_id
      ');
      $cnt->execute([':u' => $userId]);
      $counts = [];
      foreach ($cnt->fetchAll(PDO::FETCH_ASSOC) as $r) {
        $k = $r['folder_id'] === null ? 'null' : (string)$r['folder_id'];
        $counts[$k] = (int)$r['total'];
      }
      $noneCount = $counts['null'] ?? 0;

      jexit(['ok' => true, 'folders' => $folders, 'counts' => $counts, 'none' => $noneCount]);
    }

    case 'folders.reorder': {
      $idsInput = $_POST['ids'] ?? [];
      if (!is_array($idsInput) || empty($idsInput)) {
        jexit(['ok'=>false,'error'=>'Lista vazia'], 422);
      }

      $idsInput = array_values(array_filter(array_map('intval', $idsInput)));
      if (!$idsInput) jexit(['ok'=>false,'error'=>'IDs inválidos'], 422);

      $in  = implode(',', array_fill(0, count($idsInput), '?'));
      $chk = $pdo->prepare("select id from lead_folders where user_id = ? and id in ($in)");
      $chk->execute(array_merge([$userId], $idsInput));
      $owned = array_map('intval', $chk->fetchAll(PDO::FETCH_COLUMN));

      $ownedSorted = $owned;
      $idsSorted   = $idsInput;
      sort($ownedSorted);
      sort($idsSorted);
      if ($ownedSorted !== $idsSorted) {
        jexit(['ok'=>false,'error'=>'Pasta inválida'], 403);
      }

      $pdo->beginTransaction();
      $upd = $pdo->prepare('update lead_folders set sort_order = :o where id = :id and user_id = :u');
      $order = 1;
      foreach ($idsInput as $fid) {
        $upd->execute([':o'=>$order++, ':id'=>$fid, ':u'=>$userId]);
      }
      $pdo->commit();

      jexit(['ok'=>true]);
    }

    case 'folders.create': {
      $name = trim($_POST['name'] ?? '');
      if ($name === '') jexit(['ok'=>false,'error'=>'Nome da pasta é obrigatório'], 422);

      $nextStmt = $pdo->prepare("select coalesce(max(sort_order),0)+1 from lead_folders where user_id = :u");
      $nextStmt->execute([':u' => $userId]);
      $next = (int)$nextStmt->fetchColumn();

      $ins = $pdo->prepare('
        insert into lead_folders (user_id, name, sort_order)
        values (:u, :n, :o)
        on conflict (user_id, lower(name)) do nothing
        returning id, name, sort_order
      ');
      $ins->execute([':u'=>$userId, ':n'=>$name, ':o'=>$next]);
      $row = $ins->fetch(PDO::FETCH_ASSOC);
      if (!$row) jexit(['ok'=>false, 'error'=>'Já existe uma pasta com esse nome.'], 409);

      jexit(['ok'=>true,'folder'=>$row]);
    }

    case 'folders.rename': {
      $id   = (int)($_POST['id'] ?? 0);
      $name = trim($_POST['name'] ?? '');
      if ($id<=0 || $name==='') jexit(['ok'=>false,'error'=>'Dados inválidos'], 422);

      $own = $pdo->prepare('select 1 from lead_folders where id=:id and user_id=:u');
      $own->execute([':id'=>$id, ':u'=>$userId]);
      if (!$own->fetch()) jexit(['ok'=>false,'error'=>'Pasta não encontrada'], 404);

      $dup = $pdo->prepare('select 1 from lead_folders where user_id=:u and lower(name)=lower(:n) and id<>:id');
      $dup->execute([':u'=>$userId, ':n'=>$name, ':id'=>$id]);
      if ($dup->fetch()) jexit(['ok'=>false,'error'=>'Já existe pasta com esse nome'], 409);

      $up = $pdo->prepare('update lead_folders set name=:n where id=:id');
      $up->execute([':n'=>$name, ':id'=>$id]);

      jexit(['ok'=>true]);
    }

    case 'folders.delete': {
      $id = (int)($_POST['id'] ?? 0);
      if ($id<=0) jexit(['ok'=>false,'error'=>'ID inválido'], 422);

      $own = $pdo->prepare('select 1 from lead_folders where id=:id and user_id=:u');
      $own->execute([':id'=>$id, ':u'=>$userId]);
      if (!$own->fetch()) jexit(['ok'=>false,'error'=>'Pasta não encontrada'], 404);

      $pdo->beginTransaction();
      $pdo->prepare('update leads set folder_id = null where user_id=:u and folder_id=:f')
          ->execute([':u'=>$userId, ':f'=>$id]);
      $pdo->prepare('delete from lead_folders where id=:id and user_id=:u')
          ->execute([':id'=>$id, ':u'=>$userId]);
      $pdo->commit();

      jexit(['ok'=>true]);
    }

    case 'move': {
      $ids = $_POST['ids'] ?? [];
      $folder = $_POST['folder_id'] ?? '';

      if (!is_array($ids) || empty($ids)) jexit(['ok'=>false,'error'=>'Nenhum lead selecionado'], 400);
      $ids = array_filter(array_map('intval', $ids));
      if (empty($ids)) jexit(['ok'=>false,'error'=>'IDs inválidos'], 400);

      $folderId = null;
      if ($folder !== '' && $folder !== 'none') {
        $folderId = (int)$folder;
        if ($folderId <= 0) jexit(['ok'=>false,'error'=>'Pasta inválida'], 422);

        $own = $pdo->prepare('select 1 from lead_folders where id=:id and user_id=:u');
        $own->execute([':id'=>$folderId, ':u'=>$userId]);
        if (!$own->fetch()) jexit(['ok'=>false,'error'=>'Pasta não encontrada'], 404);
      }

      // ── BATCH em chunks de 500 para não estourar limites ──
      $total = 0;
      $chunks = array_chunk($ids, 500);
      $pdo->beginTransaction();
      foreach ($chunks as $chunk) {
        $in = implode(',', array_fill(0, count($chunk), '?'));
        $sql = "update leads set folder_id = ".($folderId===null?'NULL':(int)$folderId)." where user_id = ? and id in ($in)";
        $stmt = $pdo->prepare($sql);
        $stmt->execute(array_merge([$userId], $chunk));
        $total += $stmt->rowCount();
      }
      $pdo->commit();

      jexit(['ok'=>true, 'moved'=>$total]);
    }

    /* ===================== IMPORTAR ====================== */

    case 'import': {
      $csvText = '';
      if (!empty($_FILES['file']['tmp_name'])) {
        $csvText = file_get_contents($_FILES['file']['tmp_name']);
      } else {
        $csvText = trim($_POST['csv'] ?? '');
      }
      if ($csvText === '') jexit(['ok'=>false,'error'=>'Envie um arquivo CSV ou cole o conteúdo.'], 422);

      $folderId = null;
      $folderParam = $_POST['folder_id'] ?? '';
      if ($folderParam !== '' && $folderParam !== 'none') {
        $folderId = (int)$folderParam;
        if ($folderId>0) {
          $own = $pdo->prepare('select 1 from lead_folders where id=:id and user_id=:u');
          $own->execute([':id'=>$folderId, ':u'=>$userId]);
          if (!$own->fetch()) jexit(['ok'=>false,'error'=>'Pasta inválida'], 422);
        } else {
          $folderId = null;
        }
      }

      $csvText = str_replace(["\r\n","\r"], "\n", $csvText);
      $sep = (substr_count($csvText, ';') > substr_count($csvText, ',')) ? ';' : ',';

      $lines = array_values(array_filter(array_map('trim', explode("\n", $csvText)), fn($l)=>$l!==''));
      if (!$lines) jexit(['ok'=>false,'error'=>'CSV vazio.'], 422);

      $first    = str_getcsv($lines[0], $sep);
      $headers  = array_map(fn($h)=>mb_strtolower(trim($h)), $first);
      $hasHdr   = false;
      $map = ['company'=>0,'phone'=>1,'status'=>2];

      if (in_array('company', $headers) || in_array('company_name', $headers) || in_array('empresa', $headers) || in_array('nome', $headers)) {
        $hasHdr = true;
        foreach ($headers as $i=>$h) {
          if (in_array($h, ['company','company_name','empresa','nome','nome da empresa'])) $map['company']=$i;
          if (in_array($h, ['phone','telefone','celular','whatsapp'])) $map['phone']=$i;
          if (in_array($h, ['status','situação','situacao'])) $map['status']=$i;
        }
      }
      $start = $hasHdr ? 1 : 0;

      $limit = 5000;
      $rows = [];
      $seen = [];
      $ins=0; $upd=0; $skip=0;

      for ($i=$start; $i<count($lines) && count($rows)<$limit; $i++) {
        $cols   = str_getcsv($lines[$i], $sep);
        $comp   = trim($cols[$map['company']] ?? '');
        $phone  = normalizePhone($cols[$map['phone']] ?? '');
        $status = trim($cols[$map['status']] ?? 'novo');

        if ($comp==='' && $phone==='') { $skip++; continue; }
        if ($phone==='') { $skip++; continue; }

        if (isset($seen[$phone])) { $skip++; continue; }
        $seen[$phone] = true;

        $rows[] = [$userId, $comp, $phone, $status, $folderId];
      }
      if (!$rows) jexit(['ok'=>false,'error'=>'Nenhuma linha válida encontrada.'], 422);

      $sql = "
        insert into leads (user_id, company_name, phone, status, folder_id, created_at)
        values " . implode(',', array_fill(0, count($rows), '(?,?,?,?,?, now())')) . "
        on conflict (user_id, phone)
        do update set
          company_name = excluded.company_name,
          status       = excluded.status,
          folder_id    = coalesce(excluded.folder_id, leads.folder_id)
        returning xmax = 0 as inserted
      ";
      $flat = [];
      foreach ($rows as $r) { array_push($flat, $r[0], $r[1], $r[2], $r[3], $r[4]); }

      $stmt = $pdo->prepare($sql);
      $stmt->execute($flat);
      foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) {
        if (!empty($r['inserted'])) $ins++; else $upd++;
      }

      jexit(['ok'=>true, 'inserted'=>$ins, 'updated'=>$upd, 'skipped'=>$skip, 'total'=>$ins+$upd+$skip]);
    }

    /* ===================== LISTAGEM ====================== */

    case 'list': {
      $page  = max(1, (int)($_GET['page']  ?? 1));
      $limit = max(1, min(100, (int)($_GET['limit'] ?? 20)));
      $offset = ($page - 1) * $limit;

      $folderParam = $_GET['folder_id'] ?? '';
      $folderSql = '';
      $params = [':u' => $userId];

      if ($folderParam === 'none') {
        $folderSql = 'and folder_id is null';
      } elseif ($folderParam !== '') {
        $fid = (int)$folderParam;
        if ($fid > 0) {
          $folderSql = 'and folder_id = :f';
          $params[':f'] = $fid;
        }
      }

      $total = $pdo->prepare("select count(*) from leads where user_id = :u $folderSql");
      $total->execute($params);
      $totalRows = (int)$total->fetchColumn();

      // ── Contador: leads criados nos últimos 7 dias (respeita o filtro de pasta) ──
      $weekStmt = $pdo->prepare("
        select count(*) from leads
        where user_id = :u $folderSql
          and created_at >= now() - interval '7 days'
      ");
      $weekStmt->execute($params);
      $weekCount = (int)$weekStmt->fetchColumn();

      $stmt = $pdo->prepare("
        select id,
               company_name as company,
               phone,
               status,
               folder_id,
               created_at
        from leads
        where user_id = :u $folderSql
        order by created_at desc
        limit :lim offset :off
      ");
      foreach ($params as $k=>$v) $stmt->bindValue($k, $v, is_int($v)?PDO::PARAM_INT:PDO::PARAM_STR);
      $stmt->bindValue(':lim', $limit,  PDO::PARAM_INT);
      $stmt->bindValue(':off', $offset, PDO::PARAM_INT);
      $stmt->execute();
      $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

      jexit(['ok'=>true, 'page'=>$page, 'limit'=>$limit, 'total'=>$totalRows, 'week'=>$weekCount, 'data'=>$rows]);
    }

    /* =================== IDs DO FILTRO =================== */
    // Retorna TODOS os IDs do filtro atual (pasta + busca) para "selecionar todos"
    case 'all_ids': {
      $folderParam = $_GET['folder_id'] ?? '';
      $q           = trim((string)($_GET['q'] ?? ''));
      $folderSql   = '';
      $params      = [':u' => $userId];

      if ($folderParam === 'none') {
        $folderSql = 'and folder_id is null';
      } elseif ($folderParam !== '') {
        $fid = (int)$folderParam;
        if ($fid > 0) {
          $folderSql = 'and folder_id = :f';
          $params[':f'] = $fid;
        }
      }

      $whereParts = [];
      if ($q !== '') {
        $digits = normalizePhone($q);
        $whereParts[] = 'company_name ILIKE :q';
        $params[':q'] = '%'.$q.'%';
        if ($digits !== '') {
          $whereParts[] = 'phone LIKE :dlike';
          $params[':dlike'] = '%'.$digits.'%';
          if (strlen($digits) === 4) {
            $whereParts[] = 'right(phone,4) = :last4';
            $params[':last4'] = $digits;
          }
        }
      }
      $whereSql = $whereParts ? (' and ('.implode(' OR ', $whereParts).')') : '';

      $hardLimit = 50000;
      $stmt = $pdo->prepare("
        select id from leads
        where user_id = :u $folderSql $whereSql
        order by created_at desc
        limit $hardLimit
      ");
      foreach ($params as $k=>$v) {
        $stmt->bindValue($k, $v, is_int($v)?PDO::PARAM_INT:PDO::PARAM_STR);
      }
      $stmt->execute();
      $ids = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);

      jexit(['ok'=>true, 'ids'=>array_map('intval', $ids), 'total'=>count($ids)]);
    }

    /* ====================== BUSCA ======================== */

    case 'search': {
      $q = trim((string)($_GET['q'] ?? ''));
      if (mb_strlen($q) < 2) jexit(['ok'=>true, 'search'=>true, 'total'=>0, 'data'=>[]]);

      $folderParam = $_GET['folder_id'] ?? '';
      $folderSql = '';
      $params = [':u'=>$userId];

      if ($folderParam === 'none') {
        $folderSql = 'and folder_id is null';
      } elseif ($folderParam !== '') {
        $fid = (int)$folderParam;
        if ($fid > 0) {
          $folderSql = 'and folder_id = :f';
          $params[':f'] = $fid;
        }
      }

      $digits = normalizePhone($q);
      $where = [];
      $where[] = 'company_name ILIKE :q';
      $params[':q'] = '%'.$q.'%';

      if ($digits !== '') {
        $where[] = 'phone LIKE :dlike';
        $params[':dlike'] = '%'.$digits.'%';
        if (strlen($digits) === 4) {
          $where[] = 'right(phone,4) = :last4';
          $params[':last4'] = $digits;
        }
      }

      $limit = max(1, min(200, (int)($_GET['limit'] ?? 100)));

      $sqlBase = "
        from leads
        where user_id = :u $folderSql
          and ( ".implode(' OR ', $where)." )
      ";

      $stmtTotal = $pdo->prepare("select count(*) ".$sqlBase);
      $stmtData  = $pdo->prepare("
        select id, company_name as company, phone, status, folder_id, created_at
        ".$sqlBase."
        order by created_at desc
        limit :lim
      ");

      foreach ($params as $k=>$v) {
        $type = is_int($v) ? PDO::PARAM_INT : PDO::PARAM_STR;
        $stmtTotal->bindValue($k, $v, $type);
        $stmtData->bindValue($k, $v, $type);
      }
      $stmtData->bindValue(':lim', $limit, PDO::PARAM_INT);

      $stmtTotal->execute();
      $total = (int)$stmtTotal->fetchColumn();

      $stmtData->execute();
      $rows = $stmtData->fetchAll(PDO::FETCH_ASSOC);

      jexit(['ok'=>true, 'search'=>true, 'total'=>$total, 'limit'=>$limit, 'data'=>$rows]);
    }

    /* ====================== CRIAR ======================== */

    case 'create': {
      $company = trim($_POST['company'] ?? '');
      $phone   = normalizePhone($_POST['phone'] ?? '');
      $status  = trim($_POST['status'] ?? 'novo');

      $folderId = null;
      $folderParam = $_POST['folder_id'] ?? '';
      if ($folderParam !== '' && $folderParam !== 'none') {
        $folderId = (int)$folderParam;
        if ($folderId>0) {
          $own = $pdo->prepare('select 1 from lead_folders where id=:id and user_id=:u');
          $own->execute([':id'=>$folderId, ':u'=>$userId]);
          if (!$own->fetch()) jexit(['ok'=>false,'error'=>'Pasta inválida'], 422);
        } else {
          $folderId = null;
        }
      }

      if (!$phone) jexit(['ok'=>false, 'error'=>'Telefone é obrigatório.'], 400);

      $check = $pdo->prepare('select id from leads where user_id = :u and phone = :p limit 1');
      $check->execute([':u'=>$userId, ':p'=>$phone]);
      if ($check->fetch()) jexit(['ok'=>false, 'error'=>'Lead já existe para este número.'], 409);

      $stmt = $pdo->prepare('
        insert into leads (user_id, company_name, phone, status, folder_id, created_at)
        values (:u, :c, :p, :s, :f, now())
        returning id
      ');
      $stmt->execute([':u'=>$userId, ':c'=>$company, ':p'=>$phone, ':s'=>$status, ':f'=>$folderId]);
      $id = $stmt->fetchColumn();

      jexit(['ok'=>true, 'id'=>$id]);
    }

    /* ===================== EDITAR ======================== */

    case 'update': {
      $id      = (int)($_POST['id'] ?? 0);
      $company = trim($_POST['company'] ?? '');
      $phone   = normalizePhone($_POST['phone'] ?? '');

      if ($id <= 0)  jexit(['ok'=>false, 'error'=>'ID inválido.'], 422);
      if (!$phone)   jexit(['ok'=>false, 'error'=>'Telefone é obrigatório.'], 400);

      // Confirma que o lead pertence ao usuário
      $own = $pdo->prepare('select 1 from leads where id = :id and user_id = :u');
      $own->execute([':id'=>$id, ':u'=>$userId]);
      if (!$own->fetch()) jexit(['ok'=>false, 'error'=>'Lead não encontrado.'], 404);

      // Confirma que o telefone não pertence a outro lead do mesmo usuário
      $dup = $pdo->prepare('select 1 from leads where user_id = :u and phone = :p and id <> :id limit 1');
      $dup->execute([':u'=>$userId, ':p'=>$phone, ':id'=>$id]);
      if ($dup->fetch()) jexit(['ok'=>false, 'error'=>'Já existe outro lead com este número.'], 409);

      $up = $pdo->prepare('
        update leads
        set company_name = :c, phone = :p
        where id = :id and user_id = :u
      ');
      $up->execute([':c'=>$company, ':p'=>$phone, ':id'=>$id, ':u'=>$userId]);

      jexit(['ok'=>true, 'id'=>$id]);
    }

    /* ===================== EXCLUIR ======================= */

    case 'delete': {
      $ids = $_POST['ids'] ?? [];
      if (!is_array($ids) || empty($ids)) jexit(['ok'=>false,'error'=>'Nenhum lead selecionado'], 400);

      $ids = array_filter(array_map('intval', $ids));
      if (empty($ids)) jexit(['ok'=>false,'error'=>'IDs inválidos'], 400);

      // ── BATCH em chunks de 500 para garantir que todos sejam excluídos ──
      $total = 0;
      $chunks = array_chunk($ids, 500);
      $pdo->beginTransaction();
      foreach ($chunks as $chunk) {
        $in  = implode(',', array_fill(0, count($chunk), '?'));
        $sql = "delete from leads where user_id = ? and id in ($in)";
        $stmt = $pdo->prepare($sql);
        $stmt->execute(array_merge([$userId], $chunk));
        $total += $stmt->rowCount();
      }
      $pdo->commit();

      jexit(['ok'=>true, 'deleted'=>$total]);
    }

    default:
      jexit(['ok'=>false, 'error'=>'Ação inválida'], 400);
  }
} catch (Throwable $e) {
  jexit(['ok'=>false, 'error'=>$e->getMessage()], 500);
}