/**
 * Newsletter Controller
 * Handles newsletter subscriptions and management
 */

const NewsletterSubscription = require('../models/NewsletterSubscription.model');
const logger = require('../utils/logger.util');

/**
 * Subscribe to newsletter (public)
 * POST /api/newsletter/subscribe
 */
exports.subscribe = async (req, res) => {
  try {
    const { email, name, source, interests } = req.body;

    // Validate email
    if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
      return res.status(400).json({
        success: false,
        error: 'Valid email address is required'
      });
    }

    // Capture metadata
    const metadata = {
      ip_address: req.ip || req.connection.remoteAddress,
      user_agent: req.get('user-agent'),
      referrer: req.get('referer')
    };

    const subscription = await NewsletterSubscription.subscribe({
      email,
      name,
      source: source || 'blog',
      interests: interests || [],
      ...metadata
    });

    logger.info('Newsletter subscription created', {
      email: subscription.email,
      source: subscription.source,
      verified: subscription.verified
    });

    // In a real system, send verification email here
    // For now, we'll auto-verify (remove this in production)
    await NewsletterSubscription.verify(subscription.verification_token);

    res.status(201).json({
      success: true,
      message: 'Successfully subscribed to newsletter',
      subscription: {
        email: subscription.email,
        verified: true
      }
    });
  } catch (subscribeError) {
    console.error('Newsletter subscription error:', subscribeError);
    res.status(500).json({
      success: false,
      error: 'Failed to subscribe to newsletter',
      details: process.env.NODE_ENV === 'development' ? subscribeError.message : undefined
    });
  }
};

/**
 * Verify email subscription
 * GET /api/newsletter/verify/:token
 */
exports.verify = async (req, res) => {
  try {
    const { token } = req.params;

    const verified = await NewsletterSubscription.verify(token);

    if (!verified) {
      return res.status(404).json({
        success: false,
        error: 'Invalid or expired verification token'
      });
    }

    res.json({
      success: true,
      message: 'Email verified successfully'
    });
  } catch (error) {
    logger.error('Newsletter verification error:', error);
    res.status(500).json({
      success: false,
      error: 'Failed to verify email'
    });
  }
};

/**
 * Unsubscribe from newsletter (public)
 * POST /api/newsletter/unsubscribe
 */
exports.unsubscribe = async (req, res) => {
  try {
    const { email, token } = req.body;

    if (!email && !token) {
      return res.status(400).json({
        success: false,
        error: 'Email or token is required'
      });
    }

    const unsubscribed = await NewsletterSubscription.unsubscribe(email, token);

    if (!unsubscribed) {
      return res.status(404).json({
        success: false,
        error: 'Subscription not found'
      });
    }

    logger.info('Newsletter unsubscribe', { email: email || 'via token' });

    res.json({
      success: true,
      message: 'Successfully unsubscribed from newsletter'
    });
  } catch (error) {
    logger.error('Newsletter unsubscribe error:', error);
    res.status(500).json({
      success: false,
      error: 'Failed to unsubscribe'
    });
  }
};

/**
 * Update subscription preferences (public)
 * PUT /api/newsletter/preferences
 */
exports.updatePreferences = async (req, res) => {
  try {
    const { email, name, interests } = req.body;

    if (!email) {
      return res.status(400).json({
        success: false,
        error: 'Email is required'
      });
    }

    const updated = await NewsletterSubscription.updatePreferences(email, {
      name,
      interests
    });

    if (!updated) {
      return res.status(404).json({
        success: false,
        error: 'Active subscription not found'
      });
    }

    res.json({
      success: true,
      message: 'Preferences updated successfully'
    });
  } catch (error) {
    logger.error('Newsletter preferences update error:', error);
    res.status(500).json({
      success: false,
      error: 'Failed to update preferences'
    });
  }
};

/**
 * Get newsletter statistics (admin only)
 * GET /api/admin/newsletter/stats
 */
exports.getStats = async (req, res) => {
  try {
    const stats = await NewsletterSubscription.getStats();

    res.json({
      success: true,
      stats
    });
  } catch (error) {
    logger.error('Newsletter stats error:', error);
    res.status(500).json({
      success: false,
      error: 'Failed to retrieve statistics'
    });
  }
};

/**
 * List all subscriptions (admin only)
 * GET /api/admin/newsletter/subscriptions
 */
exports.listSubscriptions = async (req, res) => {
  try {
    const {
      limit = 100,
      skip = 0,
      active = 'true',
      verified = null,
      source = null
    } = req.query;

    const options = {
      limit: parseInt(limit),
      skip: parseInt(skip),
      active: active === 'true',
      verified: verified === null ? null : verified === 'true',
      source: source || null
    };

    const subscriptions = await NewsletterSubscription.list(options);
    const total = await NewsletterSubscription.count({
      active: options.active,
      ...(options.verified !== null && { verified: options.verified }),
      ...(options.source && { source: options.source })
    });

    res.json({
      success: true,
      subscriptions,
      pagination: {
        total,
        limit: options.limit,
        skip: options.skip,
        has_more: skip + subscriptions.length < total
      }
    });
  } catch (error) {
    logger.error('Newsletter list error:', error);
    res.status(500).json({
      success: false,
      error: 'Failed to list subscriptions'
    });
  }
};

/**
 * Export subscriptions as CSV (admin only)
 * GET /api/admin/newsletter/export
 */
exports.exportSubscriptions = async (req, res) => {
  try {
    const { active = 'true' } = req.query;

    const subscriptions = await NewsletterSubscription.list({
      active: active === 'true',
      limit: 10000
    });

    // Generate CSV
    const csv = [
      'Email,Name,Source,Verified,Subscribed At',
      ...subscriptions.map(sub =>
        `${sub.email},"${sub.name || ''}",${sub.source},${sub.verified},${sub.subscribed_at.toISOString()}`
      )
    ].join('\n');

    res.setHeader('Content-Type', 'text/csv');
    res.setHeader('Content-Disposition', `attachment; filename="newsletter-subscriptions-${Date.now()}.csv"`);
    res.send(csv);
  } catch (error) {
    logger.error('Newsletter export error:', error);
    res.status(500).json({
      success: false,
      error: 'Failed to export subscriptions'
    });
  }
};

/**
 * Delete subscription (admin only)
 * DELETE /api/admin/newsletter/subscriptions/:id
 */
exports.deleteSubscription = async (req, res) => {
  try {
    const { id } = req.params;

    const deleted = await NewsletterSubscription.delete(id);

    if (!deleted) {
      return res.status(404).json({
        success: false,
        error: 'Subscription not found'
      });
    }

    logger.info('Newsletter subscription deleted', { id });

    res.json({
      success: true,
      message: 'Subscription deleted successfully'
    });
  } catch (error) {
    logger.error('Newsletter delete error:', error);
    res.status(500).json({
      success: false,
      error: 'Failed to delete subscription'
    });
  }
};
