const express = require('express');
const { v4: uuidv4 } = require('uuid');
const router = express.Router();
const { createObjectCsvWriter } = require('csv-writer');
const fs = require('fs');
const path = require('path');
const emailService = require('../services/emailService');

module.exports = (pool, query, authMiddleware) => {
  // Apply authentication middleware to all routes
  router.use(authMiddleware);
  
  /**
   * Get all email campaigns
   * GET /api/admin/email-campaigns
   */
  router.get('/', async (req, res, next) => {
    try {
      const { status } = req.query;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      // Prepare query conditions
      let condition = '';
      const params = [];
      
      if (status) {
        condition = 'WHERE status = $1';
        params.push(status);
      }
      
      // Get all campaigns with basic stats
      const campaignsQuery = `
        SELECT 
          ec.*,
          COALESCE(stats.recipient_count, 0) as recipient_count
        FROM email_campaigns ec
        LEFT JOIN (
          SELECT 
            campaign_id,
            COUNT(DISTINCT subscriber_id) as recipient_count
          FROM campaign_recipients
          GROUP BY campaign_id
        ) stats ON ec.id = stats.campaign_id
        ${condition}
        ORDER BY 
          CASE 
            WHEN ec.status = 'draft' THEN 1
            WHEN ec.status = 'scheduled' THEN 2
            WHEN ec.status = 'sending' THEN 3
            WHEN ec.status = 'sent' THEN 4
            ELSE 5
          END,
          ec.created_at DESC
      `;
      
      const result = await query(campaignsQuery, params);
      
      res.json(result.rows);
    } catch (error) {
      next(error);
    }
  });
  
  /**
   * Get a single email campaign
   * GET /api/admin/email-campaigns/:id
   */
  router.get('/:id', async (req, res, next) => {
    try {
      const { id } = req.params;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      // Get campaign with list info
      const campaignQuery = `
        SELECT 
          ec.*,
          ml.name as list_name,
          COUNT(cr.subscriber_id) as recipient_count
        FROM email_campaigns ec
        LEFT JOIN campaign_recipients cr ON ec.id = cr.campaign_id
        LEFT JOIN mailing_lists ml ON ec.list_ids[1] = ml.id
        WHERE ec.id = $1
        GROUP BY ec.id, ml.name
      `;
      
      const campaignResult = await query(campaignQuery, [id]);
      
      if (campaignResult.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Campaign not found'
        });
      }
      
      res.json(campaignResult.rows[0]);
    } catch (error) {
      next(error);
    }
  });
  
  /**
   * Create a new email campaign
   * POST /api/admin/email-campaigns
   */
  router.post('/', async (req, res, next) => {
    try {
      const { 
        name, subject, preheader, fromName, fromEmail, 
        content, design, listIds, status = 'draft' 
      } = req.body;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      // Validate required fields
      if (!name || !subject || !fromName || !fromEmail) {
        return res.status(400).json({
          error: true,
          message: 'Name, subject, from name, and from email are required'
        });
      }
      
      // Create new campaign
      const campaignId = uuidv4();
      const result = await query(
        `INSERT INTO email_campaigns (
           id, name, subject, preheader, from_name, from_email, 
           content, design, list_ids, status, created_by
         )
         VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
         RETURNING *`,
        [
          campaignId, name, subject, preheader, fromName, fromEmail, 
          content, design, listIds, status, req.user.id
        ]
      );
      
      res.status(201).json(result.rows[0]);
    } catch (error) {
      next(error);
    }
  });
  
  /**
   * Update an email campaign
   * PUT /api/admin/email-campaigns/:id
   */
  router.put('/:id', async (req, res, next) => {
    try {
      const { id } = req.params;
      const { 
        name, subject, preheader, fromName, fromEmail, 
        content, design, listIds, status 
      } = req.body;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      // Check if campaign exists
      const campaignCheck = await query(
        'SELECT status FROM email_campaigns WHERE id = $1',
        [id]
      );
      
      if (campaignCheck.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Campaign not found'
        });
      }
      
      // Cannot edit campaigns that are already sent
      const currentStatus = campaignCheck.rows[0].status;
      if (currentStatus === 'sent' || currentStatus === 'sending') {
        return res.status(400).json({
          error: true,
          message: 'Cannot edit a campaign that has already been sent or is currently sending'
        });
      }
      
      // Update campaign
      const result = await query(
        `UPDATE email_campaigns
         SET name = $1,
             subject = $2,
             preheader = $3,
             from_name = $4,
             from_email = $5,
             content = $6,
             design = $7,
             list_ids = $8,
             status = $9,
             updated_at = NOW()
         WHERE id = $10
         RETURNING *`,
        [
          name, subject, preheader, fromName, fromEmail, 
          content, design, listIds, status, id
        ]
      );
      
      res.json(result.rows[0]);
    } catch (error) {
      next(error);
    }
  });
  
  /**
   * Delete an email campaign
   * DELETE /api/admin/email-campaigns/:id
   */
  router.delete('/:id', async (req, res, next) => {
    try {
      const { id } = req.params;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      // Check if campaign exists
      const campaignCheck = await query(
        'SELECT status FROM email_campaigns WHERE id = $1',
        [id]
      );
      
      if (campaignCheck.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Campaign not found'
        });
      }
      
      // Cannot delete campaigns that have been sent
      const currentStatus = campaignCheck.rows[0].status;
      if (currentStatus === 'sent' || currentStatus === 'sending') {
        return res.status(400).json({
          error: true,
          message: 'Cannot delete a campaign that has already been sent or is currently sending'
        });
      }
      
      // Begin transaction
      const client = await pool.connect();
      
      try {
        await client.query('BEGIN');
        
        // Delete campaign recipients
        await client.query(
          'DELETE FROM campaign_recipients WHERE campaign_id = $1',
          [id]
        );
        
        // Delete campaign
        await client.query(
          'DELETE FROM email_campaigns WHERE id = $1',
          [id]
        );
        
        await client.query('COMMIT');
        
        res.json({
          success: true,
          message: 'Campaign deleted successfully'
        });
      } catch (error) {
        await client.query('ROLLBACK');
        throw error;
      } finally {
        client.release();
      }
    } catch (error) {
      next(error);
    }
  });
  
  /**
   * Duplicate an email campaign
   * POST /api/admin/email-campaigns/:id/duplicate
   */
  router.post('/:id/duplicate', async (req, res, next) => {
    try {
      const { id } = req.params;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      // Check if campaign exists
      const campaignCheck = await query(
        'SELECT * FROM email_campaigns WHERE id = $1',
        [id]
      );
      
      if (campaignCheck.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Campaign not found'
        });
      }
      
      const originalCampaign = campaignCheck.rows[0];
      
      // Create new campaign ID
      const newCampaignId = uuidv4();
      
      // Insert duplicated campaign
      const result = await query(
        `INSERT INTO email_campaigns (
           id, name, subject, preheader, from_name, from_email, 
           content, design, list_ids, status, created_by
         )
         VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, 'draft', $10)
         RETURNING *`,
        [
          newCampaignId,
          `Copy of ${originalCampaign.name}`,
          originalCampaign.subject,
          originalCampaign.preheader,
          originalCampaign.from_name,
          originalCampaign.from_email,
          originalCampaign.content,
          originalCampaign.design,
          originalCampaign.list_ids,
          req.user.id
        ]
      );
      
      res.status(201).json(result.rows[0]);
    } catch (error) {
      next(error);
    }
  });
  
  /**
   * Preview/send test email
   * POST /api/admin/email-campaigns/:id/preview
   */
  router.post('/:id/preview', async (req, res, next) => {
    try {
      const { id } = req.params;
      const { email } = req.body;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      if (!email) {
        return res.status(400).json({
          error: true,
          message: 'Email address is required'
        });
      }
      
      // Get campaign details
      const campaignQuery = `
        SELECT * FROM email_campaigns WHERE id = $1
      `;
      
      const campaignResult = await query(campaignQuery, [id]);
      
      if (campaignResult.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Campaign not found'
        });
      }
      
      const campaign = campaignResult.rows[0];
      // Send test email with emailService
      try {
        await emailService.sendTestEmail({
          to: email,
          subject: `[TEST] ${campaign.subject}`,
          preheader: campaign.preheader,
          from: `${campaign.from_name} <${campaign.from_email}>`,
          content: campaign.content
        });
        
        res.json({
          success: true,
          message: `Test email sent to ${email}`
        });
      } catch (error) {
        return res.status(500).json({
          error: true,
          message: `Failed to send test email: ${error.message}`
        });
      }
    } catch (error) {
      next(error);
    }
  });
  
