import crypto from 'crypto';
export class CampaignService {
    db;
    constructor(db) {
        this.db = db;
    }
    createCampaign(data) {
        const id = crypto.randomUUID();
        this.db.prepare(`
      INSERT INTO email_campaigns (id, name, squad_name, subject, body_html, body_text, from_email, from_name)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `).run(id, data.name, data.squad_name ?? null, data.subject, data.body_html, data.body_text ?? null, data.from_email, data.from_name ?? null);
        return this.getCampaign(id);
    }
    getCampaign(id) {
        return this.db.prepare('SELECT * FROM email_campaigns WHERE id = ?').get(id);
    }
    listCampaigns(filters = {}) {
        const page = filters.page ?? 1;
        const limit = filters.limit ?? 50;
        const offset = (page - 1) * limit;
        const conditions = [];
        const params = [];
        if (filters.status) {
            conditions.push('status = ?');
            params.push(filters.status);
        }
        const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
        const total = this.db.prepare(`SELECT COUNT(*) as count FROM email_campaigns ${where}`).get(...params).count;
        const data = this.db.prepare(`SELECT * FROM email_campaigns ${where} ORDER BY created_at DESC LIMIT ? OFFSET ?`).all(...params, limit, offset);
        return { data, total };
    }
    enqueueCampaign(campaignId, filters) {
        const campaign = this.getCampaign(campaignId);
        if (!campaign || campaign.status !== 'draft')
            throw new Error('Campaign must be in draft status to enqueue');
        const conditions = ["l.status = 'active'"];
        const params = [];
        if (filters.tags?.length) {
            conditions.push(`EXISTS (SELECT 1 FROM lead_tags lt WHERE lt.lead_id = l.id AND lt.tag IN (${filters.tags.map(() => '?').join(',')}))`);
            params.push(...filters.tags);
        }
        if (filters.lists?.length) {
            conditions.push(`EXISTS (SELECT 1 FROM lead_lists ll WHERE ll.lead_id = l.id AND ll.list_name IN (${filters.lists.map(() => '?').join(',')}))`);
            params.push(...filters.lists);
        }
        const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
        const leads = this.db.prepare(`SELECT id, email FROM leads l ${where}`).all(...params);
        const insertStmt = this.db.prepare('INSERT INTO email_queue (id, campaign_id, lead_id, to_email) VALUES (?, ?, ?, ?)');
        const tx = this.db.transaction(() => {
            for (const lead of leads) {
                insertStmt.run(crypto.randomUUID(), campaignId, lead.id, lead.email);
            }
            this.db.prepare("UPDATE email_campaigns SET status = 'queued', total_recipients = ? WHERE id = ?").run(leads.length, campaignId);
        });
        tx();
    }
    startCampaign(campaignId) {
        const campaign = this.getCampaign(campaignId);
        if (!campaign || campaign.status !== 'queued')
            throw new Error('Campaign must be in queued status to start');
        if (campaign.total_recipients === 0)
            throw new Error('Campaign has no recipients');
        this.db.prepare("UPDATE email_campaigns SET status = 'sending', started_at = ? WHERE id = ?").run(new Date().toISOString(), campaignId);
    }
    pauseCampaign(campaignId) {
        const campaign = this.getCampaign(campaignId);
        if (!campaign || campaign.status !== 'sending')
            throw new Error('Campaign must be sending to pause');
        this.db.prepare("UPDATE email_campaigns SET status = 'paused' WHERE id = ?").run(campaignId);
    }
    resumeCampaign(campaignId) {
        const campaign = this.getCampaign(campaignId);
        if (!campaign || campaign.status !== 'paused')
            throw new Error('Campaign must be paused to resume');
        this.db.prepare("UPDATE email_campaigns SET status = 'sending' WHERE id = ?").run(campaignId);
    }
    cancelCampaign(campaignId) {
        const campaign = this.getCampaign(campaignId);
        if (!campaign || !['queued', 'sending', 'paused'].includes(campaign.status))
            throw new Error('Cannot cancel campaign in current status');
        this.db.prepare("UPDATE email_campaigns SET status = 'cancelled' WHERE id = ?").run(campaignId);
        this.db.prepare("DELETE FROM email_queue WHERE campaign_id = ? AND status = 'pending'").run(campaignId);
    }
    getCampaignStats(campaignId) {
        return this.getCampaign(campaignId);
    }
}
//# sourceMappingURL=campaign-service.js.map