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";
import { effectiveEventAddress, type ShootingType } from "@/lib/orderConstants";
import { getShootPrepTips } from "@/lib/shootPrepTips";

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

function sendPreshootReminderMail(
  client: { id: string; email: string; name: string; locale: "de" | "en" },
  order: { characterOrConcept: string; shootDate: Date; address: string; checklist: string[]; shootingType: ShootingType },
  customText: { de: string; en: string }
) {
  return safeSend(async () => {
    const isEn = client.locale === "en";
    const overrideText = isEn ? customText.en : customText.de;
    const dateStr = order.shootDate.toLocaleString(isEn ? "en-GB" : "de-DE", {
      dateStyle: "full",
      timeStyle: "short",
    });
    const checklistHtml = order.checklist.length
      ? `<ul style="margin:12px 0; padding-left:20px;">${order.checklist.map((c) => `<li>${c}</li>`).join("")}</ul>`
      : "";
    // Kurzer, allgemeiner Vorbereitungs-Guide je Shooting-Art — ergänzt die
    // individuelle Checkliste des Auftrags, ersetzt sie nicht (siehe shootPrepTips.ts).
    const prepTips = getShootPrepTips(order.shootingType, isEn);
    const prepTipsHtml = prepTips.length
      ? `<p style="margin:16px 0 4px;"><strong>${isEn ? "A few tips to prepare" : "Ein paar Tipps zur Vorbereitung"}:</strong></p>
         <ul style="margin:0 0 12px; padding-left:20px;">${prepTips.map((tip) => `<li>${tip}</li>`).join("")}</ul>`
      : "";
    const html = await emailShell({
      heading: `Hi ${client.name},`,
      bodyHtml: `
        <p style="margin:0 0 8px;">${
          overrideText ||
          (isEn
            ? `A quick reminder — our shoot "${order.characterOrConcept}" is coming up soon.`
            : `Kurze Erinnerung — unser Shooting „${order.characterOrConcept}" steht bald an.`)
        }</p>
        <p style="margin:0 0 4px;"><strong>${isEn ? "When" : "Wann"}:</strong> ${dateStr}</p>
        ${order.address ? `<p style="margin:0 0 4px; white-space:pre-line;"><strong>${isEn ? "Where" : "Wo"}:</strong> ${order.address}</p>` : ""}
        ${checklistHtml}
        ${prepTipsHtml}
      `,
      buttonLabel: isEn ? "View order" : "Auftrag ansehen",
      buttonUrl: `${process.env.SITE_URL}/${client.locale}/account/orders`,
      footerNote: isEn
        ? "You're receiving this because your shoot is coming up soon."
        : "Du erhältst diese E-Mail, weil dein Shooting bald ansteht.",
    });
    await sendMailIfEnabled(
      client.id,
      client.email,
      isEn ? "Your shoot is coming up — Rakku Photography" : "Dein Shooting steht bald an — Rakku Photography",
      html
    );
  });
}

// 2-Stunden-Cron-Raster (siehe api/cron/preshoot-reminder) — findet Aufträge,
// deren shootDate innerhalb des in den Einstellungen hinterlegten
// Vorlauf-Fensters liegt und noch keine Erinnerung bekommen haben.
export async function runPreshootReminderSweep() {
  await connectDB();
  const settings = await getSettings();
  if (!settings.preshootReminderSettings.enabled) return { sent: 0, skipped: "disabled" as const };

  const now = new Date();
  const windowEnd = new Date(now.getTime() + settings.preshootReminderSettings.hoursBefore * 60 * 60 * 1000);

  const candidates = await Order.find({
    shootDate: { $gte: now, $lte: windowEnd },
    preshootReminderSentAt: null,
    rejected: false,
    archived: false,
  }).select(
    "clientId characterOrConcept shootDate eventStreet eventPostCode eventCity eventCountryCode eventLocation checklist shootingType"
  );

  let sent = 0;
  for (const order of candidates) {
    const client = await Client.findById(order.clientId).select("email name firstName nickname locale").lean();
    if (!client) continue;

    await sendPreshootReminderMail(
      {
        id: String(order.clientId),
        email: client.email,
        name: client.nickname || client.firstName || client.name,
        locale: client.locale,
      },
      {
        characterOrConcept: order.characterOrConcept,
        shootDate: order.shootDate!,
        address: effectiveEventAddress(order),
        checklist: order.checklist.map((c) => c.text),
        shootingType: order.shootingType,
      },
      { de: settings.preshootReminderSettings.customText, en: settings.preshootReminderSettings.customTextEn }
    );
    order.preshootReminderSentAt = now;
    await order.save();
    sent += 1;
  }

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