const express = require('express');
const router = express.Router();

module.exports = (pool, query) => {
  /**
   * Handle email tracking for opens and clicks
   * GET /api/email/track
   * 
   * Query parameters:
   * - c: Campaign ID
   * - s: Subscriber ID
   * - t: Type of tracking (open, click)
   * - l: Link ID (only for click tracking)
   * - u: Original URL (only for click tracking, encoded)
   */
  router.get('/track', async (req, res, next) => {
    try {
      const { c: campaignId, s: subscriberId, t: type, l: linkId, u: encodedUrl } = req.query;
      
      // Validate required parameters
      if (!campaignId || !subscriberId || !type) {
        // For tracking pixels, return a 1x1 transparent GIF to avoid breaking email rendering
        if (type === 'open') {
          return sendTrackingPixel(res);
        }
        
        // For click tracking, redirect to homepage if parameters are invalid
        if (type === 'click' && encodedUrl) {
          return res.redirect(decodeURIComponent(encodedUrl));
        }
        
        return res.redirect('/');
      }
      
      // Process tracking event asynchronously (don't wait for DB operations)
      processTrackingEvent(campaignId, subscriberId, type, linkId, encodedUrl)
        .catch(err => console.error('Error processing tracking event:', err));
      
      // Respond based on tracking type
      if (type === 'open') {
        // For opens, return a 1x1 transparent GIF
        return sendTrackingPixel(res);
      } else if (type === 'click' && encodedUrl) {
        // For clicks, redirect to the original URL
        return res.redirect(decodeURIComponent(encodedUrl));
      } else {
        // Fallback to homepage
        return res.redirect('/');
      }
    } catch (error) {
      console.error('Tracking error:', error);
      
      // Always provide a response, even on error
      if (req.query.t === 'open') {
        return sendTrackingPixel(res);
      } else {
        return res.redirect('/');
      }
    }
  });
  
  /**
   * Process a tracking event and update subscriber activity
   * @param {string} campaignId - Campaign ID
   * @param {string} subscriberId - Subscriber ID
   * @param {string} type - Event type (open, click)
   * @param {string} linkId - Link ID for click events
   * @param {string} encodedUrl - Original URL for click events
   * @returns {Promise<void>}
   */
  async function processTrackingEvent(campaignId, subscriberId, type, linkId, encodedUrl) {
    try {
      // Get client IP and user agent
      const details = {};
      
      // Record the tracking event in subscriber_activity
      if (type === 'open') {
        // Check if an open has already been recorded for this subscriber/campaign
        const existingOpen = await query(
          `SELECT id FROM subscriber_activity 
           WHERE subscriber_id = $1 AND campaign_id = $2 AND type = 'open'
           LIMIT 1`,
          [subscriberId, campaignId]
        );
        
        // Only record first open to avoid duplicate counting
        if (existingOpen.rows.length === 0) {
          await query(
            `INSERT INTO subscriber_activity (subscriber_id, campaign_id, type, details)
             VALUES ($1, $2, 'open', $3)`,
            [subscriberId, campaignId, JSON.stringify(details)]
          );
          
          // Update subscriber's last_activity_at
          await query(
            `UPDATE subscribers SET last_activity_at = NOW() WHERE id = $1`,
            [subscriberId]
          );
        }
      } else if (type === 'click' && linkId) {
        // Record the click with the link ID
        await query(
          `INSERT INTO subscriber_activity (subscriber_id, campaign_id, type, link_id, url, details)
           VALUES ($1, $2, 'click', $3, $4, $5)`,
          [subscriberId, campaignId, linkId, decodeURIComponent(encodedUrl), JSON.stringify(details)]
        );
        
        // Update subscriber's last_activity_at
        await query(
          `UPDATE subscribers SET last_activity_at = NOW() WHERE id = $1`,
          [subscriberId]
        );
      }
    } catch (error) {
      console.error('Error processing tracking event:', error);
      // Don't throw - we want to fail silently for tracking
    }
  }
  
  /**
   * Send a 1x1 transparent GIF for tracking pixels
   * @param {Object} res - Express response object
   */
  function sendTrackingPixel(res) {
    // 1x1 transparent GIF in base64
    const transparentGif = Buffer.from('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', 'base64');
    
    res.set('Content-Type', 'image/gif');
    res.set('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
    res.set('Pragma', 'no-cache');
    res.set('Expires', '0');
    res.send(transparentGif);
  }
  
  return router;
};