const { SESClient, SendEmailCommand } = require("@aws-sdk/client-ses");
const fs = require("fs").promises;
const path = require("path");

let sesClient = null;

/**
 * Get or create an SES client.
 * Reuses client across Lambda invocations for better performance.
 */
function getSESClient() {
  if (!sesClient) {
    sesClient = new SESClient({
      region: process.env.AWS_REGION || "us-east-1",
    });
  }
  return sesClient;
}

/**
 * Convert HTML to plain text for email fallback.
 * @param {string} html - HTML content to convert
 * @returns {string} Plain text version
 */
function htmlToPlainText(html) {
  return html
    .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "")
    .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "")
    .replace(/<br\s*\/?>/gi, "\n")
    .replace(/<\/p>/gi, "\n\n")
    .replace(/<\/div>/gi, "\n")
    .replace(/<\/li>/gi, "\n")
    .replace(/<\/h[1-6]>/gi, "\n\n")
    .replace(/<li>/gi, "- ")
    .replace(/<[^>]+>/g, "")
    .replace(/&nbsp;/g, " ")
    .replace(/&amp;/g, "&")
    .replace(/&lt;/g, "<")
    .replace(/&gt;/g, ">")
    .replace(/&quot;/g, '"')
    .replace(/&#39;/g, "'")
    .replace(/\n\s*\n\s*\n/g, "\n\n")
    .trim();
}

/**
 * Render a template by replacing {{variable}} placeholders with values.
 * @param {string} template - Template string with {{placeholders}}
 * @param {Object} variables - Key-value pairs to substitute
 * @returns {string} Rendered template
 */
function renderTemplate(template, variables = {}) {
  let rendered = template;

  Object.keys(variables).forEach((key) => {
    const regex = new RegExp(`{{${key}}}`, "g");
    rendered = rendered.replace(regex, variables[key] ?? "");
  });

  return rendered;
}

/**
 * Load a template file from disk.
 * @param {string} templatePath - Absolute path to the template file
 * @returns {Promise<string>} Template content
 */
async function loadTemplate(templatePath) {
  try {
    return await fs.readFile(templatePath, "utf-8");
  } catch (error) {
    console.error(JSON.stringify({
      level: "error",
      message: "Failed to load email template",
      templatePath,
      error: error.message,
    }));
    throw error;
  }
}

/**
 * Send an email using AWS SES.
 * @param {string|string[]} to - Recipient email address(es)
 * @param {string} subject - Email subject line
 * @param {string} htmlBody - HTML content of the email
 * @param {string|null} textBody - Plain text content (auto-generated if not provided)
 * @returns {Promise<{success: boolean, messageId?: string, error?: string}>}
 */
async function sendEmail(to, subject, htmlBody, textBody = null) {
  // Check if email sending is enabled
  if (process.env.EMAIL_ENABLED !== "true") {
    console.log(JSON.stringify({
      level: "info",
      message: "Email sending disabled, skipping",
      to,
      subject,
    }));
    return { success: true, messageId: "disabled" };
  }

  const client = getSESClient();

  // Auto-generate plain text from HTML if not provided
  const plainText = textBody || htmlToPlainText(htmlBody);

  // Build sender address with friendly name
  const fromName = process.env.SES_FROM_NAME || "Village Share";
  const fromEmail = process.env.SES_FROM_EMAIL;

  if (!fromEmail) {
    throw new Error("SES_FROM_EMAIL environment variable is required");
  }

  const source = `${fromName} <${fromEmail}>`;

  const params = {
    Source: source,
    Destination: {
      ToAddresses: Array.isArray(to) ? to : [to],
    },
    Message: {
      Subject: {
        Data: subject,
        Charset: "UTF-8",
      },
      Body: {
        Html: {
          Data: htmlBody,
          Charset: "UTF-8",
        },
        Text: {
          Data: plainText,
          Charset: "UTF-8",
        },
      },
    },
  };

  // Add reply-to if configured
  if (process.env.SES_REPLY_TO_EMAIL) {
    params.ReplyToAddresses = [process.env.SES_REPLY_TO_EMAIL];
  }

  try {
    const command = new SendEmailCommand(params);
    const result = await client.send(command);

    console.log(JSON.stringify({
      level: "info",
      message: "Email sent successfully",
      to,
      subject,
      messageId: result.MessageId,
    }));

    return { success: true, messageId: result.MessageId };
  } catch (error) {
    console.error(JSON.stringify({
      level: "error",
      message: "Failed to send email",
      to,
      subject,
      error: error.message,
    }));

    return { success: false, error: error.message };
  }
}

/**
 * Format a date for email display.
 * @param {Date|string} date - Date to format
 * @returns {string} Formatted date string
 */
function formatEmailDate(date) {
  const dateObj = typeof date === "string" ? new Date(date) : date;
  return dateObj.toLocaleString("en-US", {
    weekday: "long",
    year: "numeric",
    month: "long",
    day: "numeric",
    hour: "numeric",
    minute: "2-digit",
    hour12: true,
    timeZone: "America/New_York",
  });
}

module.exports = {
  sendEmail,
  loadTemplate,
  renderTemplate,
  htmlToPlainText,
  formatEmailDate,
};
