210 lines
13 KiB
C#
210 lines
13 KiB
C#
|
|
using Microsoft.Extensions.Logging;
|
|||
|
|
using MotoresArgentinosV2.Core.Interfaces;
|
|||
|
|
using Microsoft.Extensions.Configuration;
|
|||
|
|
|
|||
|
|
namespace MotoresArgentinosV2.Infrastructure.Services;
|
|||
|
|
|
|||
|
|
public class NotificationService : INotificationService
|
|||
|
|
{
|
|||
|
|
private readonly IEmailService _emailService;
|
|||
|
|
private readonly ILogger<NotificationService> _logger;
|
|||
|
|
private readonly string _frontendUrl;
|
|||
|
|
|
|||
|
|
public NotificationService(IEmailService emailService, ILogger<NotificationService> logger, IConfiguration config)
|
|||
|
|
{
|
|||
|
|
_emailService = emailService;
|
|||
|
|
_logger = logger;
|
|||
|
|
// Leemos la URL del appsettings o usamos localhost como fallback
|
|||
|
|
_frontendUrl = config["AppSettings:FrontendUrl"] ?? "http://localhost:5173";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private string GetEmailShell(string title, string content)
|
|||
|
|
{
|
|||
|
|
return $@"
|
|||
|
|
<div style='background-color: #0a0c10; color: #e5e7eb; font-family: sans-serif; padding: 40px; line-height: 1.6;'>
|
|||
|
|
<div style='max-width: 600px; margin: 0 auto; background-color: #12141a; border: 1px solid #1f2937; border-radius: 24px; overflow: hidden; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5);'>
|
|||
|
|
<div style='background: linear-gradient(to right, #2563eb, #22d3ee); padding: 30px; text-align: center;'>
|
|||
|
|
<h1 style='color: white; margin: 0; font-size: 24px; text-transform: uppercase; letter-spacing: 2px; font-weight: 900;'>Motores <span style='color: #bfdbfe;'>Argentinos</span></h1>
|
|||
|
|
</div>
|
|||
|
|
<div style='padding: 40px;'>
|
|||
|
|
<h2 style='color: white; font-size: 20px; font-weight: 800; margin-top: 0; text-transform: uppercase;'>{title}</h2>
|
|||
|
|
<div style='color: #9ca3af; font-size: 14px;'>
|
|||
|
|
{content}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div style='padding: 20px; border-top: 1px solid #1f2937; text-align: center; background-color: #0d0f14;'>
|
|||
|
|
<p style='color: #4b5563; font-size: 10px; text-transform: uppercase; letter-spacing: 1px; margin: 0;'>Motores Argentinos - La Plata, Buenos Aires, Argentina</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task SendChatNotificationEmailAsync(string toEmail, string fromUser, string message, int adId)
|
|||
|
|
{
|
|||
|
|
string subject = "Tienes un nuevo mensaje - Motores Argentinos";
|
|||
|
|
string content = $@"
|
|||
|
|
<p>Hola,</p>
|
|||
|
|
<p><strong>{fromUser}</strong> te ha enviado un mensaje sobre el aviso #{adId}:</p>
|
|||
|
|
<blockquote style='background: #1a1d24; border-left: 4px solid #2563eb; padding: 15px; margin: 20px 0; font-style: italic; color: #d1d5db;'>
|
|||
|
|
""{message}""
|
|||
|
|
</blockquote>
|
|||
|
|
<p style='margin-top: 20px;'>Ingresa a tu cuenta para responder.</p>
|
|||
|
|
<div style='text-align: center; margin: 30px 0;'>
|
|||
|
|
<a href='{_frontendUrl}/mis-avisos' style='background-color: #2563eb; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; text-transform: uppercase; font-size: 12px;'>VER MENSAJES</a>
|
|||
|
|
</div>";
|
|||
|
|
|
|||
|
|
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Nuevo Mensaje", content));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task SendAdStatusChangedEmailAsync(string toEmail, string adTitle, string status, string? reason = null)
|
|||
|
|
{
|
|||
|
|
string subject = "Estado de tu aviso - Motores Argentinos";
|
|||
|
|
string color = status.ToUpper() == "APROBADO" ? "#10b981" : "#ef4444";
|
|||
|
|
|
|||
|
|
string content = $@"
|
|||
|
|
<p>Hola,</p>
|
|||
|
|
<p>Te informamos que el estado de tu aviso <strong>""{adTitle}""</strong> ha cambiado a:</p>
|
|||
|
|
<div style='background: {color}20; border: 1px solid {color}; color: {color}; padding: 15px; border-radius: 8px; text-align: center; font-weight: 900; text-transform: uppercase; margin: 20px 0; font-size: 16px;'>
|
|||
|
|
{status}
|
|||
|
|
</div>
|
|||
|
|
{(string.IsNullOrEmpty(reason) ? "" : $"<p style='background: #1f2937; padding: 15px; border-radius: 8px; border-left: 4px solid #ef4444;'><strong>Motivo:</strong> {reason}</p>")}
|
|||
|
|
<p style='margin-top: 20px;'>Gracias por confiar en nosotros.</p>";
|
|||
|
|
|
|||
|
|
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Cambio de Estado", content));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task SendSecurityAlertEmailAsync(string toEmail, string actionDescription)
|
|||
|
|
{
|
|||
|
|
string subject = "Alerta de Seguridad - Motores Argentinos";
|
|||
|
|
string content = $@"
|
|||
|
|
<p style='color: #f87171; font-weight: bold; font-size: 16px;'>¡Alerta de Seguridad!</p>
|
|||
|
|
<p>Te informamos que se ha realizado la siguiente acción crítica en tu cuenta:</p>
|
|||
|
|
<div style='background: #1a1d24; border: 1px solid #374151; padding: 15px; border-radius: 8px; margin: 20px 0;'>
|
|||
|
|
<span style='color: white; font-weight: bold;'>Acción:</span> {actionDescription}
|
|||
|
|
</div>
|
|||
|
|
<p>Si no fuiste tú, te recomendamos cambiar tu contraseña inmediatamente y contactar a nuestro equipo de soporte.</p>
|
|||
|
|
<p style='margin-top: 20px;'>Atentamente,<br>Equipo de Seguridad.</p>";
|
|||
|
|
|
|||
|
|
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Alerta de Seguridad", content));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task SendExpirationWarningEmailAsync(string toEmail, string userName, string adTitle, DateTime expirationDate)
|
|||
|
|
{
|
|||
|
|
string subject = "Tu aviso está por vencer - Motores Argentinos";
|
|||
|
|
string content = $@"
|
|||
|
|
<p>Hola <strong>{userName}</strong>,</p>
|
|||
|
|
<p>Te recordamos que tu publicación <strong>""{adTitle}""</strong> finalizará el día <strong>{expirationDate:dd/MM/yyyy}</strong>.</p>
|
|||
|
|
<p>Para asegurar que tu vehículo siga visible y no pierdas potenciales compradores, te recomendamos renovarlo ahora.</p>
|
|||
|
|
<div style='text-align: center; margin: 30px 0;'>
|
|||
|
|
<a href='{_frontendUrl}/mis-avisos' style='background-color: #f59e0b; color: #000; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; text-transform: uppercase; font-size: 12px;'>RENOVAR AVISO</a>
|
|||
|
|
</div>";
|
|||
|
|
|
|||
|
|
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Aviso por Vencer", content));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task SendAdExpiredEmailAsync(string toEmail, string userName, string adTitle)
|
|||
|
|
{
|
|||
|
|
string subject = "Tu aviso ha finalizado - Motores Argentinos";
|
|||
|
|
string content = $@"
|
|||
|
|
<p>Hola <strong>{userName}</strong>,</p>
|
|||
|
|
<p>Tu aviso <strong>""{adTitle}""</strong> ha llegado al fin de su vigencia y ya no es visible en los listados.</p>
|
|||
|
|
<p>Si aún no vendiste tu vehículo, puedes republicarlo fácilmente desde tu panel de gestión.</p>
|
|||
|
|
<div style='text-align: center; margin: 30px 0;'>
|
|||
|
|
<a href='{_frontendUrl}/mis-avisos' style='background-color: #2563eb; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; text-transform: uppercase; font-size: 12px;'>REPUBLICAR AHORA</a>
|
|||
|
|
</div>";
|
|||
|
|
|
|||
|
|
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Aviso Finalizado", content));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task SendWeeklyPerformanceEmailAsync(string toEmail, string userName, string adTitle, int views, int favorites)
|
|||
|
|
{
|
|||
|
|
string subject = "Resumen semanal de tu aviso - Motores Argentinos";
|
|||
|
|
|
|||
|
|
string content = $@"
|
|||
|
|
<p>Hola <strong>{userName}</strong>,</p>
|
|||
|
|
<p>Aquí tienes el rendimiento de tu aviso <strong>""{adTitle}""</strong> en los últimos 7 días:</p>
|
|||
|
|
|
|||
|
|
<!-- Contenedor Principal Centrado -->
|
|||
|
|
<div style='text-align: center; margin: 30px 0; font-size: 0;'>
|
|||
|
|
<!--[if mso]>
|
|||
|
|
<table role='presentation' width='100%'>
|
|||
|
|
<tr>
|
|||
|
|
<td style='width:50%; padding: 5px;' valign='top'>
|
|||
|
|
<![endif]-->
|
|||
|
|
|
|||
|
|
<!-- Caja Visitas -->
|
|||
|
|
<div style='display: inline-block; width: 46%; min-width: 140px; vertical-align: top; margin: 1%; background: #1f2937; border-radius: 12px; padding: 25px 10px; box-sizing: border-box; border: 1px solid #374151;'>
|
|||
|
|
<span style='font-size: 28px; display: block; margin-bottom: 5px;'>👁️</span>
|
|||
|
|
<strong style='font-size: 24px; color: #ffffff; display: block; font-family: sans-serif;'>{views}</strong>
|
|||
|
|
<span style='font-size: 11px; color: #9ca3af; text-transform: uppercase; font-weight: bold; letter-spacing: 1px; font-family: sans-serif;'>Visitas</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!--[if mso]>
|
|||
|
|
</td>
|
|||
|
|
<td style='width:50%; padding: 5px;' valign='top'>
|
|||
|
|
<![endif]-->
|
|||
|
|
|
|||
|
|
<!-- Caja Favoritos -->
|
|||
|
|
<div style='display: inline-block; width: 46%; min-width: 140px; vertical-align: top; margin: 1%; background: #1f2937; border-radius: 12px; padding: 25px 10px; box-sizing: border-box; border: 1px solid #374151;'>
|
|||
|
|
<span style='font-size: 28px; display: block; margin-bottom: 5px;'>⭐</span>
|
|||
|
|
<strong style='font-size: 24px; color: #ffffff; display: block; font-family: sans-serif;'>{favorites}</strong>
|
|||
|
|
<span style='font-size: 11px; color: #9ca3af; text-transform: uppercase; font-weight: bold; letter-spacing: 1px; font-family: sans-serif;'>Favoritos</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!--[if mso]>
|
|||
|
|
</td>
|
|||
|
|
</tr>
|
|||
|
|
</table>
|
|||
|
|
<![endif]-->
|
|||
|
|
</div>";
|
|||
|
|
|
|||
|
|
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Rendimiento Semanal", content));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task SendPaymentReminderEmailAsync(string toEmail, string userName, string adTitle, string link)
|
|||
|
|
{
|
|||
|
|
string subject = "Finaliza la publicación de tu aviso - Motores Argentinos";
|
|||
|
|
string content = $@"
|
|||
|
|
<p>Hola <strong>{userName}</strong>,</p>
|
|||
|
|
<p>Tu aviso del <strong>""{adTitle}""</strong> está casi listo, pero aún no es visible para los compradores.</p>
|
|||
|
|
<p>Solo falta confirmar el pago para activarlo. ¡No pierdas oportunidades de venta!</p>
|
|||
|
|
<div style='text-align: center; margin: 30px 0;'>
|
|||
|
|
<a href='{link}' style='background-color: #10b981; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; text-transform: uppercase; font-size: 12px;'>FINALIZAR PUBLICACIÓN</a>
|
|||
|
|
</div>";
|
|||
|
|
|
|||
|
|
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Acción Requerida", content));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task SendPaymentReceiptEmailAsync(string toEmail, string userName, string adTitle, decimal amount, string operationCode)
|
|||
|
|
{
|
|||
|
|
string subject = "Comprobante de Pago - Motores Argentinos";
|
|||
|
|
string content = $@"
|
|||
|
|
<p>Hola <strong>{userName}</strong>,</p>
|
|||
|
|
<p>Hemos recibido tu pago correctamente. Aquí tienes el detalle de la operación:</p>
|
|||
|
|
<div style='background: #1f2937; padding: 20px; border-radius: 8px; margin: 20px 0; border: 1px solid #374151;'>
|
|||
|
|
<p style='margin: 5px 0;'><strong>Concepto:</strong> Publicación Aviso Clasificado</p>
|
|||
|
|
<p style='margin: 5px 0;'><strong>Vehículo:</strong> {adTitle}</p>
|
|||
|
|
<p style='margin: 5px 0;'><strong>Operación:</strong> {operationCode}</p>
|
|||
|
|
<p style='margin: 5px 0;'><strong>Fecha:</strong> {DateTime.Now:dd/MM/yyyy HH:mm}</p>
|
|||
|
|
<hr style='border: 0; border-top: 1px solid #374151; margin: 15px 0;'>
|
|||
|
|
<p style='margin: 5px 0; font-size: 18px; text-align: right; color: #10b981;'><strong>Total: ${amount:N2}</strong></p>
|
|||
|
|
</div>
|
|||
|
|
<p>Tu aviso ha pasado a la etapa de moderación y será activado a la brevedad.</p>";
|
|||
|
|
|
|||
|
|
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Recibo de Pago", content));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task SendUnreadMessagesReminderEmailAsync(string toEmail, string userName, int unreadCount)
|
|||
|
|
{
|
|||
|
|
string subject = "Tienes mensajes sin leer - Motores Argentinos";
|
|||
|
|
string content = $@"
|
|||
|
|
<p>Hola <strong>{userName}</strong>,</p>
|
|||
|
|
<p>Tienes <strong>{unreadCount} mensaje{(unreadCount > 1 ? "s" : "")} sin leer</strong> en tu bandeja de entrada.</p>
|
|||
|
|
<p>Es importante responder a los interesados o moderadores para mantener la actividad de tu cuenta.</p>
|
|||
|
|
<div style='text-align: center; margin: 30px 0;'>
|
|||
|
|
<a href='{_frontendUrl}/mis-avisos' style='background-color: #2563eb; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; font-weight: bold; text-transform: uppercase; font-size: 12px;'>IR A MIS MENSAJES</a>
|
|||
|
|
</div>";
|
|||
|
|
|
|||
|
|
await _emailService.SendEmailAsync(toEmail, subject, GetEmailShell("Mensajes Pendientes", content));
|
|||
|
|
}
|
|||
|
|
}
|