import { prisma } from "@/lib/prisma";
import { toLocalDateString } from "@/lib/format";

const OPEN_MINUTES = 9 * 60; // 9:00am
const CLOSE_MINUTES = 18 * 60; // 6:00pm
const SLOT_INTERVAL_MINUTES = 30;
const PENDING_HOLD_MINUTES = 30; // how long an unpaid checkout holds a slot

function toMinutes(time: string) {
  const [h, m] = time.split(":").map(Number);
  return h * 60 + m;
}

function toTimeString(minutes: number) {
  const h = Math.floor(minutes / 60)
    .toString()
    .padStart(2, "0");
  const m = (minutes % 60).toString().padStart(2, "0");
  return `${h}:${m}`;
}

export function isSalonOpen(dateStr: string) {
  const day = new Date(`${dateStr}T00:00:00`).getDay();
  return day !== 0; // closed Sundays
}

export async function getAvailableSlots(dateStr: string, durationMinutes: number) {
  if (!isSalonOpen(dateStr)) return [];

  const pendingCutoff = new Date(Date.now() - PENDING_HOLD_MINUTES * 60 * 1000);

  const existingBookings = await prisma.booking.findMany({
    where: {
      date: dateStr,
      OR: [{ status: "paid" }, { status: "pending", createdAt: { gte: pendingCutoff } }],
    },
    include: { service: true },
  });

  const busyRanges = existingBookings.map((booking) => {
    const start = toMinutes(booking.startTime);
    return { start, end: start + booking.service.durationMinutes };
  });

  const now = new Date();
  const isToday = dateStr === toLocalDateString(now);
  const nowMinutes = now.getHours() * 60 + now.getMinutes();

  const slots: string[] = [];
  for (
    let start = OPEN_MINUTES;
    start + durationMinutes <= CLOSE_MINUTES;
    start += SLOT_INTERVAL_MINUTES
  ) {
    if (isToday && start <= nowMinutes) continue;

    const end = start + durationMinutes;
    const overlaps = busyRanges.some((range) => start < range.end && end > range.start);
    if (!overlaps) slots.push(toTimeString(start));
  }

  return slots;
}
