/** Send magic link invitations via email. */

import { magicLinkConfig } from "./config";
import { createMagicToken } from "./token";

export interface MagicLinkRecipient {
  name: string;
  email: string;
}

export interface SendMagicLinkOpts {
  space: string;
  type: "poll" | "rsvp";
  targetId: string;
  /** Title of the poll session or event (for email subject) */
  title: string;
  participants: MagicLinkRecipient[];
  /** If false, only return URLs without sending emails */
  sendEmail?: boolean;
}

export interface MagicLinkResult {
  name: string;
  email: string;
  url: string;
  sent: boolean;
}

export async function sendMagicLinks(opts: SendMagicLinkOpts): Promise<MagicLinkResult[]> {
  const results: MagicLinkResult[] = [];

  for (const participant of opts.participants) {
    const token = await createMagicToken(opts.space, opts.type, opts.targetId, participant.name);
    const url = `${magicLinkConfig.baseUrl}/respond/${token}`;

    let sent = false;
    if (opts.sendEmail !== false && participant.email) {
      try {
        const nodemailer = await import("nodemailer");
        const transport = nodemailer.createTransport({
          host: process.env.SMTP_HOST || "mailcowdockerized-postfix-mailcow-1",
          port: Number(process.env.SMTP_PORT) || 587,
          secure: false,
          auth: {
            user: process.env.SMTP_USER || "noreply@rmail.online",
            pass: process.env.SMTP_PASS,
          },
          tls: { rejectUnauthorized: false },
        });

        const typeLabel = opts.type === "poll" ? "Poll" : "RSVP";
        const subject = `${typeLabel}: ${opts.title}`;
        const html = buildInviteEmail(opts, participant, url);

        await transport.sendMail({
          from: process.env.SMTP_FROM || `rSpace <${process.env.SMTP_USER || "noreply@rmail.online"}>`,
          to: participant.email,
          subject,
          html,
        });
        sent = true;
      } catch (err) {
        console.error(`[MagicLink] Email send failed for ${participant.email}:`, err);
      }
    }

    results.push({ name: participant.name, email: participant.email, url, sent });
  }

  return results;
}

function esc(str: string): string {
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
}

function buildInviteEmail(opts: SendMagicLinkOpts, participant: MagicLinkRecipient, url: string): string {
  const typeLabel = opts.type === "poll" ? "Poll" : "Event RSVP";
  const actionLabel = opts.type === "poll" ? "Vote Now" : "RSVP Now";

  return `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width"></head>
<body style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#f8fafc;color:#1e293b;margin:0;padding:20px">
<div style="max-width:500px;margin:40px auto;background:#fff;border-radius:12px;box-shadow:0 1px 3px rgba(0,0,0,.1);padding:32px">
<h1 style="font-size:20px;margin:0 0 4px;color:#0f172a">${esc(opts.title)}</h1>
<p style="font-size:14px;color:#64748b;margin:8px 0 24px">Hi ${esc(participant.name)}, you've been invited to respond to this ${typeLabel.toLowerCase()}.</p>
<a href="${esc(url)}" style="display:inline-block;padding:14px 28px;background:#6366f1;color:#fff;border-radius:10px;text-decoration:none;font-size:16px;font-weight:600">${actionLabel}</a>
<p style="font-size:12px;color:#94a3b8;margin-top:24px">This link expires in ${magicLinkConfig.tokenExpiryDays} days. No account required.</p>
<p style="font-size:11px;color:#cbd5e1;margin-top:16px">Sent by rSpace &middot; rspace.online</p>
</div></body></html>`;
}
