import { endOfDay, setHours, setMinutes, startOfDay } from "date-fns"
import { bookingFieldsToSlotStarts, type ResourceTypeBookingFields } from "@/lib/booking"
import type { Database } from "@/lib/supabase/database.types"
import { resolveReservationRules, valueUnitFromMinutes } from "@/lib/reservations/rules"

export type PolicyRow = Database["public"]["Tables"]["resource_policies"]["Row"]

/** Mínimos campos del recurso para resolver políticas de antelación */
export type AdvanceRestrictionResource = Pick<
  Database["public"]["Tables"]["resources"]["Row"],
  "id" | "resource_type_id"
>

export const BOOKING_CALENDAR_LOOKAHEAD_DAYS = 30

export function getAdvanceRestriction(
  resource: AdvanceRestrictionResource,
  selectedDate: Date,
  policies: PolicyRow[],
  bookingFields: ResourceTypeBookingFields,
  now: Date = new Date(),
): { disabled: boolean; message?: string; minSlotStart?: Date } {
  const rules = resolveReservationRules({
    resourceId: resource.id,
    resourceTypeId: resource.resource_type_id,
    policies,
  })
  const minStartAllowed = new Date(now.getTime() + rules.bookingAdvanceMinutes * 60 * 1000)

  const slots = bookingFieldsToSlotStarts(bookingFields)
  const lastSlot = slots[slots.length - 1]
  if (!lastSlot) {
    return {
      disabled: true,
      message:
        "Este tipo de recurso no tiene franjas horarias (revisá inicio y fin de ventana en administración).",
    }
  }
  const [lastHour, lastMin] = lastSlot.split(":").map(Number)
  const lastSlotOnDay = setMinutes(setHours(selectedDate, lastHour), lastMin)

  if (lastSlotOnDay.getTime() < minStartAllowed.getTime()) {
    const { value, unit } = valueUnitFromMinutes(rules.bookingAdvanceMinutes, { value: 10, unit: "days" })
    const advanceLabel =
      unit === "days" ? `${value} día${value !== 1 ? "s" : ""}` : `${value} hora${value !== 1 ? "s" : ""}`
    return {
      disabled: true,
      message: `Este recurso requiere reservar con al menos ${advanceLabel} de antelación. La fecha seleccionada no cumple con ese requisito.`,
    }
  }

  const dayStart = startOfDay(selectedDate)
  const dayEnd = endOfDay(selectedDate)
  const minStartOnThisCalendarDay =
    minStartAllowed.getTime() >= dayStart.getTime() && minStartAllowed.getTime() <= dayEnd.getTime()

  return {
    disabled: false,
    minSlotStart: minStartOnThisCalendarDay ? minStartAllowed : undefined,
  }
}
