package services import ( "fmt" "log" "time" "github.com/gofiber/fiber/v2" "github.com/sujit-baniya/fiber-boilerplate/app" "github.com/sujit-baniya/fiber-boilerplate/utils" ) func SendPasswordResetEmail(email string, baseURL string) { resetEmail := fmt.Sprintf("%s-reset-%d", email, time.Now().Unix()) resetLink := GeneratePasswordResetURL(resetEmail, baseURL) htmlBody := app.Http.Mail.PrepareHtml("emails/password-reset", fiber.Map{ "reset_link": resetLink, }) if htmlBody == "" { htmlBody = fmt.Sprintf(`

Restablece tu contraseña haciendo clic aquí: %s

`, resetLink, resetLink) } if err := app.Http.Mail.Send(email, "Solicitud de restablecimiento de contraseña - U-site", htmlBody); err != nil { log.Printf("[MAIL] Error enviando reset a %s: %v", email, err) } else { log.Printf("[MAIL] Reset enviado a %s", email) } } func SendConfirmationEmail(email string, baseURL string, nombreUsuario string) { log.Printf("[MAIL] SendConfirmationEmail → to=%s host=%s port=%d from=%s", email, app.Http.Mail.Host, app.Http.Mail.Port, app.Http.Mail.FromAddress) confirmLink := GenerateConfirmURL(nombreUsuario, baseURL) htmlBody := app.Http.Mail.PrepareHtml("emails/confirm", fiber.Map{ "confirm_link": confirmLink, }) if htmlBody == "" { log.Printf("[MAIL] PrepareHtml devolvió cuerpo vacío, usando fallback HTML") htmlBody = fmt.Sprintf(`

Hola %s, confirma tu registro haciendo clic aquí: %s

`, nombreUsuario, confirmLink, confirmLink) } log.Printf("[MAIL] HTML body length: %d bytes", len(htmlBody)) if err := app.Http.Mail.Send(email, "✅ ¡Confirma tu registro en la Oficina Virtual de U-site!", htmlBody); err != nil { log.Printf("[MAIL] Error enviando confirmación a %s: %v", email, err) } else { log.Printf("[MAIL] Confirmación enviada a %s", email) } } // SendUserCredencialesEmail envía al usuario admin su nombre de usuario y un link para establecer contraseña. func SendUserCredencialesEmail(email, nombre, nombreUsuario string) { resetEmail := fmt.Sprintf("%s-reset-%d", email, time.Now().Unix()) resetLink := GeneratePasswordResetURL(resetEmail, GetPublicURL()) loginURL := absAppURL("/login") htmlBody := fmt.Sprintf(`
U

Bienvenido a U-site

Panel de administración

Hola %s,

Tu cuenta ha sido creada. Estos son tus datos de acceso:

Usuario: %s

Acceso: %s

Establece tu contraseña haciendo clic en el siguiente botón:

Establecer contraseña

El enlace es válido por 1 hora.

© U-site — Todos los derechos reservados

`, nombre, nombreUsuario, loginURL, loginURL, resetLink) if err := app.Http.Mail.Send(email, "Bienvenido a U-site — Tus credenciales de acceso", htmlBody); err != nil { log.Printf("[MAIL] Error enviando credenciales a %s: %v", email, err) } else { log.Printf("[MAIL] Credenciales enviadas a %s", email) } } func GenerateConfirmURL(nombreUsuario string, baseURL string) string { token := utils.Encrypt(nombreUsuario, app.Http.Server.Key) uri := fmt.Sprintf("%s/do/verify-email?t=%s", baseURL, token) return uri } func GeneratePasswordResetURL(email string, baseURL string) string { token := utils.Encrypt(email, app.Http.Server.Key) uri := fmt.Sprintf("%s/reset-password?t=%s", baseURL, token) return uri } // SendPortalPasswordResetEmail envía al usuario del portal un enlace para restablecer su contraseña. func SendPortalPasswordResetEmail(email, nombre, resetLink string) { htmlBody := fmt.Sprintf(`
U

Restablecer contraseña

Portal de Clientes · U-site

Hola %s,

Recibimos una solicitud para restablecer la contraseña de tu cuenta. Haz clic en el siguiente botón para continuar:

Restablecer contraseña

Este enlace es válido por 1 hora. Si no solicitaste este cambio, puedes ignorar este mensaje.

© 2025 U-site — Todos los derechos reservados

`, nombre, resetLink) go func() { if err := app.Http.Mail.Send(email, "Restablece tu contraseña - Portal U-site", htmlBody, ""); err != nil { log.Printf("[Portal] Error enviando correo de reseteo a %s: %v", email, err) } }() } // SendPortalCredentialsEmail envía al usuario del portal su URL de acceso y contraseña inicial. func SendPortalCredentialsEmail(email, nombre, password string) { loginURL := absAppURL("/portal/login") htmlBody := fmt.Sprintf(`
U

Portal de Clientes

Acceso a tu espacio de trabajo

Hola %s,

