TemplateService.java 5.87 KB
package com.ecommerce.notification.service;

import com.ecommerce.notification.model.NotificationTemplate;
import com.ecommerce.notification.repository.NotificationTemplateRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class TemplateService {
    
    private final NotificationTemplateRepository templateRepository;
    private final ResourceLoader resourceLoader;
    
    public Map<String, Object> processTemplate(String templateName, String type, Map<String, Object> variables) {
        try {
            // First try to get template from database
            NotificationTemplate template = templateRepository.findByName(templateName)
                    .orElseThrow(() -> new RuntimeException("Template not found: " + templateName));
            
            if (!template.getIsActive()) {
                throw new RuntimeException("Template is not active: " + templateName);
            }
            
            String content = template.getContent();
            String subject = template.getSubject();
            
            // Process variables in content and subject
            if (variables != null) {
                content = processVariables(content, variables);
                if (subject != null) {
                    subject = processVariables(subject, variables);
                }
            }
            
            Map<String, Object> result = new HashMap<>();
            result.put("content", content);
            if (subject != null) {
                result.put("subject", subject);
            }
            
            return result;
            
        } catch (Exception e) {
            log.warn("Database template processing failed for {}: {}", templateName, e.getMessage());
            
            // Fallback to file-based templates
            return processFileTemplate(templateName, type, variables);
        }
    }
    
    private Map<String, Object> processFileTemplate(String templateName, String type, Map<String, Object> variables) {
        try {
            String templatePath = String.format("classpath:templates/%s/%s", 
                    type.toLowerCase(), templateName);
            
            Resource resource = resourceLoader.getResource(templatePath);
            String content = readResourceContent(resource);
            
            // Process variables in content
            if (variables != null) {
                content = processVariables(content, variables);
            }
            
            Map<String, Object> result = new HashMap<>();
            result.put("content", content);
            
            // For email templates, set a default subject
            if ("EMAIL".equalsIgnoreCase(type)) {
                result.put("subject", getDefaultSubject(templateName));
            }
            
            return result;
            
        } catch (Exception e) {
            log.error("File template processing failed for {}: {}", templateName, e.getMessage());
            throw new RuntimeException("Template processing failed: " + e.getMessage());
        }
    }
    
    private String processVariables(String template, Map<String, Object> variables) {
        String processed = template;
        
        for (Map.Entry<String, Object> entry : variables.entrySet()) {
            String placeholder = "{{" + entry.getKey() + "}}";
            String value = entry.getValue() != null ? entry.getValue().toString() : "";
            processed = processed.replace(placeholder, value);
        }
        
        return processed;
    }
    
    private String readResourceContent(Resource resource) throws IOException {
        try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) {
            return FileCopyUtils.copyToString(reader);
        }
    }
    
    private String getDefaultSubject(String templateName) {
        switch (templateName) {
            case "order-confirmation":
                return "Order Confirmation - Your Order has been Received";
            case "payment-success":
                return "Payment Successful - Thank You for Your Purchase";
            case "shipping-update":
                return "Shipping Update - Your Order is on the Way";
            case "password-reset":
                return "Password Reset Request";
            default:
                return "Notification from E-Commerce";
        }
    }
    
    public NotificationTemplate createTemplate(NotificationTemplate template) {
        if (templateRepository.findByName(template.getName()).isPresent()) {
            throw new RuntimeException("Template with name already exists: " + template.getName());
        }
        return templateRepository.save(template);
    }
    
    public NotificationTemplate updateTemplate(Long id, NotificationTemplate templateDetails) {
        NotificationTemplate template = templateRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Template not found with id: " + id));
        
        template.setName(templateDetails.getName());
        template.setType(templateDetails.getType());
        template.setChannel(templateDetails.getChannel());
        template.setSubject(templateDetails.getSubject());
        template.setContent(templateDetails.getContent());
        template.setVariables(templateDetails.getVariables());
        template.setIsActive(templateDetails.getIsActive());
        template.setDescription(templateDetails.getDescription());
        
        return templateRepository.save(template);
    }
}