import axios from "axios";
import db from "../models/index.js";
import { baseEmailLayout } from "./emailTemplates/baseLayout.js";

const OTP_EXPIRES_MINUTES = parseInt(process.env.OTP_EXPIRES_MINUTES || "10");
const { EmailTemplate } = db;

// ─────────────────────────────────────────────────────────────
// CORE SENDER
// ─────────────────────────────────────────────────────────────

/**
 * Send an email via ZeptoMail.
 * @param {string|string[]} to - Recipient email(s)
 * @param {string} subject - Email subject
 * @param {string} html - Rendered HTML body
 * @param {string} [text] - Plain text fallback (auto-generated if omitted)
 * @returns {Promise<boolean>}
 */
export const sendEmail = async (to, subject, html, text = null) => {
  const url = process.env.ZEPTOMAIL_URL || "https://api.zeptomail.com/v1.1/email";
  const token = process.env.ZEPTOMAIL_TOKEN;
  const fromAddress = process.env.ZEPTOMAIL_FROM_ADDRESS;
  const fromName = process.env.ZEPTOMAIL_FROM_NAME || "Airpero";

  const recipients = Array.isArray(to)
    ? to.map((email) => ({ email_address: { address: email } }))
    : [{ email_address: { address: to } }];

  const payload = {
    from: { address: fromAddress, name: fromName },
    to: recipients,
    subject,
    htmlbody: html,
    ...(text && { textbody: text }),
  };

  try {
    await axios.post(url, payload, {
      headers: {
        Authorization: token,
        "Content-Type": "application/json",
      },
    });
    const recipientList = Array.isArray(to) ? to.join(", ") : to;
    console.log(`📧 [ZeptoMail] Email sent → "${subject}" → ${recipientList}`);
    return true;
  } catch (error) {
    console.error(
      "❌ [ZeptoMail] Failed to send email:",
      JSON.stringify(error.response?.data || error.message, null, 2)
    );
    return false;
  }
};

// ─────────────────────────────────────────────────────────────
// DYNAMIC TEMPLATE RENDERER
// ─────────────────────────────────────────────────────────────

/**
 * Fetch a template from DB, replace variables, and wrap in base layout.
 * @param {string} slug - The template slug
 * @param {object} variables - Key-value pairs for substitution
 * @returns {Promise<{subject: string, html: string} | null>}
 */
export const renderTemplate = async (slug, variables = {}) => {
  try {
    const template = await EmailTemplate.findOne({ where: { slug } });
    if (!template) {
      console.error(`❌ EmailTemplate not found for slug: ${slug}`);
      return null;
    }

    let subject = template.subject;
    let bodyHtml = template.bodyHtml;

    // Replace variables e.g. {{businessName}}
    Object.keys(variables).forEach((key) => {
      const regex = new RegExp(`{{\\s*${key}\\s*}}`, "g");
      const value = variables[key] !== undefined && variables[key] !== null ? String(variables[key]) : "";
      subject = subject.replace(regex, value);
      bodyHtml = bodyHtml.replace(regex, value);
      
      // Handlebars style boolean tags for if statements (very basic implementation)
      const ifRegex = new RegExp(`{{#if\\s+${key}}}([\\s\\S]*?){{/if}}`, "g");
      bodyHtml = bodyHtml.replace(ifRegex, variables[key] ? "$1" : "");
    });

    const finalHtml = baseEmailLayout({ htmlContent: bodyHtml, title: subject });
    return { subject, html: finalHtml };
  } catch (error) {
    console.error("Error rendering email template:", error);
    return null;
  }
};

// ─────────────────────────────────────────────────────────────
// NAMED EMAIL HELPERS
// ─────────────────────────────────────────────────────────────

export const sendOtpEmail = async (to, otp, purpose, recipientName = "Merchant") => {
  const slugMap = {
    login: "otp_login",
    payout: "otp_payout",
    password_reset: "otp_password_reset", // Ensure seed has this, or use password_reset_link. Assuming we seeded standard ones. Wait, I seeded otp_login and otp_payout. We didn't seed otp_password_reset, we seeded password_reset_link. If purpose is password_reset, we need to map to appropriate slug or fallback.
  };
  const slug = slugMap[purpose] || "otp_login";
  
  const rendered = await renderTemplate(slug, {
    name: recipientName,
    otp,
    expiryMinutes: OTP_EXPIRES_MINUTES
  });

  if (!rendered) return false;
  return sendEmail(to, rendered.subject, rendered.html);
};

export const sendPasswordResetEmail = async (to, resetUrl, recipientName = "Merchant") => {
  const rendered = await renderTemplate("password_reset_link", {
    name: recipientName,
    resetUrl
  });
  if (!rendered) return false;
  return sendEmail(to, rendered.subject, rendered.html);
};

export const sendMerchantWelcomeEmail = async (to, merchantData) => {
  const rendered = await renderTemplate("merchant_welcome", merchantData);
  if (!rendered) return false;
  return sendEmail(to, rendered.subject, rendered.html);
};

export const sendTransactionAlertEmail = async (to, transactionData) => {
  const isCredit = transactionData.type === "credit";
  const typeLabel = isCredit ? "Credit" : "Debit";
  const typeColor = isCredit ? "#059669" : "#dc2626";
  const typeIcon = isCredit ? "⬆️" : "⬇️";
  const amountSign = isCredit ? "+" : "-";
  
  const formattedAmount = new Intl.NumberFormat("en-NG", {
    style: "currency",
    currency: transactionData.currency || "NGN",
    minimumFractionDigits: 2,
  }).format(transactionData.amount);

  const rendered = await renderTemplate("transaction_alert", {
    ...transactionData,
    typeLabel,
    typeColor,
    typeIcon,
    amountSign,
    formattedAmount,
  });

  if (!rendered) return false;
  return sendEmail(to, rendered.subject, rendered.html);
};

// --- NEW TRIGGERS ---

export const sendNewDeviceLoginEmail = async (to, businessName, ipAddress) => {
  const rendered = await renderTemplate("new_device_login", {
    businessName,
    ipAddress,
    time: new Date().toUTCString()
  });
  if (!rendered) return false;
  return sendEmail(to, rendered.subject, rendered.html);
};

export const sendFailedOtpAttemptEmail = async (to, name) => {
  const rendered = await renderTemplate("failed_otp_attempt", { name });
  if (!rendered) return false;
  return sendEmail(to, rendered.subject, rendered.html);
};

export const sendPasswordChangedEmail = async (to, name) => {
  const rendered = await renderTemplate("password_changed_success", { name });
  if (!rendered) return false;
  return sendEmail(to, rendered.subject, rendered.html);
};
