// src/services/emailService.server.ts
/**
 * @file This service manages all email sending functionality using Nodemailer.
 * It is configured via environment variables and should only be used on the server.
 */
import nodemailer from 'nodemailer';
import type { Logger } from 'pino';
import { WatchedItemDeal } from '../types';

// 1. Create a Nodemailer transporter using SMTP configuration from environment variables.
// For development, you can use a service like Ethereal (https://ethereal.email/)
// or a local SMTP server like MailHog.
const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: parseInt(process.env.SMTP_PORT || '587', 10),
  secure: process.env.SMTP_SECURE === 'true', // true for 465, false for other ports
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});

interface EmailOptions {
  to: string;
  subject: string;
  text: string;
  html: string;
}

/**
 * Sends an email using the pre-configured transporter.
 * @param options The email options, including recipient, subject, and body.
 */
export const sendEmail = async (options: EmailOptions, logger: Logger) => {
  const mailOptions = {
    from: `"Flyer Crawler" <${process.env.SMTP_FROM_EMAIL}>`, // sender address
    to: options.to,
    subject: options.subject,
    text: options.text,
    html: options.html,
  };

  try {
    const info = await transporter.sendMail(mailOptions);
    logger.info({ to: options.to, subject: options.subject, messageId: info.messageId }, `Email sent successfully.`);
  } catch (error) {
    logger.error({ err: error, to: options.to, subject: options.subject }, 'Failed to send email.');
    // Re-throwing the error is important so the background job knows it failed.
    throw error;
  }
};

/**
 * Sends a notification email to a user about new deals on their watched items.
 * This function formats the deal information into a user-friendly email.
 * @param to The recipient's email address.
 * @param name The recipient's name (can be null).
 * @param deals An array of deals found for the user.
 */
export const sendDealNotificationEmail = async (to: string, name: string | null, deals: WatchedItemDeal[], logger: Logger) => {
  const recipientName = name || 'there';
  const subject = `New Deals Found on Your Watched Items!`;

  // Generate a simple list of deals for the email body
  const dealsListHtml = deals
    .map(
      deal =>
        `<li>
          <strong>${deal.item_name}</strong> is on sale for 
          <strong>$${(deal.best_price_in_cents / 100).toFixed(2)}</strong> 
          at ${deal.store_name}!
        </li>`
    )
    .join('');

  const html = `
    <h1>Hi ${recipientName},</h1>
    <p>We found some great deals on items you're watching:</p>
    <ul>
      ${dealsListHtml}
    </ul>
    <p>Check them out on the deals page!</p>
  `;

  const text = `Hi ${recipientName},\n\nWe found some great deals on items you're watching. Visit the deals page on the site to learn more.\n\nFlyer Crawler`;

  // Use the generic sendEmail function to send the composed email
  await sendEmail({
    to,
    subject,
    text,
    html,
  }, logger);
};

/**
 * Sends a password reset email to a user containing a link with their reset token.
 * @param to The recipient's email address.
 * @param token The unique password reset token.
 */
export const sendPasswordResetEmail = async (to: string, token: string, logger: Logger) => {
  const subject = 'Your Password Reset Request';
  // Construct the full reset URL using the frontend base URL from environment variables.
  const resetUrl = `${process.env.FRONTEND_URL}/reset-password?token=${token}`;

  const html = `
    <div style="font-family: sans-serif; padding: 20px;">
      <h2>Password Reset Request</h2>
      <p>You requested a password reset for your Flyer Crawler account.</p>
      <p>Please click the link below to set a new password. This link will expire in 1 hour.</p>
      <a href="${resetUrl}" style="background-color: #007bff; color: white; padding: 14px 25px; text-align: center; text-decoration: none; display: inline-block; border-radius: 5px;">Reset Your Password</a>
      <p style="margin-top: 20px;">If you did not request this, please ignore this email.</p>
    </div>
  `;

  const text = `Password Reset Request\n\nYou requested a password reset for your Flyer Crawler account.\nPlease use the following link to set a new password: ${resetUrl}\nThis link will expire in 1 hour.\n\nIf you did not request this, please ignore this email.`;

  // Use the generic sendEmail function to send the composed email.
  await sendEmail({
    to,
    subject,
    text,
    html,
  }, logger);
};

/**
 * Sends a welcome email to a new user.
 * @param to The recipient's email address.
 * @param name The recipient's name (can be null).
 */
export const sendWelcomeEmail = async (to: string, name: string | null, logger: Logger) => {
  const recipientName = name || 'there';
  const subject = 'Welcome to Flyer Crawler!';

  const html = `
    <div style="font-family: sans-serif; padding: 20px;">
      <h2>Welcome!</h2>
      <p>Hello ${recipientName},</p>
      <p>Thank you for joining Flyer Crawler. We're excited to have you on board.</p>
      <p>Start by uploading your first flyer to see how much you can save!</p>
    </div>
  `;

  const text = `Welcome!\n\nHello ${recipientName},\n\nThank you for joining Flyer Crawler. We're excited to have you on board.\n\nStart by uploading your first flyer to see how much you can save!`;

  await sendEmail({
    to,
    subject,
    text,
    html,
  }, logger);
};