import { transport } from "./mailer";
import { getEmailTemplate } from "./payload";
import { renderOrderConfirmationHtml, type OrderConfirmationData } from "./emailTemplates";
import { generateInvoicePdf, getSellerForInvoice } from "./invoiceData";
import { sendCriticalAlert } from "./alertAdmin";

// Superset of OrderConfirmationData (used for the HTML render) plus the
// address/invoice fields the PDF needs but the email body doesn't —
// avoids threading a second parallel "order" argument through this
// function for what's ultimately one order.
export type OrderConfirmationEmailData = OrderConfirmationData & {
  invoiceNumber: string;
  invoiceIssuedAt: string;
  customerFirstName: string;
  customerLastName: string;
  deliveryMethod: "address" | "packstation";
  street?: string | null;
  packstationNumber?: string | null;
  postNumber?: string | null;
  zip: string;
  city: string;
  country: string;
  paymentMethodTitle: string;
};

// Called from app/api/checkout/route.ts right after a successful
// createOrder() — fire-and-forget, must never block or fail the checkout
// response itself. A missing/unpublished template falls back to a plain
// default so a first-ever order isn't silently un-confirmed just because
// nobody's visited the Payload admin yet (mirrors seed-email-templates.ts's
// defaults, kept in sync by hand — there are only two places this wording
// lives, seeding it is a one-time setup step, not a runtime dependency).
//
// The invoice PDF is generated here too (not a separate fire-and-forget
// step) so it can ride along as an attachment on this same send, per the
// "always emailed, not just downloadable" checkout decision — but its own
// failure must not sink the confirmation email itself, so it's wrapped in
// its own try/catch and just sends without the attachment if generation
// fails (still alerted, same severity as the frontend's own critical-error
// path for this checkout flow).
export async function sendOrderConfirmationEmail(order: OrderConfirmationEmailData, customerEmail: string): Promise<boolean> {
  const template = (await getEmailTemplate("order-confirmation")) ?? {
    subject: "Bestellt! Deine Ruhe kann kommen 🎉",
    heading: "Bestellt!",
    bodyText: "Deine Bestellung ist bei uns eingetrudelt — wir kümmern uns schon liebevoll darum, sie für dich zu packen.",
    footerText: null,
  };

  const seller = await getSellerForInvoice();
  const html = renderOrderConfirmationHtml(template, order, seller);

  let attachments: { filename: string; content: Buffer }[] | undefined;
  try {
    const pdf = await generateInvoicePdf(
      {
        orderNumber: order.orderNumber,
        invoiceNumber: order.invoiceNumber,
        invoiceIssuedAt: order.invoiceIssuedAt,
        customerFirstName: order.customerFirstName,
        customerLastName: order.customerLastName,
        deliveryMethod: order.deliveryMethod,
        street: order.street,
        packstationNumber: order.packstationNumber,
        postNumber: order.postNumber,
        zip: order.zip,
        city: order.city,
        country: order.country,
        paymentMethodTitle: order.paymentMethodTitle,
        items: order.items.map((i) => ({
          productName: i.productName,
          quantity: i.quantity,
          unitPrice: i.unitPrice,
          taxRatePercent: i.taxRatePercent,
          bundleContents: i.bundleContents ?? null,
        })),
        subtotal: order.subtotal,
        shippingCost: order.shippingCost,
        discountAmount: order.discountAmount,
        discountCode: order.discountCode,
        total: order.total,
      },
      seller,
    );
    if (pdf) attachments = [{ filename: `Rechnung-${order.invoiceNumber}.pdf`, content: pdf }];
    else throw new Error("generateInvoicePdf returned null (missing invoice-settings?)");
  } catch (err) {
    sendCriticalAlert("Rechnungs-PDF konnte nicht erzeugt werden", {
      orderNumber: order.orderNumber,
      invoiceNumber: order.invoiceNumber,
      error: String(err),
    });
  }

  await transport.sendMail({
    // Display name only, not the address — see the memory note on why the
    // envelope stays admin@mk360.de (that's the domain the Hostinger SMTP
    // account is actually authorized for; sellerEmail's domain isn't
    // confirmed SPF-authorized on it yet). Reply-To is what actually routes
    // a customer's reply to the seller, regardless of the From address.
    from: `"${seller?.sellerName ?? "einfach produktiv"}" <admin@mk360.de>`,
    replyTo: seller?.sellerEmail || undefined,
    to: customerEmail,
    subject: template.subject,
    html,
    attachments,
  });
  return true;
}
