import { connectDB } from "@/lib/db";
import { Order } from "@/models/Order";
import { Client } from "@/models/Client";
import { getSettings } from "@/lib/settings";
import { sendMailIfEnabled } from "@/lib/mail";
import { emailShell } from "@/lib/emailTemplate";

async function safeSend(fn: () => Promise<void>) {
  try {
    await fn();
  } catch (err) {
    console.error("Wiedervorlage-Mail fehlgeschlagen:", err);
  }
}

function sendReengagementMail(
  client: { id: string; email: string; name: string; locale: "de" | "en" },
  customText: { de: string; en: string }
) {
  return safeSend(async () => {
    const isEn = client.locale === "en";
    const overrideText = isEn ? customText.en : customText.de;
    const html = await emailShell({
      heading: `Hi ${client.name},`,
      bodyHtml: overrideText
        ? `<p style="margin:0; white-space:pre-line;">${overrideText}</p>`
        : isEn
          ? `<p style="margin:0;">It's been about a year since our last shoot together — how time flies! If you're up for another session (or know someone who would be), I'd love to hear from you.</p>`
          : `<p style="margin:0;">Es ist schon ungefähr ein Jahr her seit unserem letzten gemeinsamen Shooting — wie die Zeit vergeht! Falls du Lust auf eine weitere Session hast (oder jemanden kennst, der/die das könnte), würde ich mich sehr freuen, von dir zu hören.</p>`,
      buttonLabel: isEn ? "See offers" : "Angebote ansehen",
      buttonUrl: `${process.env.SITE_URL}/${client.locale}/angebote`,
      footerNote: isEn
        ? "You're receiving this because it's been a while since your last shoot with Rakku Photography."
        : "Du erhältst diese E-Mail, weil dein letztes Shooting mit Rakku Photography schon eine Weile her ist.",
    });
    await sendMailIfEnabled(
      client.id,
      client.email,
      isEn ? "It's been a while — Rakku Photography" : "Ist schon eine Weile her — Rakku Photography",
      html
    );
  });
}

// Täglicher Cron-Lauf (siehe api/cron/reengagement) — findet Kunden, deren
// letztes vereinbartes shootDate mindestens delayDays zurückliegt, und
// schickt ihnen einmalig pro shootDate eine Wiedervorlage-Mail. Aggregation
// statt Einzelabfrage pro Kunde, damit das auch bei vielen Kunden/Aufträgen
// eine einzelne, schnelle DB-Runde bleibt.
export async function runReengagementSweep() {
  await connectDB();
  const settings = await getSettings();
  if (!settings.reengagementSettings.enabled) return { sent: 0, skipped: "disabled" as const };

  const now = new Date();
  const cutoff = new Date(now.getTime() - settings.reengagementSettings.delayDays * 24 * 60 * 60 * 1000);

  const candidates = await Order.aggregate<{ _id: string; lastShootDate: Date }>([
    { $match: { shootDate: { $ne: null, $lte: now } } },
    { $group: { _id: "$clientId", lastShootDate: { $max: "$shootDate" } } },
    { $match: { lastShootDate: { $lte: cutoff } } },
  ]);

  let sent = 0;
  for (const candidate of candidates) {
    const client = await Client.findById(candidate._id).select("email name firstName nickname locale role lastReengagementShootDate").lean();
    if (!client || client.role !== "client") continue;
    if (client.lastReengagementShootDate && client.lastReengagementShootDate >= candidate.lastShootDate) continue;

    await sendReengagementMail(
      {
        id: String(candidate._id),
        email: client.email,
        name: client.nickname || client.firstName || client.name,
        locale: client.locale,
      },
      { de: settings.reengagementSettings.customText, en: settings.reengagementSettings.customTextEn }
    );
    await Client.findByIdAndUpdate(candidate._id, { lastReengagementShootDate: candidate.lastShootDate });
    sent += 1;
  }

  return { sent, candidates: candidates.length };
}
