import { slotSizeToMinutes, type ResourceTypeBookingFields } from "@/lib/booking"

const DEFAULT_TZ = "America/Argentina/Buenos_Aires"

export function getBookingValidationTimezone(): string {
  return process.env.BOOKING_LOCAL_TIMEZONE?.trim() || DEFAULT_TZ
}

type ZonedParts = {
  dateKey: string
  minutesSinceMidnight: number
}

function toZonedParts(iso: Date, timeZone: string): ZonedParts {
  const d = new Date(iso)
  const formatter = new Intl.DateTimeFormat("en-CA", {
    timeZone,
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
    hour12: false,
  })
  const parts = formatter.formatToParts(d)
  const get = (type: Intl.DateTimeFormatPartTypes) =>
    parts.find((p) => p.type === type)?.value ?? "0"
  const y = get("year")
  const mo = get("month")
  const da = get("day")
  const h = parseInt(get("hour"), 10)
  const m = parseInt(get("minute"), 10)
  const s = parseInt(get("second"), 10)
  return {
    dateKey: `${y}-${mo}-${da}`,
    minutesSinceMidnight: h * 60 + m + Math.round(s / 60),
  }
}

function parsePgTimeToMinutes(t: string): number {
  const parts = t.split(":").map((x) => parseInt(x, 10))
  const h = parts[0] ?? 0
  const mi = parts[1] ?? 0
  const se = parts[2] ?? 0
  return h * 60 + mi + Math.round(se / 60)
}

/**
 * Valida que inicio/fin caigan el mismo día civil en BOOKING_LOCAL_TIMEZONE
 * y dentro de [booking_window_start, booking_window_end] en minutos desde medianoche.
 */
export function reservationFitsResourceTypeWindow(args: {
  startAt: Date
  endAt: Date
  type: ResourceTypeBookingFields
  timeZone?: string
}): boolean {
  const tz = args.timeZone ?? getBookingValidationTimezone()
  const start = toZonedParts(args.startAt, tz)
  const end = toZonedParts(args.endAt, tz)
  if (start.dateKey !== end.dateKey) return false

  const w0 = parsePgTimeToMinutes(args.type.booking_window_start)
  const w1 = parsePgTimeToMinutes(args.type.booking_window_end)
  if (!(start.minutesSinceMidnight >= w0 && end.minutesSinceMidnight <= w1)) return false
  return true
}

export function reservationMeetsMinSlotDuration(args: {
  startAt: Date
  endAt: Date
  type: ResourceTypeBookingFields
}): boolean {
  const minutes = Math.round((args.endAt.getTime() - args.startAt.getTime()) / 60000)
  const min = slotSizeToMinutes(String(args.type.slot_size))
  return minutes >= min
}