Tu cuenta en el Portal de Clientes ha sido creada. Usa los siguientes datos para ingresar:

Email: %s

Contraseña: %s

Enlace de acceso: %s

Ingresar al Portal

Si no esperabas este correo, puedes ignorarlo.

`, nombre, email, password, loginURL, loginURL, loginURL) go func() { if err := app.Http.Mail.Send(email, "Acceso a tu Portal de Clientes - U-site", htmlBody, ""); err != nil { log.Printf("[Portal] Error enviando credenciales a %s: %v", email, err) } }() } // ─── Notificaciones de Tickets ──────────────────────────────────────────────── // SendTicketNuevoAdmin notifica al admin que el cliente abrió un ticket. func SendTicketNuevoAdmin(adminEmail, proyectoNombre, autorNombre, titulo, descripcion, ticketURL string) { subject := fmt.Sprintf("🎫 Nuevo ticket: %s", titulo) htmlBody := fmt.Sprintf(`
🎫

Nuevo ticket de soporte

Proyecto: %s

Cliente: %s

Título: %s

Descripción: %s

Ver ticket
`, proyectoNombre, autorNombre, titulo, descripcion, ticketURL) go func() { if err := app.Http.Mail.Send(adminEmail, subject, htmlBody, ""); err != nil { log.Printf("[Notif] Error enviando ticket nuevo a admin: %v", err) } }() } // SendTicketRespuestaPortalUser notifica al portal user que el admin respondió. func SendTicketRespuestaPortalUser(userEmail, userName, proyectoNombre, titulo, respuesta, ticketURL string) { subject := fmt.Sprintf("💬 Respuesta en tu ticket: %s", titulo) htmlBody := fmt.Sprintf(`
💬

Hay una respuesta en tu ticket

Proyecto: %s

Hola %s,

El equipo respondió tu ticket "%s":

%s
Ver mi ticket
`, proyectoNombre, userName, titulo, respuesta, ticketURL) go func() { if err := app.Http.Mail.Send(userEmail, subject, htmlBody, ""); err != nil { log.Printf("[Notif] Error enviando respuesta ticket a %s: %v", userEmail, err) } }() } // SendTicketRespuestaAdmin notifica al admin que el portal user respondió. func SendTicketRespuestaAdmin(adminEmail, proyectoNombre, autorNombre, titulo, respuesta, ticketURL string) { subject := fmt.Sprintf("💬 Respuesta de cliente en ticket: %s", titulo) htmlBody := fmt.Sprintf(`

💬 Respuesta de cliente

Proyecto: %s | Cliente: %s

En el ticket "%s":

%s
Ver ticket
`, proyectoNombre, autorNombre, titulo, respuesta, ticketURL) go func() { if err := app.Http.Mail.Send(adminEmail, subject, htmlBody, ""); err != nil { log.Printf("[Notif] Error enviando respuesta cliente a admin: %v", err) } }() } // SendTareaAsignadaEmail notifica al usuario asignado sobre una nueva tarea. func SendTareaAsignadaEmail(toEmail, toName, tareaTitle, prioridad, descripcion, tareaURL string) { subject := fmt.Sprintf("📋 Nueva tarea asignada: %s", tareaTitle) htmlBody := fmt.Sprintf(`
📋

Nueva tarea asignada

Prioridad: %s

Hola %s,

Se te asignó la siguiente tarea:

%s

%s

Ver tarea

© U-site — Panel de administración

`, prioridad, toName, tareaTitle, descripcion, tareaURL) go func() { if err := app.Http.Mail.Send(toEmail, subject, htmlBody, ""); err != nil { log.Printf("[Notif] Error enviando tarea asignada a %s: %v", toEmail, err) } }() } // SendTareaNotifAdmin notifica al admin sobre cambios en tareas (estado, comentarios). func SendTareaNotifAdmin(adminEmail, titulo, cuerpo, tareaURL string) { htmlBody := fmt.Sprintf(`

%s

%s

Ver tablero de tareas

© U-site — Panel de administración

`, titulo, cuerpo, tareaURL) go func() { if err := app.Http.Mail.Send(adminEmail, titulo, htmlBody, ""); err != nil { log.Printf("[Notif] Error enviando notif tarea a admin: %v", err) } }() } // SendFacturaSubidaPortalUser notifica a un portal user que tiene una nueva factura disponible. func SendFacturaSubidaPortalUser(toEmail, userName, clienteNombre, numero string, monto float64, moneda, portalURL string) { go func() { subject := fmt.Sprintf("Nueva factura disponible: %s", numero) htmlBody := fmt.Sprintf(`

🧾 Nueva factura disponible

Hola %s,

Tienes una nueva factura disponible para descargar:

Número%s
Monto%s %.2f
Ver en el portal

Este es un mensaje automático.

`, userName, numero, moneda, monto, portalURL) if err := app.Http.Mail.Send(toEmail, subject, htmlBody, ""); err != nil { log.Printf("[Notif] Error enviando factura_subida a %s: %v", toEmail, err) } }() }