// import nodemailer from "nodemailer";
import nodemailer from "nodemailer"
import dbConnect from "@/lib/mongodb";
import EmailTemplate from "@/models/EmailTemplate";
import GeneralSettings from "@/models/GeneralSettings";

export interface SendTemplateMailOptions {
  slug: string;
  to?: string | string[];
  replyTo?: string;
  templateData?: Record<string, string | number | boolean | null | undefined>;
  subjectOverride?: string;
  fallbackSubject?: string;
  fallbackContent?: string;
}

function normalizeValue(value: unknown) {
  if (value === null || value === undefined) return "";
  if (typeof value === "boolean") return value ? "Yes" : "No";
  return String(value);
}

function replacePlaceholders(content: string, templateData: Record<string, string>) {
  return content.replace(/\{\{\s*([\w.-]+)\s*\}\}/g, (_, key) => {
    return templateData[key] ?? "";
  });
}

function getDefaultTransporter() {
  const host = process.env.SMTP_HOST || process.env.MAIL_HOST;
  const port = Number(process.env.SMTP_PORT ?? process.env.MAIL_PORT ?? 587);
  const user = process.env.SMTP_USER || process.env.MAIL_USERNAME;
  const pass = process.env.SMTP_PASS || process.env.MAIL_PASSWORD;
  const encryption = process.env.SMTP_SECURE || process.env.MAIL_ENCRYPTION;

  if (!host) {
    throw new Error("Missing SMTP_HOST / MAIL_HOST environment variable for email delivery.");
  }

  let secure = false;
  if (process.env.SMTP_SECURE !== undefined) {
    secure = process.env.SMTP_SECURE === "true";
  } else if (process.env.MAIL_ENCRYPTION) {
    secure = process.env.MAIL_ENCRYPTION.toLowerCase() === "ssl";
  } else {
    secure = port === 465;
  }

  const transportOptions: any = {
    host,
    port,
    secure,
  };

  if (process.env.MAIL_ENCRYPTION?.toLowerCase() === "tls" || port === 587) {
    transportOptions.requireTLS = true;
  }

  if (user && pass) {
    transportOptions.auth = {
      user,
      pass,
    };
  }

  return nodemailer.createTransport(transportOptions);
}

async function getEmailTemplate(slug: string) {
  await dbConnect();
  return EmailTemplate.findOne({ slug }).lean();
}

async function getGeneralSettings() {
  await dbConnect();
  return GeneralSettings.findOne().lean();
}

const readableSlugLabel = (slug: string) => {
  switch (slug) {
    case "contact-us":
      return "Contact request";
    case "leads":
      return "Lead submission";
    case "newletter":
      return "Newsletter signup";
    default:
      return slug.replace(/[-_]/g, " ").replace(/\b\w/g, (m) => m.toUpperCase());
  }
};

function buildGenericTemplate(htmlLabel: string, companyName: string, companyLogo: string, detailsHtml: string) {
  return `
    <div style="font-family: Arial, sans-serif; color: #333; line-height: 1.5;">
      <div style="text-align: center; padding: 32px 0;">
        ${companyLogo ? `<img src="${companyLogo}" alt="${companyName}" style="max-width: 180px; height: auto;" />` : `<h1 style="margin: 0; font-size: 28px;">${companyName}</h1>`}
      </div>
      <div style="background: #f8f8f8; padding: 24px; border-radius: 12px;">
        <h2 style="margin-top: 0;">${htmlLabel} received</h2>
        <p style="margin: 0 0 24px;">A new ${htmlLabel.toLowerCase()} was submitted. Details are below.</p>
        <table style="width: 100%; border-collapse: collapse; font-size: 14px;">
          <tbody>
            ${detailsHtml}
          </tbody>
        </table>
      </div>
      <div style="margin-top: 24px; font-size: 13px; color: #777;">
        <p style="margin: 0;">${companyName}</p>
      </div>
    </div>
  `;
}

export async function sendTemplateMail(options: SendTemplateMailOptions) {
  const { slug, to, replyTo, templateData = {}, subjectOverride, fallbackSubject, fallbackContent } = options;

  const [template, settings] = await Promise.all([getEmailTemplate(slug), getGeneralSettings()]);

  const companyName = settings?.appName ?? process.env.DEFAULT_FROM_NAME ?? "Company";
  const companyLogo = settings?.logo ?? settings?.footerLogo ?? "";
  const recipient =
    to || settings?.email || process.env.DEFAULT_TO_EMAIL || process.env.SMTP_USER || "no-reply@example.com";

  const safeTemplateData: Record<string, string> = {
    companyName,
    companyLogo,
    companyEmail: settings?.email ?? "",
    companyPhone: settings?.phoneNumber ?? "",

    ...Object.fromEntries(
      Object.entries(templateData)
        .filter(([_, value]) => value !== undefined && value !== null)
        .map(([key, value]) => [
          key,
          key === "productsTable"
            ? String(value) // keep HTML
            : normalizeValue(value)
        ])
    ),
  };

  const subject = subjectOverride
    || (template?.subject ? replacePlaceholders(template.subject, safeTemplateData) : undefined)
    || fallbackSubject
    || `${readableSlugLabel(slug)} received at ${companyName}`;

  let html = template?.content
    ? replacePlaceholders(template.content, safeTemplateData)
    : fallbackContent
      || buildGenericTemplate(
        readableSlugLabel(slug),
        companyName,
        companyLogo,
        Object.entries(safeTemplateData)
          .filter(([key]) => !["companyName", "companyLogo"].includes(key) && safeTemplateData[key])
          .map(
            ([key, value]) =>
              `<tr style="border-bottom: 1px solid #e4e4e4;"><td style="padding: 10px; font-weight: 700; text-transform: capitalize; width: 180px;">${key.replace(/([A-Z])/g, " $1")}</td><td style="padding: 10px;">${value}</td></tr>`
          )
          .join("")
      );

  const fromName = template?.fromName || companyName;
  const fromEmail = template?.fromEmail || settings?.email || process.env.DEFAULT_FROM_EMAIL || process.env.SMTP_USER || "no-reply@example.com";

  const transporter = getDefaultTransporter();

  const mailOptions = {
    from: `${fromName} <${fromEmail}>`,
    to: recipient,
    subject,
    html,
    replyTo,
  };

  return transporter.sendMail(mailOptions);
}
