const fs = require('fs').promises;
const path = require('path');

class EmailTemplateService {
    constructor() {
        this.templatesDir = path.join(__dirname, '../templates/email');
        this.cache = new Map();
    }

    async loadTemplate(templateName, type = 'html') {
        const cacheKey = `${templateName}.${type}`;
        
        // Check cache first
        if (this.cache.has(cacheKey)) {
            return this.cache.get(cacheKey);
        }

        try {
            const templatePath = path.join(this.templatesDir, `${templateName}.${type}`);
            const template = await fs.readFile(templatePath, 'utf-8');
            
            // Cache the template
            this.cache.set(cacheKey, template);
            
            return template;
        } catch (error) {
            console.error(`Failed to load email template ${templateName}.${type}:`, error);
            throw new Error(`Email template not found: ${templateName}.${type}`);
        }
    }

    processTemplate(template, variables) {
        if (!template) return '';
        
        let processed = template;
        
        // Handle conditional blocks {{#if VARIABLE}}...{{/if}}
        processed = processed.replace(/\{\{#if\s+(\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g, (match, varName, content) => {
            const value = variables[varName];
            // Check if value exists and is not empty string
            if (value !== undefined && value !== null && value !== '') {
                // Recursively process the content inside the conditional block
                return this.processTemplate(content, variables);
            }
            return '';
        });
        
        // Replace variables {{VARIABLE}}
        processed = processed.replace(/\{\{(\w+)\}\}/g, (match, varName) => {
            const value = variables[varName];
            // Return the value or empty string if undefined
            return value !== undefined && value !== null ? String(value) : '';
        });
        
        // Handle line breaks in MESSAGE field for HTML templates
        if (variables.MESSAGE && processed.includes('{{MESSAGE}}')) {
            processed = processed.replace(/\{\{MESSAGE\}\}/g, variables.MESSAGE.replace(/\n/g, '<br>'));
        }
        
        return processed;
    }

    async render(templateName, variables) {
        try {
            // Load both HTML and text versions
            const [htmlTemplate, textTemplate] = await Promise.all([
                this.loadTemplate(templateName, 'html'),
                this.loadTemplate(templateName, 'txt')
            ]);

            // Add default variables
            const defaultVariables = {
                APP_NAME: process.env.APP_NAME || 'BNKops Influence Campaign',
                TIMESTAMP: new Date().toLocaleString(),
                ...variables
            };

            // Use processTemplate which handles conditionals properly
            return {
                html: this.processTemplate(htmlTemplate, defaultVariables),
                text: this.processTemplate(textTemplate, defaultVariables)
            };
        } catch (error) {
            console.error('Failed to render email template:', error);
            throw error;
        }
    }

    // Get available template names
    async getAvailableTemplates() {
        try {
            const files = await fs.readdir(this.templatesDir);
            const templates = new Set();
            
            files.forEach(file => {
                const ext = path.extname(file);
                const name = path.basename(file, ext);
                if (ext === '.html' || ext === '.txt') {
                    templates.add(name);
                }
            });
            
            return Array.from(templates);
        } catch (error) {
            console.error('Failed to get available templates:', error);
            return [];
        }
    }

    // Clear template cache (useful for development)
    clearCache() {
        this.cache.clear();
        console.log('Email template cache cleared');
    }

    // Check if template exists
    async templateExists(templateName) {
        try {
            const htmlPath = path.join(this.templatesDir, `${templateName}.html`);
            const txtPath = path.join(this.templatesDir, `${templateName}.txt`);
            
            // Check if at least one format exists
            const [htmlExists, txtExists] = await Promise.all([
                fs.access(htmlPath).then(() => true).catch(() => false),
                fs.access(txtPath).then(() => true).catch(() => false)
            ]);
            
            return htmlExists || txtExists;
        } catch (error) {
            return false;
        }
    }
}

module.exports = new EmailTemplateService();