var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/components/venueBooking/utils.ts
var utils_exports = {};
__export(utils_exports, {
  AUTO_VIEW_HOURS: () => AUTO_VIEW_HOURS,
  FIRST_COLUMN_WIDTH: () => FIRST_COLUMN_WIDTH,
  SLOTS_PER_HOUR: () => SLOTS_PER_HOUR,
  SLOT_MINUTES: () => SLOT_MINUTES,
  SLOT_MIN_WIDTH: () => SLOT_MIN_WIDTH,
  buildHourGroups: () => buildHourGroups,
  buildSlotPriceInfo: () => buildSlotPriceInfo,
  formatDateKey: () => formatDateKey,
  formatHourHeader: () => formatHourHeader,
  formatRange: () => formatRange,
  getColumnTag: () => getColumnTag,
  getDateDisplay: () => getDateDisplay,
  getDateMetaFromSummary: () => getDateMetaFromSummary,
  getFirstAvailableSlotIndex: () => getFirstAvailableSlotIndex,
  getMonthDays: () => getMonthDays,
  getMonthLabel: () => getMonthLabel,
  getPriceColor: () => getPriceColor,
  getResourceCourtMeta: () => getResourceCourtMeta,
  getSlotTag: () => getSlotTag,
  getSuggestedStartHourIndex: () => getSuggestedStartHourIndex,
  getTableGridStyle: () => getTableGridStyle,
  getTimeMetaFromGrid: () => getTimeMetaFromGrid,
  getWeekDays: () => getWeekDays,
  getWeekdayShortLabel: () => getWeekdayShortLabel,
  isHourBoundary: () => isHourBoundary,
  minutesToTime: () => minutesToTime,
  pad: () => pad,
  parseDateKey: () => parseDateKey,
  timeToMinutes: () => timeToMinutes
});
module.exports = __toCommonJS(utils_exports);
var import_dayjs = __toESM(require("dayjs"));
var import_utils = require("@pisell/utils");
var SLOT_MINUTES = 30;
var SLOTS_PER_HOUR = 2;
var AUTO_VIEW_HOURS = 5;
var FIRST_COLUMN_WIDTH = 120;
var SLOT_MIN_WIDTH = 70;
function formatDateKey(date) {
  return date.format("YYYY-MM-DD");
}
function parseDateKey(key) {
  return (0, import_dayjs.default)(key);
}
function getWeekDays(anchor) {
  const weekStart = anchor.startOf("week");
  return Array.from({ length: 7 }, (_, i) => weekStart.add(i, "day"));
}
function getMonthLabel(date) {
  return date.format("MMMM YYYY");
}
function getMonthDays(date) {
  const firstOfMonth = date.startOf("month");
  const daysInMonth = date.daysInMonth();
  const firstDayOfWeek = firstOfMonth.day();
  const offset = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1;
  const cells = [];
  for (let i = 0; i < offset; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) {
    cells.push(firstOfMonth.date(d));
  }
  while (cells.length % 7 !== 0) cells.push(null);
  return cells;
}
function getWeekdayShortLabel(date) {
  const weekday = date.day();
  if (weekday === 1) return String(import_utils.locales.getText("pisell2.venue.calendar.weekday.short.mon") || "周一");
  if (weekday === 2) return String(import_utils.locales.getText("pisell2.venue.calendar.weekday.short.tue") || "周二");
  if (weekday === 3) return String(import_utils.locales.getText("pisell2.venue.calendar.weekday.short.wed") || "周三");
  if (weekday === 4) return String(import_utils.locales.getText("pisell2.venue.calendar.weekday.short.thu") || "周四");
  if (weekday === 5) return String(import_utils.locales.getText("pisell2.venue.calendar.weekday.short.fri") || "周五");
  if (weekday === 6) return String(import_utils.locales.getText("pisell2.venue.calendar.weekday.short.sat") || "周六");
  return String(import_utils.locales.getText("pisell2.venue.calendar.weekday.short.sun") || "周日");
}
function pad(n) {
  return String(n).padStart(2, "0");
}
function timeToMinutes(time) {
  const [h, m] = time.split(":").map(Number);
  return h * 60 + m;
}
function minutesToTime(minutes) {
  return `${pad(Math.floor(minutes / 60))}:${pad(minutes % 60)}`;
}
function isHourBoundary(slot) {
  return slot.endsWith(":00");
}
function formatHourHeader(slot) {
  const [hour] = slot.split(":").map(Number);
  const suffix = hour >= 12 ? import_utils.locales.getText("pisell2.venue.time.pm") || "pm" : import_utils.locales.getText("pisell2.venue.time.am") || "am";
  const hour12 = hour % 12 === 0 ? 12 : hour % 12;
  const template = import_utils.locales.getText("pisell2.venue.time.hour.format") || "{hour}{suffix}";
  return template.replace("{hour}", String(hour12)).replace("{suffix}", suffix);
}
function buildHourGroups(timeLabels) {
  return timeLabels.filter((slot) => slot.endsWith(":00"));
}
function getDateMetaFromSummary(date, dateSummary, symbol = "$") {
  const dateKey = formatDateKey(date);
  const item = dateSummary.find((s) => s.date === dateKey);
  if (!item) {
    return { topTag: null, startingPrice: null, fewLeft: false, soldOut: true, unavailable: true };
  }
  const soldOut = item.status === "sold_out" || item.status === "unavailable";
  const fewLeft = item.status === "few_left";
  const unavailable = item.status === "unavailable";
  const startingPrice = item.startingPrice ? `${symbol}${item.startingPrice}+` : null;
  return {
    topTag: null,
    // API 暂不返回 topTag，后续可扩展
    startingPrice: soldOut || unavailable ? null : startingPrice,
    fewLeft,
    soldOut,
    unavailable
  };
}
function getResourceCourtMeta(resource) {
  const total = resource.slots.length;
  const availableCount = resource.slots.filter((s) => s.status === "available").length;
  const ratio = total > 0 ? availableCount / total : 0;
  return {
    soldOut: availableCount === 0,
    fewLeft: availableCount > 0 && ratio < 0.2
  };
}
function getTimeMetaFromGrid(resources, slotIndex) {
  const availableCount = resources.filter(
    (r) => r.slots[slotIndex] && r.slots[slotIndex].status === "available"
  ).length;
  const ratio = resources.length > 0 ? availableCount / resources.length : 0;
  return {
    soldOut: availableCount === 0,
    fewLeft: availableCount > 0 && ratio < 0.2
  };
}
function buildSlotPriceInfo(slot) {
  const price = slot.price ? parseFloat(slot.price) : 0;
  return {
    price,
    originalPrice: null,
    label: "",
    // 后续可从 API 扩展标签信息
    highlight: false
  };
}
function getPriceColor(params) {
  if (params.highlight) return "text-emerald-600";
  if (params.courtType === "Pickleball") return "vb-primary-text";
  return "text-zinc-800";
}
function getSlotTag(priceInfo) {
  if (priceInfo.highlight || priceInfo.label === "Promo") {
    return {
      text: "pisell2.venue.label.promo",
      className: "bg-emerald-50 text-emerald-700 ring-emerald-200"
    };
  }
  if (priceInfo.label === "Off-Peak") {
    return {
      text: "pisell2.venue.label.off.peak",
      className: "bg-zinc-100 text-zinc-600 ring-zinc-200"
    };
  }
  return null;
}
function getColumnTag(resources, slotIndex) {
  return null;
}
function getTableGridStyle(slotCount) {
  return {
    gridTemplateColumns: `${FIRST_COLUMN_WIDTH}px repeat(${slotCount}, minmax(${SLOT_MIN_WIDTH}px, 1fr))`,
    minWidth: `${FIRST_COLUMN_WIDTH + slotCount * SLOT_MIN_WIDTH}px`,
    width: "100%"
  };
}
function getFirstAvailableSlotIndex(grid) {
  if (!grid) return 0;
  for (let i = 0; i < grid.timeLabels.length; i++) {
    const hasAvailable = grid.resources.some(
      (r) => r.slots[i] && r.slots[i].status === "available"
    );
    if (hasAvailable) return i;
  }
  return 0;
}
function getSuggestedStartHourIndex(params) {
  const { firstAvailableIndex, totalHours } = params;
  const earliestHour = Math.floor(firstAvailableIndex / SLOTS_PER_HOUR) + 1;
  const maxStartHour = Math.max(1, totalHours - AUTO_VIEW_HOURS + 1);
  if (earliestHour <= AUTO_VIEW_HOURS) return 1;
  return Math.max(1, Math.min(maxStartHour, earliestHour));
}
function formatRange(start, end) {
  return `${start} - ${end}`;
}
function getDateDisplay(dateKey) {
  return (0, import_dayjs.default)(dateKey).format("ddd, D MMM YYYY");
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  AUTO_VIEW_HOURS,
  FIRST_COLUMN_WIDTH,
  SLOTS_PER_HOUR,
  SLOT_MINUTES,
  SLOT_MIN_WIDTH,
  buildHourGroups,
  buildSlotPriceInfo,
  formatDateKey,
  formatHourHeader,
  formatRange,
  getColumnTag,
  getDateDisplay,
  getDateMetaFromSummary,
  getFirstAvailableSlotIndex,
  getMonthDays,
  getMonthLabel,
  getPriceColor,
  getResourceCourtMeta,
  getSlotTag,
  getSuggestedStartHourIndex,
  getTableGridStyle,
  getTimeMetaFromGrid,
  getWeekDays,
  getWeekdayShortLabel,
  isHourBoundary,
  minutesToTime,
  pad,
  parseDateKey,
  timeToMinutes
});
