prepare('SELECT id, fin_at FROM turnero_sesiones WHERE fecha = ? LIMIT 1'); $stmt->execute([$hoy]); $existing = $stmt->fetch(PDO::FETCH_ASSOC); if ($existing) { if ($existing['fin_at'] === null) { jsonError('Ya hay una sesión abierta para hoy'); } // Re-abrir (fue cerrada) $pdo->prepare('UPDATE turnero_sesiones SET fin_at=NULL, cerrado_por=NULL WHERE id=?') ->execute([$existing['id']]); jsonOk(['sesion_id' => $existing['id']], 'Sesión del día reabierta'); } $stmt = $pdo->prepare( 'INSERT INTO turnero_sesiones (fecha, abierto_por, inicio_at) VALUES (?, ?, NOW())' ); $stmt->execute([$hoy, $uid]); jsonOk(['sesion_id' => (int)$pdo->lastInsertId()], 'Sesión del día abierta'); } // ── CERRAR sesión ──────────────────────────────────────────── if ($accion === 'cerrar') { $sesionId = (int)($input['sesion_id'] ?? 0); if (!$sesionId) jsonError('sesion_id requerido'); $stmt = $pdo->prepare('SELECT id, fin_at FROM turnero_sesiones WHERE id = ?'); $stmt->execute([$sesionId]); $s = $stmt->fetch(PDO::FETCH_ASSOC); if (!$s) jsonError('Sesión no encontrada', 404); if ($s['fin_at']) jsonError('La sesión ya está cerrada'); $pdo->prepare('UPDATE turnero_sesiones SET fin_at=NOW(), cerrado_por=? WHERE id=?') ->execute([$uid, $sesionId]); jsonOk(['sesion_id' => $sesionId], 'Sesión cerrada correctamente'); } // ── REABRIR sesión ─────────────────────────────────────────── if ($accion === 'reabrir') { $sesionId = (int)($input['sesion_id'] ?? 0); if (!$sesionId) jsonError('sesion_id requerido'); $stmt = $pdo->prepare('SELECT id, fin_at FROM turnero_sesiones WHERE id = ?'); $stmt->execute([$sesionId]); $s = $stmt->fetch(PDO::FETCH_ASSOC); if (!$s) jsonError('Sesión no encontrada', 404); $pdo->prepare('UPDATE turnero_sesiones SET fin_at=NULL, cerrado_por=NULL WHERE id=?') ->execute([$sesionId]); jsonOk(['sesion_id' => $sesionId], 'Sesión reabierta'); } // ── CONFIG WHATSAPP ────────────────────────────────────────── if ($accion === 'config_wa') { $template = trim($input['template'] ?? ''); $templateMuestra = trim($input['template_muestra'] ?? ''); $lang = trim($input['lang'] ?? 'es_CO'); $waKiosko = (int)($input['wa_kiosko'] ?? 0); $waConsent = (int)($input['wa_consent'] ?? 0); if ($template === '') jsonError('El nombre de plantilla es requerido'); if (!preg_match('/^[a-z0-9_]{1,64}$/i', $template)) { jsonError('Nombre de plantilla inválido — solo letras, números y guiones bajos'); } if ($templateMuestra !== '' && !preg_match('/^[a-z0-9_]{1,64}$/i', $templateMuestra)) { jsonError('Nombre de plantilla muestra inválido — solo letras, números y guiones bajos'); } if (!preg_match('/^[a-z]{2}_[A-Z]{2}$/i', $lang)) { jsonError('Código de idioma inválido (formato: es_CO)'); } // Upsert en lab_config $upsert = $pdo->prepare( 'INSERT INTO lab_config (clave, valor) VALUES (?, ?) ON DUPLICATE KEY UPDATE valor = VALUES(valor)' ); $upsert->execute(['turnero_wa_template', $template]); $upsert->execute(['turnero_wa_template_muestra', $templateMuestra]); $upsert->execute(['turnero_wa_lang', $lang]); $upsert->execute(['turnero_wa_kiosko_enabled', (string)$waKiosko]); $upsert->execute(['turnero_wa_consent_enabled', (string)$waConsent]); jsonOk([], 'Configuración WhatsApp guardada'); }