"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var EmailService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.EmailService = void 0;
const common_1 = require("@nestjs/common");
const config_1 = require("@nestjs/config");
let EmailService = EmailService_1 = class EmailService {
    constructor(configService) {
        this.configService = configService;
        this.logger = new common_1.Logger(EmailService_1.name);
        this.isConfigured = false;
    }
    onModuleInit() {
        const emailConfig = this.configService.get('email');
        this.provider = emailConfig?.provider || 'sendgrid';
        this.fromEmail = emailConfig?.from || 'noreply@example.com';
        this.fromName = emailConfig?.fromName || 'Template SaaS';
        this.replyTo = emailConfig?.replyTo || '';
        this.sendgridApiKey = emailConfig?.sendgridApiKey || '';
        this.sesRegion = emailConfig?.sesRegion || 'us-east-1';
        this.sesAccessKeyId = emailConfig?.sesAccessKeyId || '';
        this.sesSecretAccessKey = emailConfig?.sesSecretAccessKey || '';
        this.smtpHost = emailConfig?.smtpHost || '';
        this.smtpPort = emailConfig?.smtpPort || 587;
        this.smtpUser = emailConfig?.smtpUser || '';
        this.smtpPassword = emailConfig?.smtpPassword || '';
        this.smtpSecure = emailConfig?.smtpSecure || false;
        this.isConfigured = this.checkConfiguration();
        if (this.isConfigured) {
            this.logger.log(`Email service initialized with provider: ${this.provider}`);
        }
        else {
            this.logger.warn('Email service not configured - emails will be logged only');
        }
    }
    checkConfiguration() {
        switch (this.provider) {
            case 'sendgrid':
                return !!this.sendgridApiKey;
            case 'ses':
                return !!(this.sesAccessKeyId && this.sesSecretAccessKey);
            case 'smtp':
                return !!(this.smtpHost && this.smtpUser && this.smtpPassword);
            default:
                return false;
        }
    }
    async sendEmail(dto) {
        this.logger.debug(`Sending email to ${dto.to.email}: ${dto.subject}`);
        if (!this.isConfigured) {
            this.logger.warn('Email not configured, logging email instead');
            this.logEmail(dto);
            return {
                success: true,
                messageId: `mock-${Date.now()}`,
                provider: this.provider,
            };
        }
        try {
            switch (this.provider) {
                case 'sendgrid':
                    return await this.sendViaSendGrid(dto);
                case 'ses':
                    return await this.sendViaSES(dto);
                case 'smtp':
                    return await this.sendViaSMTP(dto);
                default:
                    throw new Error(`Unknown email provider: ${this.provider}`);
            }
        }
        catch (error) {
            this.logger.error(`Failed to send email: ${error.message}`, error.stack);
            return {
                success: false,
                provider: this.provider,
                error: error.message,
            };
        }
    }
    async sendTemplateEmail(dto) {
        const { templateKey, variables, ...emailData } = dto;
        const template = await this.getTemplate(templateKey);
        if (!template) {
            return {
                success: false,
                provider: this.provider,
                error: `Template not found: ${templateKey}`,
            };
        }
        const renderedSubject = this.renderTemplate(template.subject, variables || {});
        const renderedHtml = this.renderTemplate(template.html, variables || {});
        const renderedText = template.text
            ? this.renderTemplate(template.text, variables || {})
            : undefined;
        return this.sendEmail({
            ...emailData,
            subject: renderedSubject,
            html: renderedHtml,
            text: renderedText,
        });
    }
    async sendBulkEmails(emails) {
        const results = [];
        const batchSize = 10;
        for (let i = 0; i < emails.length; i += batchSize) {
            const batch = emails.slice(i, i + batchSize);
            const batchResults = await Promise.all(batch.map((email) => this.sendEmail(email)));
            results.push(...batchResults);
        }
        return results;
    }
    async sendViaSendGrid(dto) {
        const message = {
            personalizations: [
                {
                    to: [{ email: dto.to.email, name: dto.to.name }],
                    ...(dto.cc?.length && {
                        cc: dto.cc.map((c) => ({ email: c.email, name: c.name })),
                    }),
                    ...(dto.bcc?.length && {
                        bcc: dto.bcc.map((b) => ({ email: b.email, name: b.name })),
                    }),
                },
            ],
            from: { email: this.fromEmail, name: this.fromName },
            ...(this.replyTo && { reply_to: { email: this.replyTo } }),
            subject: dto.subject,
            content: [],
        };
        if (dto.text) {
            message.content.push({ type: 'text/plain', value: dto.text });
        }
        if (dto.html) {
            message.content.push({ type: 'text/html', value: dto.html });
        }
        if (dto.attachments?.length) {
            message.attachments = dto.attachments.map((a) => ({
                content: a.content,
                filename: a.filename,
                type: a.contentType,
                disposition: 'attachment',
            }));
        }
        const response = await fetch('https://api.sendgrid.com/v3/mail/send', {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${this.sendgridApiKey}`,
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(message),
        });
        if (!response.ok) {
            const errorBody = await response.text();
            throw new Error(`SendGrid error: ${response.status} - ${errorBody}`);
        }
        const messageId = response.headers.get('x-message-id') || `sg-${Date.now()}`;
        return {
            success: true,
            messageId,
            provider: 'sendgrid',
        };
    }
    async sendViaSES(dto) {
        const endpoint = `https://email.${this.sesRegion}.amazonaws.com/v2/email/outbound-emails`;
        const body = {
            FromEmailAddress: `${this.fromName} <${this.fromEmail}>`,
            Destination: {
                ToAddresses: [`${dto.to.name || ''} <${dto.to.email}>`],
                ...(dto.cc?.length && {
                    CcAddresses: dto.cc.map((c) => `${c.name || ''} <${c.email}>`),
                }),
                ...(dto.bcc?.length && {
                    BccAddresses: dto.bcc.map((b) => `${b.name || ''} <${b.email}>`),
                }),
            },
            Content: {
                Simple: {
                    Subject: { Data: dto.subject },
                    Body: {
                        ...(dto.text && { Text: { Data: dto.text } }),
                        ...(dto.html && { Html: { Data: dto.html } }),
                    },
                },
            },
            ...(this.replyTo && { ReplyToAddresses: [this.replyTo] }),
        };
        const timestamp = new Date().toISOString().replace(/[:-]|\.\d{3}/g, '');
        const date = timestamp.slice(0, 8);
        const headers = {
            'Content-Type': 'application/json',
            'X-Amz-Date': timestamp,
            'Host': `email.${this.sesRegion}.amazonaws.com`,
        };
        this.logger.warn('AWS SES: Using simplified implementation - consider using @aws-sdk/client-sesv2');
        const response = await fetch(endpoint, {
            method: 'POST',
            headers: {
                ...headers,
                'X-Amz-Security-Token': '',
            },
            body: JSON.stringify(body),
        });
        if (!response.ok) {
            const errorBody = await response.text();
            throw new Error(`SES error: ${response.status} - ${errorBody}`);
        }
        const result = await response.json();
        return {
            success: true,
            messageId: result.MessageId || `ses-${Date.now()}`,
            provider: 'ses',
        };
    }
    async sendViaSMTP(dto) {
        this.logger.warn('SMTP: Requires nodemailer package - install with: npm install nodemailer');
        this.logEmail(dto);
        return {
            success: true,
            messageId: `smtp-${Date.now()}`,
            provider: 'smtp',
        };
    }
    async getTemplate(templateKey) {
        const templates = {
            welcome: {
                subject: 'Welcome to {{appName}}!',
                html: `
          <h1>Welcome, {{userName}}!</h1>
          <p>Thank you for joining {{appName}}. We're excited to have you on board.</p>
          <p>Get started by exploring our features.</p>
          <p>Best regards,<br/>The {{appName}} Team</p>
        `,
                text: 'Welcome, {{userName}}! Thank you for joining {{appName}}.',
            },
            password_reset: {
                subject: 'Reset your password - {{appName}}',
                html: `
          <h1>Password Reset Request</h1>
          <p>Hi {{userName}},</p>
          <p>We received a request to reset your password. Click the link below to proceed:</p>
          <p><a href="{{resetLink}}">Reset Password</a></p>
          <p>This link expires in {{expiresIn}}.</p>
          <p>If you didn't request this, please ignore this email.</p>
        `,
                text: 'Hi {{userName}}, Reset your password here: {{resetLink}}',
            },
            invitation: {
                subject: "You've been invited to {{tenantName}}",
                html: `
          <h1>You're Invited!</h1>
          <p>{{inviterName}} has invited you to join {{tenantName}} on {{appName}}.</p>
          <p><a href="{{inviteLink}}">Accept Invitation</a></p>
          <p>This invitation expires in {{expiresIn}}.</p>
        `,
                text: "You've been invited to {{tenantName}}. Accept here: {{inviteLink}}",
            },
            notification: {
                subject: '{{title}}',
                html: `
          <h2>{{title}}</h2>
          <p>{{message}}</p>
          {{#if actionUrl}}
          <p><a href="{{actionUrl}}">{{actionText}}</a></p>
          {{/if}}
        `,
                text: '{{title}}: {{message}}',
            },
        };
        return templates[templateKey] || null;
    }
    renderTemplate(template, variables) {
        let result = template;
        for (const [key, value] of Object.entries(variables)) {
            const regex = new RegExp(`\\{\\{${key}\\}\\}`, 'g');
            result = result.replace(regex, String(value ?? ''));
        }
        result = result.replace(/\{\{#if\s+(\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g, (_, condition, content) => {
            return variables[condition] ? content : '';
        });
        return result;
    }
    logEmail(dto) {
        this.logger.log('=== EMAIL (NOT SENT - NO PROVIDER CONFIGURED) ===');
        this.logger.log(`To: ${dto.to.email}`);
        if (dto.cc?.length) {
            this.logger.log(`CC: ${dto.cc.map((c) => c.email).join(', ')}`);
        }
        if (dto.bcc?.length) {
            this.logger.log(`BCC: ${dto.bcc.map((b) => b.email).join(', ')}`);
        }
        this.logger.log(`Subject: ${dto.subject}`);
        this.logger.log(`Body (text): ${dto.text?.substring(0, 200) || '(none)'}`);
        this.logger.log(`Body (html): ${dto.html?.substring(0, 200) || '(none)'}`);
        this.logger.log('================================================');
    }
    isEnabled() {
        return this.isConfigured;
    }
    getProvider() {
        return this.provider;
    }
};
exports.EmailService = EmailService;
exports.EmailService = EmailService = EmailService_1 = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [config_1.ConfigService])
], EmailService);
//# sourceMappingURL=email.service.js.map