import { connectDB } from "./db";
import { Order } from "@/models/Order";
import { CalendarEvent } from "@/models/CalendarEvent";
import { Calendar } from "@/models/Calendar";
import { dayKey } from "./calendarGrid";

// Scannt vorwärts ab dem Ende der Mindestvorlaufzeit (siehe
// bookingSettings.minLeadTimeWeeks in models/Settings.ts) nach dem ersten Tag
// ohne Order-/CalendarEvent-Überschneidung — gleiche Datenquelle wie
// api/availability/route.ts, nur als Einzelwert statt Monatsraster. Rein
// informativ für die öffentliche Angebote-Seite, ersetzt keine echte
// Terminvergabe (die bleibt Sache des Teams, siehe setOrderShootDateAction).
const SCAN_WINDOW_DAYS = 180;

export async function getNextAvailableDate(minLeadTimeWeeks: number): Promise<Date | null> {
  await connectDB();
  const earliest = new Date(Date.now() + minLeadTimeWeeks * 7 * 24 * 60 * 60 * 1000);
  earliest.setHours(0, 0, 0, 0);
  const rangeEnd = new Date(earliest.getTime() + SCAN_WINDOW_DAYS * 24 * 60 * 60 * 1000);

  const [orders, publicCalendars] = await Promise.all([
    Order.find({ rejected: false, shootDate: { $gte: earliest, $lt: rangeEnd } })
      .select("shootDate shootEndDate")
      .lean(),
    Calendar.find({ kind: "custom" }).select("_id").lean(),
  ]);
  const events = await CalendarEvent.find({
    calendarId: { $in: publicCalendars.map((c) => c._id) },
    start: { $lt: rangeEnd },
    $or: [{ end: { $gte: earliest } }, { end: null, start: { $gte: earliest } }],
  })
    .select("start end")
    .lean();

  const busyDays = new Set<string>();
  const markBusy = (start: Date, end: Date | null) => {
    const last = end && end.getTime() > start.getTime() ? end : start;
    for (let d = new Date(start); dayKey(d) <= dayKey(last); d.setDate(d.getDate() + 1)) busyDays.add(dayKey(d));
  };
  for (const o of orders) markBusy(new Date(o.shootDate as Date), o.shootEndDate ? new Date(o.shootEndDate) : null);
  for (const e of events) markBusy(new Date(e.start), e.end ? new Date(e.end) : null);

  for (let d = new Date(earliest); d < rangeEnd; d.setDate(d.getDate() + 1)) {
    if (!busyDays.has(dayKey(d))) return new Date(d);
  }
  return null;
}
