import crypto from "crypto";
import { connectDB } from "@/lib/db";
import { Order } from "@/models/Order";
import { Client } from "@/models/Client";
import { ClientPhotoFolder } from "@/models/ClientPhotoFolder";
import { OrderFeedback } from "@/models/OrderFeedback";
import { getSettings } from "@/lib/settings";
import { notifyClientFeedbackRequest } from "@/lib/orderEmails";

// Sicherheitsnetz zum bereits bestehenden Weg (Zufriedenheits-Mail beim
// Archivieren eines Auftrags, siehe archiveOrderAction) — falls ein Auftrag
// nie archiviert wird, obwohl die Galerie längst freigegeben ist, greift
// dieser tägliche Cron-Lauf trotzdem. Der eindeutige Index auf
// OrderFeedback.orderId verhindert in beiden Fällen einen Doppelversand.
export async function runFeedbackRequestSweep() {
  await connectDB();
  const settings = await getSettings();
  if (!settings.feedbackRequestSettings.enabled) return { sent: 0, skipped: "disabled" as const };

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

  const folders = await ClientPhotoFolder.find({ orderId: { $ne: null }, assignedAt: { $lte: cutoff } })
    .select("orderId")
    .lean();
  const candidateOrderIds = [...new Set(folders.map((f) => String(f.orderId)))];
  if (candidateOrderIds.length === 0) return { sent: 0, candidates: 0 };

  const alreadySent = await OrderFeedback.find({ orderId: { $in: candidateOrderIds } })
    .select("orderId")
    .lean();
  const alreadySentSet = new Set(alreadySent.map((f) => String(f.orderId)));
  const pendingOrderIds = candidateOrderIds.filter((id) => !alreadySentSet.has(id));
  if (pendingOrderIds.length === 0) return { sent: 0, candidates: candidateOrderIds.length };

  const orders = await Order.find({ _id: { $in: pendingOrderIds }, rejected: false }).select("characterOrConcept clientId shootingType").lean();

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

    const token = crypto.randomUUID().replace(/-/g, "");
    await OrderFeedback.create({
      orderId: order._id,
      clientId: order.clientId,
      clientName: client.nickname || client.firstName || client.name,
      shootingType: order.shootingType,
      token,
    });
    await notifyClientFeedbackRequest(
      { email: client.email, name: client.nickname || client.firstName || client.name, locale: client.locale },
      { id: String(order._id), characterOrConcept: order.characterOrConcept },
      token
    );
    sent += 1;
  }

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