"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.campaignEmailsService = void 0;
const client_1 = require("@prisma/client");
const database_1 = require("../../../config/database");
const error_handler_1 = require("../../../middleware/error-handler");
const email_queue_service_1 = require("../../../services/email-queue.service");
const metrics_1 = require("../../../utils/metrics");
const crm_activity_1 = require("../../../utils/crm-activity");
const group_service_1 = require("../../social/group.service");
const achievements_service_1 = require("../../social/achievements.service");
exports.campaignEmailsService = {
    async sendEmail(slug, data, senderIp) {
        const campaign = await database_1.prisma.campaign.findUnique({
            where: { slug },
            select: {
                id: true,
                slug: true,
                title: true,
                status: true,
                emailSubject: true,
                emailBody: true,
                allowSmtpEmail: true,
                allowMailtoLink: true,
                allowEmailEditing: true,
            },
        });
        if (!campaign) {
            throw new error_handler_1.AppError(404, 'Campaign not found', 'CAMPAIGN_NOT_FOUND');
        }
        if (campaign.status !== client_1.CampaignStatus.ACTIVE) {
            throw new error_handler_1.AppError(400, 'Campaign is not active', 'CAMPAIGN_NOT_ACTIVE');
        }
        if (data.emailMethod === client_1.EmailMethod.SMTP && !campaign.allowSmtpEmail) {
            throw new error_handler_1.AppError(400, 'SMTP email is not enabled for this campaign', 'SMTP_NOT_ALLOWED');
        }
        if (data.emailMethod === client_1.EmailMethod.MAILTO && !campaign.allowMailtoLink) {
            throw new error_handler_1.AppError(400, 'Mailto link is not enabled for this campaign', 'MAILTO_NOT_ALLOWED');
        }
        // Determine subject and body (custom only if campaign allows editing)
        const subject = (campaign.allowEmailEditing && data.customEmailSubject)
            ? data.customEmailSubject
            : campaign.emailSubject;
        const message = (campaign.allowEmailEditing && data.customEmailBody)
            ? data.customEmailBody
            : campaign.emailBody;
        const status = data.emailMethod === client_1.EmailMethod.SMTP
            ? client_1.CampaignEmailStatus.QUEUED
            : client_1.CampaignEmailStatus.CLICKED;
        const campaignEmail = await database_1.prisma.campaignEmail.create({
            data: {
                campaignId: campaign.id,
                campaignSlug: campaign.slug,
                userEmail: data.userEmail,
                userName: data.userName,
                userPostalCode: data.postalCode,
                recipientEmail: data.recipientEmail,
                recipientName: data.recipientName,
                recipientTitle: data.recipientTitle,
                recipientLevel: data.recipientLevel,
                emailMethod: data.emailMethod,
                subject,
                message,
                status,
                senderIp,
            },
        });
        if (data.emailMethod === client_1.EmailMethod.SMTP) {
            await email_queue_service_1.emailQueueService.addCampaignEmail({
                campaignEmailId: campaignEmail.id,
                recipientEmail: data.recipientEmail,
                recipientName: data.recipientName,
                recipientLevel: data.recipientLevel,
                userEmail: data.userEmail,
                userName: data.userName,
                postalCode: data.postalCode,
                subject,
                message,
                campaignTitle: campaign.title,
            });
        }
        (0, metrics_1.recordCampaignEmail)(campaign.id);
        // CRM activity (fire-and-forget)
        (0, crm_activity_1.recordCrmActivity)({
            email: data.userEmail,
            activityType: 'EMAIL_SENT',
            title: `Sent campaign email: ${campaign.title}`,
            metadata: { campaignId: campaign.id, campaignSlug: campaign.slug, recipientEmail: data.recipientEmail, emailMethod: data.emailMethod },
        }).catch(() => { });
        // Social group sync (fire-and-forget)
        group_service_1.groupService.syncCampaignTeam(campaign.id).catch(() => { });
        // Achievement check for registered users (fire-and-forget)
        database_1.prisma.user.findUnique({ where: { email: data.userEmail }, select: { id: true } })
            .then((user) => {
            if (user)
                achievements_service_1.achievementsService.checkAndUnlock(user.id, ['campaigns']).catch(() => { });
        })
            .catch(() => { });
        // Fire-and-forget: check campaign milestones
        Promise.resolve().then(() => __importStar(require('../../social/impact-stories.service'))).then(({ impactStoriesService }) => {
            impactStoriesService.checkMilestones(campaign.id).catch(() => { });
        }).catch(() => { });
        return {
            id: campaignEmail.id,
            status: campaignEmail.status,
            emailMethod: campaignEmail.emailMethod,
        };
    },
    async trackMailto(slug, data, senderIp) {
        const campaign = await database_1.prisma.campaign.findUnique({
            where: { slug },
            select: {
                id: true,
                slug: true,
                title: true,
                status: true,
                emailSubject: true,
                emailBody: true,
                allowMailtoLink: true,
            },
        });
        if (!campaign) {
            throw new error_handler_1.AppError(404, 'Campaign not found', 'CAMPAIGN_NOT_FOUND');
        }
        if (campaign.status !== client_1.CampaignStatus.ACTIVE) {
            throw new error_handler_1.AppError(400, 'Campaign is not active', 'CAMPAIGN_NOT_ACTIVE');
        }
        const campaignEmail = await database_1.prisma.campaignEmail.create({
            data: {
                campaignId: campaign.id,
                campaignSlug: campaign.slug,
                userEmail: data.userEmail,
                userName: data.userName,
                userPostalCode: data.postalCode,
                recipientEmail: data.recipientEmail,
                recipientName: data.recipientName,
                recipientTitle: data.recipientTitle,
                recipientLevel: data.recipientLevel,
                emailMethod: client_1.EmailMethod.MAILTO,
                subject: campaign.emailSubject,
                message: campaign.emailBody,
                status: client_1.CampaignEmailStatus.CLICKED,
                senderIp,
            },
        });
        // Social group sync (fire-and-forget)
        group_service_1.groupService.syncCampaignTeam(campaign.id).catch(() => { });
        // Fire-and-forget: check campaign milestones
        Promise.resolve().then(() => __importStar(require('../../social/impact-stories.service'))).then(({ impactStoriesService }) => {
            impactStoriesService.checkMilestones(campaign.id).catch(() => { });
        }).catch(() => { });
        return {
            id: campaignEmail.id,
            status: campaignEmail.status,
            emailMethod: campaignEmail.emailMethod,
        };
    },
    async listByCampaign(campaignId, filters) {
        const { page, limit, status, emailMethod } = filters;
        const skip = (page - 1) * limit;
        const where = { campaignId };
        if (status)
            where.status = status;
        if (emailMethod)
            where.emailMethod = emailMethod;
        const [emails, total] = await Promise.all([
            database_1.prisma.campaignEmail.findMany({
                where,
                skip,
                take: limit,
                orderBy: { sentAt: 'desc' },
                select: {
                    id: true,
                    userEmail: true,
                    userName: true,
                    userPostalCode: true,
                    recipientEmail: true,
                    recipientName: true,
                    recipientLevel: true,
                    emailMethod: true,
                    subject: true,
                    status: true,
                    sentAt: true,
                },
            }),
            database_1.prisma.campaignEmail.count({ where }),
        ]);
        return {
            emails,
            pagination: {
                page,
                limit,
                total,
                totalPages: Math.ceil(total / limit),
            },
        };
    },
    async getStats(campaignId) {
        const [totals, byMethod] = await Promise.all([
            database_1.prisma.campaignEmail.groupBy({
                by: ['status'],
                where: { campaignId },
                _count: true,
            }),
            database_1.prisma.campaignEmail.groupBy({
                by: ['emailMethod'],
                where: { campaignId },
                _count: true,
            }),
        ]);
        const stats = {
            total: 0,
            queued: 0,
            sent: 0,
            failed: 0,
            clicked: 0,
            smtpCount: 0,
            mailtoCount: 0,
        };
        for (const row of totals) {
            stats.total += row._count;
            const key = row.status.toLowerCase();
            if (key in stats)
                stats[key] = row._count;
        }
        for (const row of byMethod) {
            if (row.emailMethod === client_1.EmailMethod.SMTP)
                stats.smtpCount = row._count;
            if (row.emailMethod === client_1.EmailMethod.MAILTO)
                stats.mailtoCount = row._count;
        }
        return stats;
    },
};
//# sourceMappingURL=campaign-emails.service.js.map