/**
 * Send campaign immediately
 * POST /api/admin/email-campaigns/:id/send
 */
  router.post('/:id/send', async (req, res, next) => {
    try {
      const { id } = req.params;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      // Get campaign details
      const campaignQuery = `
        SELECT * FROM email_campaigns WHERE id = $1
      `;
      
      const campaignResult = await query(campaignQuery, [id]);
      
      if (campaignResult.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Campaign not found'
        });
      }
      
      const campaign = campaignResult.rows[0];
      
      // Ensure campaign is in a valid state for sending
      if (campaign.status !== 'draft' && campaign.status !== 'scheduled') {
        return res.status(400).json({
          error: true,
          message: `Cannot send campaign with status "${campaign.status}"`
        });
      }
      
      // Begin transaction
      const client = await pool.connect();
      
      try {
        await client.query('BEGIN');
        
        // Update campaign status
        await client.query(
          `UPDATE email_campaigns
          SET status = 'sending',
              sent_at = NOW(),
              updated_at = NOW()
          WHERE id = $1`,
          [id]
        );
        
        // Get recipients from mailing lists
        if (!campaign.list_ids || campaign.list_ids.length === 0) {
          await client.query('ROLLBACK');
          return res.status(400).json({
            error: true,
            message: 'Campaign has no mailing lists selected'
          });
        }
        
        // Prepare the query parameters for the list IDs
        const listIdParams = campaign.list_ids;
        const placeholders = listIdParams.map((_, i) => `$${i + 1}`).join(',');
        
        // Get active subscribers from selected mailing lists
        const subscribersQuery = `
          SELECT DISTINCT
            s.id,
            s.email,
            s.first_name,
            s.last_name
          FROM subscribers s
          JOIN mailing_list_subscribers ms ON s.id = ms.subscriber_id
          WHERE ms.list_id IN (${placeholders})
          AND s.status = 'active'
        `;
        
        const subscribersResult = await client.query(subscribersQuery, listIdParams);
        const subscribers = subscribersResult.rows;
        
        if (subscribers.length === 0) {
          await client.query('ROLLBACK');
          return res.status(400).json({
            error: true,
            message: 'Selected mailing lists have no active subscribers'
          });
        }
        
        // Add recipients to campaign_recipients table
        for (const subscriber of subscribers) {
          await client.query(
            `INSERT INTO campaign_recipients (campaign_id, subscriber_id)
            VALUES ($1, $2)
            ON CONFLICT (campaign_id, subscriber_id) DO NOTHING`,
            [id, subscriber.id]
          );
        }
        
        await client.query('COMMIT');
        
        // Now send the actual emails using a background process
        // We'll update the campaign status after all emails have been sent
        sendCampaignEmails(id, campaign, subscribers).then(async () => {
          // Update campaign status to sent after all emails have been processed
          await query(
            `UPDATE email_campaigns
            SET status = 'sent',
                updated_at = NOW()
            WHERE id = $1`,
            [id]
          );
          console.log(`Campaign ${id} completed sending to all recipients`);
        }).catch(err => {
          console.error(`Error sending campaign ${id}:`, err);
        });
        res.json({
          success: true,
          message: `Campaign scheduled for sending to ${subscribers.length} recipients`,
          id
        });
      } catch (error) {
        await client.query('ROLLBACK');
        throw error;
      } finally {
        client.release();
      }
    } catch (error) {
      next(error);
    }
  });

  /**
   * Helper function to send campaign emails to all subscribers
   * This runs asynchronously after the HTTP response has been sent
   * 
   * @param {string} campaignId - The campaign ID
   * @param {Object} campaign - The campaign object
   * @param {Array} subscribers - Array of subscriber objects
   * @returns {Promise<void>}
   */
  async function sendCampaignEmails(campaignId, campaign, subscribers) {
    // Use a smaller batch size to avoid overwhelming the email server
    const batchSize = 20;
    const totalSubscribers = subscribers.length;
    let processed = 0;
    
    try {
      // Process subscribers in batches
      for (let i = 0; i < totalSubscribers; i += batchSize) {
        const batch = subscribers.slice(i, i + batchSize);
        
        // Send emails in parallel within each batch
        await Promise.all(batch.map(async (subscriber) => {
          try {
            let personalizedContent = personalizeContent(campaign.content, subscriber);
            let personalizedSubject = personalizeContent(campaign.subject, subscriber);
            let personalizedPreheader = campaign.preheader ? personalizeContent(campaign.preheader, subscriber) : '';
            
            await emailService.sendCampaignEmail({
              to: subscriber.email,
              subject: personalizedSubject,
              preheader: personalizedPreheader,
              from: `${campaign.from_name} <${campaign.from_email}>`,
              content: personalizedContent,
              campaignId: campaignId,
              subscriberId: subscriber.id
            });
            
            // Log email sending activity
            await query(
              `INSERT INTO subscriber_activity (subscriber_id, campaign_id, type)
              VALUES ($1, $2, 'sent')`,
              [subscriber.id, campaignId]
            );
            
            processed++;
            
            // Log progress periodically
            if (processed % 50 === 0 || processed === totalSubscribers) {
              console.log(`Campaign ${campaignId}: ${processed}/${totalSubscribers} emails sent`);
            }
          } catch (error) {
            console.error(`Error sending email to ${subscriber.email}:`, error);
            
            // Log error in subscriber activity
            try {
              await query(
                `INSERT INTO subscriber_activity (subscriber_id, campaign_id, type, details)
                VALUES ($1, $2, 'error', $3)`,
                [subscriber.id, campaignId, error.message.substring(0, 255)]
              );
            } catch (logError) {
              console.error('Error logging subscriber activity:', logError);
            }
          }
        }));
        
        // Add a small delay between batches to avoid rate limiting
        if (i + batchSize < totalSubscribers) {
          await new Promise(resolve => setTimeout(resolve, 1000));
        }
      }
      
      console.log(`Campaign ${campaignId} completed: ${processed}/${totalSubscribers} emails sent successfully`);
      return processed;
    } catch (error) {
      console.error(`Error sending campaign ${campaignId}:`, error);
      throw error;
    }
  }
  
  /**
   * Schedule campaign for later
   * POST /api/admin/email-campaigns/:id/schedule
   */
  router.post('/:id/schedule', async (req, res, next) => {
    try {
      const { id } = req.params;
      const { scheduledDate } = req.body;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      if (!scheduledDate) {
        return res.status(400).json({
          error: true,
          message: 'Scheduled date is required'
        });
      }
      
      // Validate date is in the future
      const scheduleTime = new Date(scheduledDate);
      const now = new Date();
      
      if (scheduleTime <= now) {
        return res.status(400).json({
          error: true,
          message: 'Scheduled date must be in the future'
        });
      }
      
      // Get campaign details
      const campaignQuery = `
        SELECT * FROM email_campaigns WHERE id = $1
      `;
      
      const campaignResult = await query(campaignQuery, [id]);
      
      if (campaignResult.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Campaign not found'
        });
      }
      
      const campaign = campaignResult.rows[0];
      
      // Ensure campaign is in a valid state for scheduling
      if (campaign.status !== 'draft' && campaign.status !== 'scheduled') {
        return res.status(400).json({
          error: true,
          message: `Cannot schedule campaign with status "${campaign.status}"`
        });
      }
      
      // Update campaign
      const result = await query(
        `UPDATE email_campaigns
         SET status = 'scheduled',
             scheduled_for = $1,
             updated_at = NOW()
         WHERE id = $2
         RETURNING *`,
        [scheduleTime, id]
      );
      
      res.json({
        success: true,
        message: `Campaign scheduled for ${scheduleTime.toISOString()}`,
        campaign: result.rows[0]
      });
    } catch (error) {
      next(error);
    }
  });
  
  /**
   * Get campaign analytics
   * GET /api/admin/email-campaigns/:id/analytics
   */
  router.get('/:id/analytics', async (req, res, next) => {
    try {
      const { id } = req.params;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      // Check if campaign exists
      const campaignCheck = await query(
        'SELECT id FROM email_campaigns WHERE id = $1',
        [id]
      );
      
      if (campaignCheck.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Campaign not found'
        });
      }
      
      // Get campaign recipients count
      const recipientsQuery = `
        SELECT COUNT(*) as sent
        FROM campaign_recipients
        WHERE campaign_id = $1
      `;
      
      const recipientsResult = await query(recipientsQuery, [id]);
      const sent = parseInt(recipientsResult.rows[0].sent, 10);
      
      // Get delivery stats
      const deliveryQuery = `
        SELECT
          COUNT(*) FILTER (WHERE a.type = 'bounce') as bounced,
          COUNT(*) FILTER (WHERE a.type = 'sent') as delivered
        FROM campaign_recipients cr
        LEFT JOIN subscriber_activity a 
          ON cr.subscriber_id = a.subscriber_id 
          AND a.campaign_id = cr.campaign_id
        WHERE cr.campaign_id = $1
      `;
      
      const deliveryResult = await query(deliveryQuery, [id]);
      const bounced = parseInt(deliveryResult.rows[0].bounced, 10);
      const delivered = sent - bounced; // In reality, delivered would be from webhooks
      
      // Get engagement stats
      const engagementQuery = `
        SELECT
          COUNT(DISTINCT subscriber_id) FILTER (WHERE type = 'open') as opened,
          COUNT(DISTINCT subscriber_id) FILTER (WHERE type = 'click') as clicked,
          COUNT(DISTINCT subscriber_id) FILTER (WHERE type = 'unsubscribe') as unsubscribed
        FROM subscriber_activity
        WHERE campaign_id = $1
      `;
      
      const engagementResult = await query(engagementQuery, [id]);
      const opened = parseInt(engagementResult.rows[0].opened, 10);
      const clicked = parseInt(engagementResult.rows[0].clicked, 10);
      const unsubscribed = parseInt(engagementResult.rows[0].unsubscribed, 10);
      
      // Get link performance
      const linksQuery = `
        SELECT
          l.id,
          l.url,
          l.text,
          COUNT(a.id) as clicks,
          COUNT(DISTINCT a.subscriber_id) as unique_clicks
        FROM campaign_links l
        LEFT JOIN subscriber_activity a 
          ON l.id = a.link_id 
          AND a.type = 'click'
        WHERE l.campaign_id = $1
        GROUP BY l.id, l.url, l.text
        ORDER BY unique_clicks DESC
      `;
      
      const linksResult = await query(linksQuery, [id]);
      
      // Get opens by hour (for graphing)
      const opensByHourQuery = `
        SELECT
          DATE_TRUNC('hour', timestamp) as hour,
          COUNT(*) as opens
        FROM subscriber_activity
        WHERE campaign_id = $1 AND type = 'open'
        GROUP BY hour
        ORDER BY hour
      `;
      
      const opensByHourResult = await query(opensByHourQuery, [id]);
      
      res.json({
        sent,
        delivered,
        bounced,
        opened,
        clicked,
        unsubscribed,
        links: linksResult.rows,
        opens_by_hour: opensByHourResult.rows
      });
    } catch (error) {
      next(error);
    }
  });
  
  /**
   * Get campaign subscriber activity
   * GET /api/admin/email-campaigns/:id/activity
   */
  router.get('/:id/activity', async (req, res, next) => {
    try {
      const { id } = req.params;
      const { page = 0, pageSize = 25, search = '', type } = req.query;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      // Check if campaign exists
      const campaignCheck = await query(
        'SELECT id FROM email_campaigns WHERE id = $1',
        [id]
      );
      
      if (campaignCheck.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Campaign not found'
        });
      }
      
      // Prepare query conditions
      const conditions = ['a.campaign_id = $1'];
      const queryParams = [id];
      let paramIndex = 2;
      
      if (search) {
        conditions.push(`(
          s.email ILIKE ${paramIndex} OR
          s.first_name ILIKE ${paramIndex} OR
          s.last_name ILIKE ${paramIndex}
        )`);
        queryParams.push(`%${search}%`);
        paramIndex++;
      }
      
      if (type && type !== 'all') {
        conditions.push(`a.type = ${paramIndex}`);
        queryParams.push(type);
        paramIndex++;
      }
      
      // Build WHERE clause
      const whereClause = conditions.length > 0 
        ? `WHERE ${conditions.join(' AND ')}` 
        : '';
      
      // Get total count
      const countQuery = `
        SELECT COUNT(*) as total
        FROM subscriber_activity a
        JOIN subscribers s ON a.subscriber_id = s.id
        ${whereClause}
      `;
      
      const countResult = await query(countQuery, queryParams);
      const totalCount = parseInt(countResult.rows[0].total, 10);
      
      // Get activity with pagination
      const offset = page * pageSize;
      const activityQuery = `
        SELECT 
          a.id,
          a.type,
          a.timestamp,
          a.details,
          a.url,
          s.email,
          s.first_name,
          s.last_name
        FROM subscriber_activity a
        JOIN subscribers s ON a.subscriber_id = s.id
        ${whereClause}
        ORDER BY a.timestamp DESC
        LIMIT ${paramIndex} OFFSET ${paramIndex + 1}
      `;
      
      queryParams.push(parseInt(pageSize, 10), offset);
      console.log("queryParams", queryParams)
      console.log("activityQuery", activityQuery)
      const activityResult = await query(activityQuery, queryParams);
      
      res.json({
        activities: activityResult.rows,
        totalCount,
        page: parseInt(page, 10),
        pageSize: parseInt(pageSize, 10)
      });
    } catch (error) {
      next(error);
    }
  });
  
  /**
   * Export campaign report
   * GET /api/admin/email-campaigns/:id/export
   */
  router.get('/:id/export', async (req, res, next) => {
    try {
      const { id } = req.params;
      
      if (!req.user.is_admin) {
        return res.status(403).json({
          error: true,
          message: 'Admin access required'
        });
      }
      
      // Check if campaign exists
      const campaignCheck = await query(
        'SELECT name FROM email_campaigns WHERE id = $1',
        [id]
      );
      
      if (campaignCheck.rows.length === 0) {
        return res.status(404).json({
          error: true,
          message: 'Campaign not found'
        });
      }
      
      const campaignName = campaignCheck.rows[0].name;
      
      // Get all subscriber activity for this campaign
      const activityQuery = `
        SELECT 
          s.email,
          s.first_name,
          s.last_name,
          a.type,
          a.timestamp,
          a.details,
          a.url
        FROM subscriber_activity a
        JOIN subscribers s ON a.subscriber_id = s.id
        WHERE a.campaign_id = $1
        ORDER BY s.email, a.timestamp
      `;
      
      const activityResult = await query(activityQuery, [id]);
      const activities = activityResult.rows;
      
      // Create a temp file for CSV
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
      const fileName = `campaign-report-${campaignName.replace(/[^a-z0-9]/gi, '-').toLowerCase()}-${timestamp}.csv`;
      const filePath = path.join(__dirname, '../uploads/temp', fileName);
      
      // Create CSV writer
      const csvWriter = createObjectCsvWriter({
        path: filePath,
        header: [
          { id: 'email', title: 'Email' },
          { id: 'first_name', title: 'First Name' },
          { id: 'last_name', title: 'Last Name' },
          { id: 'type', title: 'Activity Type' },
          { id: 'timestamp', title: 'Timestamp' },
          { id: 'details', title: 'Details' },
          { id: 'url', title: 'URL' }
        ]
      });
      
      // Format dates in the data
      const formattedActivities = activities.map(activity => ({
        ...activity,
        timestamp: activity.timestamp ? new Date(activity.timestamp).toISOString() : ''
      }));
      
      // Write to CSV
      await csvWriter.writeRecords(formattedActivities);
      
      // Send file and delete after sending
      res.download(filePath, fileName, (err) => {
        // Delete the temp file after sending
        fs.unlink(filePath, (unlinkErr) => {
          if (unlinkErr) console.error('Error deleting temp file:', unlinkErr);
        });
        
        if (err) {
          console.error('Error sending file:', err);
          if (!res.headersSent) {
            res.status(500).json({
              error: true,
              message: 'Error sending file'
            });
          }
        }
      });
    } catch (error) {
      next(error);
    }
  });
  
  return router;
};


/**
 * Replace personalization variables in content
 * 
 * @param {string} content - The email content
 * @param {Object} subscriber - The subscriber object
 * @returns {string} - Content with variables replaced
 */
function personalizeContent(content, subscriber) {
  if (!content) return '';
  
  let personalized = content;
  
  if (personalized.includes('{{first_name}}')) {
    personalized = personalized.replace(/{{first_name}}/g, subscriber.first_name || '');
  }
  
  if (personalized.includes('{{last_name}}')) {
    personalized = personalized.replace(/{{last_name}}/g, subscriber.last_name || '');
  }
  
  if (personalized.includes('{{email}}')) {
    personalized = personalized.replace(/{{email}}/g, subscriber.email || '');
  }
  
  return personalized;
}