import jwt from 'jsonwebtoken';
export function processSnsNotification(db, notification) {
    const messageId = notification.mail?.messageId;
    if (!messageId)
        return;
    const queueItem = db.prepare('SELECT id, campaign_id, lead_id, status FROM email_queue WHERE ses_message_id = ?').get(messageId);
    if (!queueItem)
        return;
    const type = notification.notificationType;
    if (type === 'Bounce') {
        if (queueItem.status === 'bounced')
            return; // idempotent
        db.transaction(() => {
            db.prepare("UPDATE email_queue SET status = 'bounced' WHERE id = ?").run(queueItem.id);
            db.prepare('UPDATE email_campaigns SET bounce_count = bounce_count + 1 WHERE id = ?').run(queueItem.campaign_id);
            if (queueItem.lead_id) {
                db.prepare("UPDATE leads SET status = 'bounced', updated_at = ? WHERE id = ?").run(new Date().toISOString(), queueItem.lead_id);
            }
        })();
    }
    else if (type === 'Complaint') {
        if (queueItem.status === 'complained')
            return;
        db.transaction(() => {
            db.prepare("UPDATE email_queue SET status = 'complained' WHERE id = ?").run(queueItem.id);
            db.prepare('UPDATE email_campaigns SET complaint_count = complaint_count + 1 WHERE id = ?').run(queueItem.campaign_id);
            if (queueItem.lead_id) {
                db.prepare("UPDATE leads SET status = 'complained', updated_at = ? WHERE id = ?").run(new Date().toISOString(), queueItem.lead_id);
            }
        })();
    }
    // Delivery notifications are ignored (optional metric)
}
export async function snsWebhookRoutes(app, opts) {
    const { db, jwtSecret } = opts;
    // SNS webhook — public, no auth
    app.post('/api/email/sns', async (request, reply) => {
        const body = request.body;
        // Handle subscription confirmation
        if (body.Type === 'SubscriptionConfirmation' && body.SubscribeURL) {
            try {
                await fetch(body.SubscribeURL);
            }
            catch { /* ignore */ }
            return reply.send({ ok: true });
        }
        // Process notification
        if (body.Type === 'Notification') {
            try {
                const message = typeof body.Message === 'string' ? JSON.parse(body.Message) : body.Message;
                processSnsNotification(db, message);
            }
            catch { /* ignore malformed */ }
        }
        return reply.send({ ok: true });
    });
    // Unsubscribe — public, token-based
    app.get('/api/email/unsubscribe/:token', async (request, reply) => {
        try {
            const decoded = jwt.verify(request.params.token, jwtSecret);
            if (decoded.action !== 'unsubscribe' || !decoded.email) {
                return reply.status(400).send({ error: 'Invalid token' });
            }
            db.prepare("UPDATE leads SET status = 'unsubscribed', updated_at = ? WHERE email = ?").run(new Date().toISOString(), decoded.email);
            db.prepare("DELETE FROM email_queue WHERE lead_id = (SELECT id FROM leads WHERE email = ?) AND status = 'pending'").run(decoded.email);
            return reply.type('text/html').send('<html><body><h2>You have been unsubscribed.</h2><p>You will no longer receive emails from us.</p></body></html>');
        }
        catch {
            return reply.status(400).send({ error: 'Invalid or expired token' });
        }
    });
}
//# sourceMappingURL=sns-webhook.js.map