import "server-only";
import nodemailer, { type Transporter } from "nodemailer";

/**
 * Wrapper Nodemailer.
 *
 * Lit la config SMTP depuis l'env (cf. .env.production.example).
 * En dev, si SMTP_HOST est absent, on log les emails au lieu de les envoyer.
 */

let cachedTransporter: Transporter | null = null;

function getTransporter(): Transporter | null {
  if (cachedTransporter) return cachedTransporter;

  const host = process.env.SMTP_HOST;
  if (!host) return null;

  const port = Number(process.env.SMTP_PORT ?? 587);
  const secure = process.env.SMTP_SECURE === "true";
  const user = process.env.SMTP_USER;
  const pass = process.env.SMTP_PASS;

  cachedTransporter = nodemailer.createTransport({
    host,
    port,
    secure,
    auth: user && pass ? { user, pass } : undefined,
    // STARTTLS : on force requireTLS si port 587 et secure=false.
    requireTLS: !secure && port === 587,
  });
  return cachedTransporter;
}

export interface SendEmailInput {
  to: string;
  subject: string;
  /** Texte brut. */
  text: string;
  /** HTML optionnel. */
  html?: string;
}

export async function sendEmail({
  to,
  subject,
  text,
  html,
}: SendEmailInput): Promise<{ ok: boolean; reason?: string }> {
  const transporter = getTransporter();
  const from = process.env.SMTP_FROM ?? "Socialex <contact@socialex.pro>";

  if (!transporter) {
    // Dev mode : log uniquement.
    console.log("\n📧 [email mock] (SMTP_HOST non défini)");
    console.log(`  From    : ${from}`);
    console.log(`  To      : ${to}`);
    console.log(`  Subject : ${subject}`);
    console.log(`  Body    :\n${text}\n`);
    return { ok: true, reason: "mocked" };
  }

  try {
    await transporter.sendMail({ from, to, subject, text, html });
    return { ok: true };
  } catch (err) {
    console.error("[email] Échec envoi :", err);
    return {
      ok: false,
      reason: err instanceof Error ? err.message : "unknown error",
    };
  }
}

/* ─── Templates de mails ─────────────────────────────────────────────── */

export interface PasswordResetEmailParams {
  to: string;
  clientName: string;
  setUrl: string;
  /** Si true, c'est un email "définissez votre mot de passe" (post inscription).
   *  Si false (défaut), c'est un classique "vous avez oublié votre mot de passe". */
  isInitialSetup?: boolean;
}

export async function sendPasswordResetEmail(p: PasswordResetEmailParams) {
  const action = p.isInitialSetup
    ? "définir votre mot de passe et activer votre espace client"
    : "réinitialiser votre mot de passe";

  const subject = p.isInitialSetup
    ? "Activez votre espace client Socialex"
    : "Réinitialisation de votre mot de passe Socialex";

  const text = `Bonjour ${p.clientName},

Pour ${action}, cliquez sur le lien ci-dessous :

${p.setUrl}

Ce lien est valable 24 heures et ne peut être utilisé qu'une seule fois.

Si vous n'êtes pas à l'origine de cette demande, ignorez cet email : aucun changement ne sera effectué tant que le lien n'aura pas été utilisé.

À bientôt,
Socialex
contact@socialex.pro`;

  return sendEmail({ to: p.to, subject, text });
}

export interface InvoiceEmailParams {
  to: string;
  clientName: string;
  dossierReference: string;
  invoiceNumber: string;
  amountCents: number;
  serviceTitle: string;
  /** Lien magic link pour set password (généré côté caller). */
  setPasswordLink: string;
  /**
   * Mode de paiement choisi par le client.
   * - "bank" : on inclut les coordonnées bancaires (env BANK_*).
   * - "quote" : on précise qu'aucun règlement n'est à effectuer ; on
   *   reprendra contact pour finaliser le devis.
   */
  paymentMode?: "bank" | "quote";
}

function bankBlock(invoiceNumber: string): string {
  const iban = process.env.BANK_IBAN;
  const bic = process.env.BANK_BIC;
  const holder = process.env.BANK_HOLDER ?? "Socialex";
  if (!iban) return ""; // pas de coordonnées en config → on n'en met pas

  return `
──────────────────────────────────────────────────
COORDONNÉES BANCAIRES (VIREMENT)
──────────────────────────────────────────────────

  Bénéficiaire : ${holder}
  IBAN         : ${iban}${bic ? `\n  BIC          : ${bic}` : ""}
  Référence    : ${invoiceNumber}

Merci d'indiquer la référence ${invoiceNumber} dans le libellé du virement.
`;
}

export async function sendInvoiceEmail(p: InvoiceEmailParams) {
  const amount = new Intl.NumberFormat("fr-FR", {
    style: "currency",
    currency: "EUR",
  }).format(p.amountCents / 100);

  const isQuote = p.paymentMode === "quote";

  const intro = isQuote
    ? `Nous avons bien reçu votre demande pour : ${p.serviceTitle}.

Votre dossier a été créé sous la référence ${p.dossierReference}. Aucun règlement n'est demandé à ce stade : un expert reprendra contact rapidement pour finaliser votre devis.`
    : `Nous avons bien reçu votre demande pour : ${p.serviceTitle}.

Votre dossier a été créé sous la référence ${p.dossierReference}.

Pour valider la prise en charge et démarrer le traitement, merci de régler la facture suivante :

  Facture : ${p.invoiceNumber}
  Montant : ${amount}`;

  const bank = p.paymentMode === "bank" ? bankBlock(p.invoiceNumber) : "";

  const text = `Bonjour ${p.clientName},

${intro}
${bank}
──────────────────────────────────────────────────
ACTIVEZ VOTRE ESPACE CLIENT
──────────────────────────────────────────────────

Pour suivre l'avancement de votre dossier et déposer vos documents, activez votre espace client en définissant votre mot de passe :

${p.setPasswordLink}

Ce lien est valable 24 heures et ne peut être utilisé qu'une seule fois. Si vous ne l'utilisez pas à temps, vous pourrez en redemander un depuis la page de connexion (option "Mot de passe oublié").

──────────────────────────────────────────────────

À bientôt,
Socialex
contact@socialex.pro`;

  return sendEmail({
    to: p.to,
    subject: `Votre dossier ${p.dossierReference} — Socialex`,
    text,
  });
}
