package zw.qantra.tm.domain.services; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.http.HttpHeaders; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import jakarta.mail.internet.MimeMessage; import zw.qantra.tm.domain.dtos.sms.SmsApiResponse; import zw.qantra.tm.domain.dtos.sms.SmsBatchRequest; import zw.qantra.tm.domain.dtos.sms.SmsMessage; import zw.qantra.tm.rest.RestService; import java.io.BufferedReader; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.UUID; import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class NotificationService { private static final Logger logger = LoggerFactory.getLogger(NotificationService.class); private final RestService restService; private final JavaMailSender emailSender; @Value("${zss.sms.api.url}") private String smsApiUrl; @Value("${zss.sms.api.auth}") private String smsApiAuth; @Value("${sms.debug}") private Boolean smsDebug; @Async public void sendEmail(String to, String subject, String text) { sendEmailWithHtml(to, subject, text, null); } @Async public void sendEmailWithHtml(String to, String subject, String htmlContent) { sendEmailWithHtml(to, subject, null, htmlContent); } @Async public void sendEmailWithHtml(String to, String subject, String text, String htmlContent) { try { MimeMessage message = emailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); helper.setFrom("noreply@qantra.co.zw"); helper.setTo(to); helper.setSubject(subject); if (htmlContent != null) { helper.setText(text != null ? text : "", htmlContent); } else if (text != null) { helper.setText(text); } emailSender.send(message); logger.info("Email sent to {} - Subject: {}", to, subject); } catch (Exception e) { logger.error("Failed to send email to {}: {}", to, e.getMessage(), e); } } @Async public void sendOtpEmail(String to, String username, String otpCode) { try { // Load and populate the HTML template ClassPathResource resource = new ClassPathResource("templates/email-otp.html"); String htmlTemplate; try (BufferedReader reader = new BufferedReader( new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))) { htmlTemplate = reader.lines().collect(Collectors.joining("\n")); } // Simple placeholder replacement String htmlContent = htmlTemplate .replace("{{username}}", username != null ? username : "") .replace("{{otpCode}}", otpCode != null ? otpCode : ""); MimeMessage message = emailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); helper.setFrom("noreply@qantra.co.zw"); helper.setTo(to); helper.setSubject("Velocity Pay verification code"); helper.setText("Your Velocity Pay verification code is: " + otpCode, htmlContent); emailSender.send(message); logger.info("OTP email sent to {} for user: {}", to, username); } catch (Exception e) { logger.error("Failed to send OTP email to {}: {}", to, e.getMessage(), e); } } @Async public void sendSms(String to, String message) { if(smsDebug) { logger.info("Sending SMS to {}: {}", to, message); return; } try { SmsMessage smsMessage = SmsMessage.builder() .reference(UUID.randomUUID().toString()) .message(message) .msisdn(to) .build(); SmsBatchRequest batchRequest = SmsBatchRequest.builder() .batchReference(UUID.randomUUID().toString()) .smsList(Collections.singletonList(smsMessage)) .build(); HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", smsApiAuth); SmsApiResponse response = restService.postWithExternalAuth( smsApiUrl, batchRequest, headers, SmsApiResponse.class ); logger.info("SMS sent to {} - Status: {}, Result: {}", to, response.getStatus(), response.getResult()); } catch (Exception e) { logger.error("Failed to send SMS to {}: {}", to, e.getMessage(), e); } } }