almeira-web/dripzone-app/src/app/api/custom-requests/route.ts

212 lines
7.6 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { dataService } from '@/lib/data-service';
import { CustomProductRequest } from '@/types';
import fs from 'fs';
import path from 'path';
const EVOLUTION_API_URL = process.env.EVOLUTION_API_URL || 'https://evolution.almeira.com.co';
const EVOLUTION_API_KEY = process.env.EVOLUTION_API_KEY || 'EE49029EEB85-4568-8F81-C9FDFC6E2943';
const EVOLUTION_INSTANCE = process.env.EVOLUTION_INSTANCE_NAME || 'AutomataAlmeira';
const CARLOS_PHONE = '573167455877';
// Carpeta local para almacenar fotos de encargos especiales
const UPLOADS_DIR = path.join(process.cwd(), 'public', 'uploads', 'custom-requests');
function ensureUploadsDir() {
if (!fs.existsSync(UPLOADS_DIR)) {
fs.mkdirSync(UPLOADS_DIR, { recursive: true });
}
}
// Función auxiliar para enviar mensajes de WhatsApp vía Evolution API
async function sendWhatsAppMessage(number: string, text: string) {
try {
const cleanNumber = number.replace(/\D/g, '');
const fullNumber = cleanNumber.length === 10 ? `57${cleanNumber}` : cleanNumber;
const res = await fetch(`${EVOLUTION_API_URL}/message/sendText/${EVOLUTION_INSTANCE}`, {
method: 'POST',
headers: {
apikey: EVOLUTION_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
number: fullNumber,
text: text,
}),
});
return await res.json();
} catch (err) {
console.warn('Error enviando WhatsApp a ' + number + ':', err);
return null;
}
}
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const userId = searchParams.get('userId') || undefined;
const requests = dataService.getCustomRequests(userId);
return NextResponse.json({ success: true, requests });
} catch (error: any) {
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const {
userId,
customerName,
customerPhone,
customerEmail,
customerCity,
brand,
modelName,
size,
colorway,
targetBudget,
notes,
imageBase64,
} = body;
if (!customerName || !customerPhone || !brand || !modelName || !size) {
return NextResponse.json(
{
success: false,
error: 'Faltan campos obligatorios: Nombre, Teléfono, Marca, Modelo y Talla.',
},
{ status: 400 }
);
}
let finalImageUrl = body.imageUrl || '';
// Si el usuario envió una imagen en base64, guardarla en disco
if (imageBase64 && imageBase64.startsWith('data:image')) {
try {
ensureUploadsDir();
const matches = imageBase64.match(/^data:image\/([a-zA-Z0-9]+);base64,(.+)$/);
if (matches) {
const ext = matches[1] === 'jpeg' ? 'jpg' : matches[1];
const buffer = Buffer.from(matches[2], 'base64');
const filename = `encargo-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.${ext}`;
const filePath = path.join(UPLOADS_DIR, filename);
fs.writeFileSync(filePath, buffer);
finalImageUrl = `/uploads/custom-requests/${filename}`;
}
} catch (saveErr) {
console.warn('No se pudo guardar la imagen del encargo en disco:', saveErr);
}
}
// Crear la solicitud en DataService
const createdRequest = dataService.addCustomRequest({
userId,
customerName,
customerPhone,
customerEmail,
customerCity: customerCity || 'Colombia',
brand,
modelName,
size,
colorway: colorway || 'Original / Según Foto',
targetBudget: targetBudget ? parseInt(targetBudget, 10) : undefined,
notes: notes || '',
imageUrl: finalImageUrl,
status: 'pending',
});
// 1. Notificación inmediata a Carlos (+57 316 745 5877)
const budgetFormatted = createdRequest.targetBudget
? `$${createdRequest.targetBudget.toLocaleString('es-CO')}`
: 'A cotizar por bodega';
const adminMessage = `🚨 *NUEVA SOLICITUD DE ENCARGO ESPECIAL* 👟
-----------------------------------------
👤 *Cliente:* ${customerName}
📱 *WhatsApp:* ${customerPhone}
🏙️ *Ciudad:* ${customerCity || 'Colombia'}
${customerEmail ? `✉️ *Correo:* ${customerEmail}\n` : ''}
🏷️ *Marca:* ${brand}
👟 *Modelo:* ${modelName}
📏 *Talla Deseada:* ${size}
🎨 *Colorway:* ${colorway || 'Original / Ver Foto'}
💰 *Presupuesto Estimado:* ${budgetFormatted}
📝 *Notas del Cliente:* ${notes || 'Ninguna'}
📅 *Fecha:* ${new Date().toLocaleString('es-CO')}
-----------------------------------------
⚡ ¡Consulta de inmediato con tus proveedores mayoristas para enviar cotización al cliente!`;
sendWhatsAppMessage(CARLOS_PHONE, adminMessage).catch(() => {});
sendWhatsAppMessage('120363428012905103@g.us', adminMessage).catch(() => {});
// 2. Confirmación automática al cliente por WhatsApp
const clientMessage = `👋 ¡Hola *${customerName}*!
Recibimos con éxito tu solicitud por encargo para las *${brand} ${modelName}* en talla *${size}*. 👟🔥
Nuestro equipo ya está verificando disponibilidad y mejor precio con nuestras bodegas y proveedores mayoristas. Te responderemos a este mismo chat con la cotización exacta en el menor tiempo posible.
¡Gracias por confiar en DripZone! 🚀`;
sendWhatsAppMessage(customerPhone, clientMessage).catch(() => {});
return NextResponse.json({
success: true,
message: '¡Solicitud de encargo recibida con éxito! Nuestro equipo te contactará por WhatsApp.',
request: createdRequest,
});
} catch (error: any) {
console.error('Error en POST /api/custom-requests:', error);
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
}
}
export async function PUT(request: NextRequest) {
try {
const body = await request.json();
const { id, updates, notifyCustomer } = body;
if (!id) {
return NextResponse.json({ success: false, error: 'ID de solicitud requerido' }, { status: 400 });
}
const updated = dataService.updateCustomRequest(id, updates);
if (!updated) {
return NextResponse.json({ success: false, error: 'Solicitud no encontrada' }, { status: 404 });
}
// Si el admin activó la notificación al cliente (por ejemplo al cotizar el producto)
if (notifyCustomer && updated.customerPhone && updated.quotedPrice) {
const quoteMessage = `👋 ¡Hola *${updated.customerName}*!
¡Buenas noticias! Encontramos tu par solicitado: *${updated.brand} ${updated.modelName}* en talla *${updated.size}*. 👟✨
💰 *Precio Cotizado:* $${updated.quotedPrice.toLocaleString('es-CO')} COP
🚚 *Envío:* Despacho directo a tu dirección con pago contraentrega disponible.
¿Deseas confirmar tu pedido para apartarlo de bodega de inmediato? Respóndenos a este mensaje para coordinar la entrega.`;
sendWhatsAppMessage(updated.customerPhone, quoteMessage).catch(() => {});
}
return NextResponse.json({ success: true, request: updated });
} catch (error: any) {
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
}
}
export async function DELETE(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const id = searchParams.get('id');
if (!id) {
return NextResponse.json({ success: false, error: 'ID requerido' }, { status: 400 });
}
const deleted = dataService.deleteCustomRequest(id);
return NextResponse.json({ success: deleted });
} catch (error: any) {
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
}
}