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/plus/pisellReservation/floorRoomCard/mapRowToFloorRoomCardData.ts
var mapRowToFloorRoomCardData_exports = {};
__export(mapRowToFloorRoomCardData_exports, {
  buildDetailModalRoomCardData: () => buildDetailModalRoomCardData,
  isReservationPlaceholderCustomerId: () => isReservationPlaceholderCustomerId,
  mapPisellReservationRowToFloorRoomCardData: () => mapPisellReservationRowToFloorRoomCardData,
  rawToBooking: () => rawToBooking,
  resolveBookingCardAmount: () => resolveBookingCardAmount,
  resolveBookingIdForHeader: () => resolveBookingIdForHeader,
  resolveBookingProductQuantity: () => resolveBookingProductQuantity,
  resolveBookingStripIdForUi: () => resolveBookingStripIdForUi,
  resolveFloorRoomCardHolder: () => resolveFloorRoomCardHolder
});
module.exports = __toCommonJS(mapRowToFloorRoomCardData_exports);
var import_dayjs = __toESM(require("dayjs"));
var import_floorRoomCardUtils = require("./floorRoomCardUtils");
function coerceHhMm(raw) {
  if (raw == null) return null;
  const s = String(raw).trim();
  if (!s) return null;
  const m = s.match(/^(\d{1,2}):(\d{2})/);
  if (!m) return null;
  return `${m[1].padStart(2, "0")}:${m[2]}`;
}
function coerceYmd(raw) {
  if (raw == null) return null;
  const s = String(raw).trim();
  const head = s.slice(0, 10);
  if (/^\d{4}-\d{2}-\d{2}$/.test(head)) return head;
  const d = (0, import_dayjs.default)(s);
  return d.isValid() ? d.format("YYYY-MM-DD") : null;
}
function coerceHostMinutesField(raw) {
  if (raw == null || raw === "") return void 0;
  const n = typeof raw === "number" ? raw : Number(String(raw).trim());
  if (!Number.isFinite(n) || n < 0) return void 0;
  return Math.round(n);
}
function coerceHostProgressPercent(raw) {
  if (raw == null || raw === "") return void 0;
  const n = typeof raw === "number" ? raw : Number(String(raw).trim());
  if (!Number.isFinite(n)) return void 0;
  return Math.min(100, Math.max(0, Math.round(n)));
}
function parseOrderCustomerId(raw) {
  if (raw == null || raw === "") return null;
  const n = typeof raw === "number" ? raw : Number(String(raw).trim());
  return Number.isFinite(n) ? n : null;
}
function parseBookingOrderCustomerId(order) {
  if (!order) return null;
  const top = parseOrderCustomerId(order.customer_id);
  if (top != null) return top;
  const cust = order.customer;
  if (cust && typeof cust === "object") {
    return parseOrderCustomerId(cust.id);
  }
  return null;
}
function isReservationPlaceholderCustomerId(order) {
  const n = parseBookingOrderCustomerId(order);
  return n === 0 || n === 1;
}
function isRealOrderCustomer(order) {
  const n = parseBookingOrderCustomerId(order);
  if (n == null) return false;
  return n !== 0 && n !== 1;
}
function coalesceSummaryAmount(v) {
  if (v == null || v === "") return null;
  if (typeof v === "number" && Number.isFinite(v)) return v;
  const s = String(v).trim();
  return s !== "" ? v : null;
}
function resolveBookingCardAmount(rawBooking, order, paymentStatusLower) {
  const pay = String(paymentStatusLower ?? "").trim().toLowerCase();
  const ord = order;
  const sum = ord == null ? void 0 : ord.summary;
  const fallbackChain = () => {
    const v = rawBooking.amount ?? rawBooking.total ?? rawBooking.grand_total ?? (ord == null ? void 0 : ord.total_amount) ?? (sum == null ? void 0 : sum.total_amount) ?? 0;
    return typeof v === "string" || typeof v === "number" ? v : 0;
  };
  if (pay === "paid") {
    const v = (sum == null ? void 0 : sum.total_amount) ?? (ord == null ? void 0 : ord.total_amount) ?? rawBooking.amount ?? rawBooking.total ?? fallbackChain();
    return typeof v === "string" || typeof v === "number" ? v : fallbackChain();
  }
  const needPayUsesTotal = pay === "payment_processing" || pay === "unpaid";
  if (needPayUsesTotal) {
    const fromTotal = coalesceSummaryAmount(sum == null ? void 0 : sum.total_amount);
    if (fromTotal != null) return fromTotal;
    const fromGap = coalesceSummaryAmount(sum == null ? void 0 : sum.amount_gap);
    if (fromGap != null) return fromGap;
    return fallbackChain();
  }
  const fromGapFirst = coalesceSummaryAmount(sum == null ? void 0 : sum.amount_gap);
  if (fromGapFirst != null) return fromGapFirst;
  const fromTotalSecond = coalesceSummaryAmount(sum == null ? void 0 : sum.total_amount);
  if (fromTotalSecond != null) return fromTotalSecond;
  return fallbackChain();
}
function countTopLevelProductLinesInRaw(rawBooking) {
  const p = rawBooking.products;
  if (!Array.isArray(p)) return null;
  return p.filter((x) => x && typeof x === "object").length;
}
function parseSummaryProductQuantity(v) {
  if (v == null || v === "") return null;
  if (typeof v === "number" && Number.isFinite(v))
    return Math.max(0, Math.round(v));
  const n = Number(String(v).replace(/,/g, "").trim());
  return Number.isFinite(n) ? Math.max(0, Math.round(n)) : null;
}
function resolveBookingProductQuantity(rawBooking) {
  const fromArr = countTopLevelProductLinesInRaw(rawBooking);
  if (fromArr != null) return fromArr;
  const ord = rawBooking.order;
  const sum = ord == null ? void 0 : ord.summary;
  return parseSummaryProductQuantity(sum == null ? void 0 : sum.product_quantity) ?? 0;
}
function holderFromBookingHolderField(b) {
  const h = b.holder;
  if (h && typeof h === "object") {
    const name = typeof h.name === "string" ? h.name.trim() : "";
    let phone;
    if (typeof h.phone === "string" && /\d/.test(h.phone)) phone = h.phone;
    else {
      const po = h.phone;
      if (po && typeof po.phone === "string" && /\d/.test(po.phone))
        phone = po.phone;
    }
    if (name || phone) return { name, ...phone ? { phone } : {} };
  }
  const hd = b.holder_data;
  const hx = Array.isArray(hd) ? hd[0] : hd;
  if (hx && typeof hx === "object") {
    const ho = hx;
    if (typeof ho.name === "string" && ho.name.trim()) {
      return { name: ho.name.trim() };
    }
    const data = ho.data;
    const cn = data == null ? void 0 : data.customer_name;
    if (typeof cn === "string" && cn.trim()) {
      return { name: cn.trim() };
    }
  }
  return null;
}
function contactsInfoContact(order) {
  const ci = order.contacts_info;
  if (!ci || typeof ci !== "object") return null;
  const fn = typeof ci.first_name === "string" ? ci.first_name.trim() : "";
  const ln = typeof ci.last_name === "string" ? ci.last_name.trim() : "";
  const name = [fn, ln].filter(Boolean).join(" ");
  const phoneObj = ci.phone;
  const ph = phoneObj == null ? void 0 : phoneObj.phone;
  const phone = typeof ph === "string" && /\d/.test(ph) ? ph : void 0;
  if (!name && !phone) return null;
  return { name, ...phone ? { phone } : {} };
}
function resolveFloorRoomCardHolder(b) {
  const ord = b.order;
  if (isReservationPlaceholderCustomerId(ord)) {
    return void 0;
  }
  const rh = holderFromBookingHolderField(b);
  if (rh && (rh.name || rh.phone)) {
    return {
      name: rh.name,
      ...rh.phone ? { phone: rh.phone } : {}
    };
  }
  if (ord) {
    const ci = contactsInfoContact(ord);
    if (ci && (ci.name || ci.phone)) {
      return {
        name: ci.name,
        ...ci.phone ? { phone: ci.phone } : {}
      };
    }
  }
  if (ord && isRealOrderCustomer(ord)) {
    const cn = typeof ord.customer_name === "string" ? ord.customer_name.trim() : "";
    const topPhone = typeof ord.phone === "string" && /\d/.test(ord.phone) ? ord.phone : void 0;
    if (cn || topPhone) {
      return {
        name: cn,
        ...topPhone ? { phone: topPhone } : {}
      };
    }
    const cust = ord.customer;
    if (cust && typeof cust === "object") {
      const custName = typeof cust.name === "string" && cust.name.trim() || [cust.first_name, cust.last_name].filter(Boolean).join(" ").trim() || typeof cust.company_name === "string" && cust.company_name.trim() || "";
      const custPhoneRaw = cust.phone ?? cust.mobile;
      const custPhone = typeof custPhoneRaw === "string" && /\d/.test(custPhoneRaw) ? custPhoneRaw : void 0;
      if (custName || custPhone) {
        return {
          name: custName,
          ...custPhone ? { phone: custPhone } : {}
        };
      }
    }
  }
  return void 0;
}
function rawToBooking(b, index) {
  const orderBookingId = b.booking_id != null && String(b.booking_id) !== "" ? String(b.booking_id) : `b_${b.id ?? index}`;
  const recordIdRaw = b.id;
  const recordId = recordIdRaw != null && String(recordIdRaw).trim() !== "" ? String(recordIdRaw).trim() : void 0;
  const ord = b.order;
  const scheduleDateStr = typeof (ord == null ? void 0 : ord.schedule_date) === "string" ? ord.schedule_date.trim() : "";
  const startYmd = coerceYmd(b.start_date) ?? coerceYmd(b.select_date) ?? (scheduleDateStr ? coerceYmd(scheduleDateStr) : null) ?? coerceYmd(ord == null ? void 0 : ord.create_date);
  const scheduleTimeFromOrder = scheduleDateStr.includes(" ") ? coerceHhMm(scheduleDateStr.split(/\s+/).slice(-1)[0] ?? "") : null;
  const startHm = coerceHhMm(b.start_time) ?? scheduleTimeFromOrder ?? coerceHhMm(ord == null ? void 0 : ord.start_time);
  const endYmd = coerceYmd(b.end_date) ?? startYmd ?? coerceYmd(ord == null ? void 0 : ord.create_date);
  let endHm = coerceHhMm(b.end_time) ?? coerceHhMm(ord == null ? void 0 : ord.end_time);
  let startD = null;
  if (startYmd && startHm) {
    const t = (0, import_dayjs.default)(`${startYmd} ${startHm}`);
    if (t.isValid()) startD = t;
  }
  if (!startD && b.start_at) {
    const t = (0, import_dayjs.default)(String(b.start_at));
    if (t.isValid()) startD = t;
  }
  let endD = null;
  if (endYmd && endHm) {
    const t = (0, import_dayjs.default)(`${endYmd} ${endHm}`);
    if (t.isValid()) endD = t;
  }
  if (!endD && b.end_at) {
    const t = (0, import_dayjs.default)(String(b.end_at));
    if (t.isValid()) endD = t;
  }
  if (!endD && startD && typeof b.duration === "number" && Number.isFinite(b.duration) && String(b.sub_type) === "minutes") {
    const t = startD.add(b.duration, "minute");
    if (t.isValid()) endD = t;
  }
  if (!endD && startD) {
    endD = startD.add(2, "hour");
  }
  const startDateOut = (startD == null ? void 0 : startD.isValid()) ? startD.format("YYYY-MM-DD") : startYmd ?? "";
  const startTimeOut = (startD == null ? void 0 : startD.isValid()) ? startD.format("HH:mm") : startHm ?? "--:--";
  let endDateOut = (endD == null ? void 0 : endD.isValid()) ? endD.format("YYYY-MM-DD") : endYmd ?? startDateOut;
  let endTimeOut = (endD == null ? void 0 : endD.isValid()) ? endD.format("HH:mm") : endHm ?? "--:--";
  const num = b.number;
  const party = typeof num === "number" && Number.isFinite(num) ? num : Number(num) || 0;
  const lt = coerceHostMinutesField(b.lateTime);
  const tt = coerceHostMinutesField(b.timeoutTime);
  const rr = coerceHostMinutesField(b.remainingReserveTime);
  const pp = coerceHostProgressPercent(b.progressPercent);
  const rawOps = ord == null ? void 0 : ord.payment_status;
  const opsTrim = rawOps != null && String(rawOps).trim() !== "" ? String(rawOps).trim() : "";
  const opsLower = opsTrim.toLowerCase();
  const order_payment_status = opsTrim === "" ? void 0 : opsLower === "paid" ? "paid" : opsLower === "partially_paid" ? "unpaid" : opsTrim;
  const amt = resolveBookingCardAmount(b, ord, opsLower);
  const productQty = resolveBookingProductQuantity(b);
  const holder = resolveFloorRoomCardHolder(b);
  const hostBookingStatus = coerceHostBookingStatusForCard(b);
  const rawIsNext = b.is_next ?? b.isNext;
  const isNextMarked = rawIsNext === true || rawIsNext === "true" || rawIsNext === 1 || rawIsNext === "1";
  return {
    booking_id: orderBookingId,
    ...recordId ? { recordId } : {},
    start_date: startDateOut || startYmd || "",
    start_time: startTimeOut,
    end_date: endDateOut || startDateOut || "",
    end_time: endTimeOut,
    number: party,
    ...holder ? { holder } : {},
    ...hostBookingStatus ? { hostBookingStatus } : {},
    amount: typeof amt === "string" || typeof amt === "number" ? amt : 0,
    product_quantity: productQty,
    ...lt != null && lt > 0 ? { lateTime: lt } : {},
    ...tt != null && tt > 0 ? { timeoutTime: tt } : {},
    ...rr != null && rr > 0 ? { remainingReserveTime: rr } : {},
    ...pp !== void 0 ? { progressPercent: pp } : {},
    ...order_payment_status !== void 0 ? { order_payment_status } : {},
    ...isNextMarked ? { isNext: true } : {}
  };
}
function syntheticFromRow(row) {
  var _a, _b;
  const day = row.floorMapReferenceDay ?? (0, import_dayjs.default)().format("YYYY-MM-DD");
  const startT = (row.time ?? "12:00").trim().split(/\s+/)[0] ?? "12:00";
  const startD = (0, import_dayjs.default)(`${day} ${startT}`);
  let endD;
  if ((_a = row.timeEnd) == null ? void 0 : _a.trim()) {
    const et = row.timeEnd.trim().split(/\s+/)[0];
    endD = (0, import_dayjs.default)(`${day} ${et}`);
    if (!endD.isValid() || endD.valueOf() <= startD.valueOf()) {
      endD = startD.add(2, "hour");
    }
  } else {
    endD = startD.add(2, "hour");
  }
  const guestPhone = row.guestPhone && !row.guestPhone.includes("*") ? row.guestPhone : void 0;
  const displayName = ((_b = row.guestName) == null ? void 0 : _b.trim()) ?? "";
  const holderFromRow = displayName || guestPhone ? {
    name: displayName,
    ...guestPhone ? { phone: guestPhone } : {}
  } : void 0;
  const amt = row.priceDisplay ?? 0;
  const startsIn = row.startsInMinutes != null && Number.isFinite(row.startsInMinutes) && row.startsInMinutes > 0 ? Math.round(row.startsInMinutes) : void 0;
  const rowLateMin = row.lateMinutes != null && Number.isFinite(row.lateMinutes) && row.lateMinutes > 0 ? Math.round(row.lateMinutes) : void 0;
  const rowDelayMin = row.delayMinutes != null && Number.isFinite(row.delayMinutes) && row.delayMinutes > 0 ? Math.round(row.delayMinutes) : void 0;
  const synHost = row.cardStatus === "occupied" || row.cardStatus === "barBusy" ? "occupied" : row.cardStatus === "booked" ? "reserved" : void 0;
  return {
    booking_id: `syn_${row.id}`,
    start_date: startD.format("YYYY-MM-DD"),
    start_time: startD.format("HH:mm"),
    end_date: endD.format("YYYY-MM-DD"),
    end_time: endD.format("HH:mm"),
    number: row.partySize ?? 0,
    ...holderFromRow ? { holder: holderFromRow } : {},
    amount: amt,
    product_quantity: 0,
    ...startsIn != null ? { remainingReserveTime: startsIn } : {},
    ...rowLateMin != null ? { lateTime: rowLateMin } : {},
    ...rowDelayMin != null ? { timeoutTime: rowDelayMin } : {},
    ...synHost ? { hostBookingStatus: synHost } : {},
    /** 与行上 isPaid 一致，避免仅因无 order 对象时缺省成「未付」红字（迟到与时间态无关） */
    ...row.isPaid === true ? { order_payment_status: "paid" } : {},
    ...row.isNext === true ? { isNext: true } : {}
  };
}
function syntheticFromSlot(row, slot, index) {
  const day = row.floorMapReferenceDay ?? (0, import_dayjs.default)().format("YYYY-MM-DD");
  const t = slot.time.replace(/ .*/, "").trim() || "12:00";
  const startD = (0, import_dayjs.default)(`${day} ${t}`);
  const endD = startD.add(2, "hour");
  const sn = slot.name.trim();
  return {
    booking_id: `slot_${index}`,
    start_date: startD.format("YYYY-MM-DD"),
    start_time: startD.format("HH:mm"),
    end_date: endD.format("YYYY-MM-DD"),
    end_time: endD.format("HH:mm"),
    number: row.partySize ?? 0,
    ...sn ? { holder: { name: sn } } : {},
    amount: 0,
    product_quantity: 0,
    hostBookingStatus: "reserved"
  };
}
function normalizeHostBookingStatus(b) {
  return String(b.status ?? "").trim().toLowerCase();
}
function coerceHostBookingStatusForCard(b) {
  const s = normalizeHostBookingStatus(b);
  if (s === "reserved" || s === "occupied" || s === "locked" || s === "empty") {
    return s;
  }
  return void 0;
}
function floorSourceHasOccupiedStatus(list) {
  return (list == null ? void 0 : list.some((b) => normalizeHostBookingStatus(b) === "occupied")) ?? false;
}
function floorSourceHasReservedStatus(list) {
  return (list == null ? void 0 : list.some((b) => normalizeHostBookingStatus(b) === "reserved")) ?? false;
}
function mapPisellReservationRowToFloorRoomCardData(row, roomTitle) {
  var _a, _b;
  const cap = row.capacityLabel != null && String(row.capacityLabel).trim() !== "" ? row.capacityLabel : "—";
  const title = roomTitle.trim() || row.code || "";
  if (row.cardStatus === "maintenance") {
    return {
      main_field: title,
      capacity: cap,
      status: "locked",
      sub_status: "",
      bookings: []
    };
  }
  if (row.cardStatus === "available") {
    return {
      main_field: title,
      capacity: cap,
      status: "empty",
      sub_status: "",
      bookings: []
    };
  }
  let bookings = [];
  if ((_a = row.floorMapSourceBookings) == null ? void 0 : _a.length) {
    bookings = row.floorMapSourceBookings.map(
      (b, i) => rawToBooking(b, i)
    );
  } else if ((_b = row.slots) == null ? void 0 : _b.length) {
    bookings = row.slots.map((s, i) => syntheticFromSlot(row, s, i));
  } else {
    bookings = [syntheticFromRow(row)];
  }
  const rawFloorSource = row.floorMapSourceBookings;
  let useOccupiedCard = row.cardStatus === "occupied" || row.cardStatus === "barBusy";
  let useBookedCard = row.cardStatus === "booked";
  if (rawFloorSource == null ? void 0 : rawFloorSource.length) {
    if (floorSourceHasOccupiedStatus(rawFloorSource)) {
      useOccupiedCard = true;
    } else {
      useOccupiedCard = false;
      if (floorSourceHasReservedStatus(rawFloorSource)) useBookedCard = true;
    }
  }
  if (useOccupiedCard) {
    let sub = "payed";
    if (row.hostIsTimeout === true || row.delayMinutes != null && row.delayMinutes > 0) {
      sub = "timeout";
    } else if (row.isPaid === false) {
      sub = "payment_required";
    } else {
      sub = "payed";
    }
    const occupiedBookings = bookings.length > 1 ? (0, import_floorRoomCardUtils.reorderBookingsForSingleOccupiedPrimary)(bookings) : bookings;
    return {
      main_field: title,
      capacity: cap,
      status: "occupied",
      sub_status: sub,
      bookings: occupiedBookings
    };
  }
  if (useBookedCard) {
    let sub = "not_arrived";
    if (row.hostReservedStatus === "late") sub = "late";
    else if (row.hostReservedStatus === "not_arrived") sub = "not_arrived";
    else if (row.lateMinutes != null && row.lateMinutes > 0) sub = "late";
    const reservedBookings = bookings.length > 1 ? (0, import_floorRoomCardUtils.reorderBookingsAllReservedChronological)(bookings) : bookings;
    return {
      main_field: title,
      capacity: cap,
      status: "reserved",
      sub_status: sub,
      bookings: reservedBookings
    };
  }
  return {
    main_field: title,
    capacity: cap,
    status: "empty",
    sub_status: "",
    bookings: []
  };
}
function resolveBookingStripIdForUi(raw) {
  const order = raw.order ?? {};
  const pick = (v) => v != null && String(v).trim() !== "" ? String(v).trim() : "";
  return pick(raw.booking_id) || pick(raw.id) || pick(order.shop_full_order_number) || pick(order.order_number) || "—";
}
function resolveBookingIdForHeader(raw) {
  const pick = (v) => v != null && String(v).trim() !== "" ? String(v).trim() : "";
  return pick(raw.booking_id) || pick(raw.booking_uid) || pick(raw.id) || "—";
}
function buildDetailModalRoomCardData(raw, tableRow) {
  const base = tableRow ?? {
    id: String(
      raw.id ?? raw.booking_uid ?? raw.booking_id ?? "modal-booking"
    ),
    code: (() => {
      const bid = raw.booking_id;
      const rid = raw.id;
      const s = bid != null && String(bid).trim() !== "" ? String(bid).trim() : rid != null && String(rid).trim() !== "" ? String(rid).trim() : "";
      return s || "—";
    })(),
    cardStatus: "booked"
  };
  const merged = {
    ...base,
    floorMapSourceBookings: [raw]
  };
  const title = resolveBookingStripIdForUi(raw);
  return mapPisellReservationRowToFloorRoomCardData(merged, title);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  buildDetailModalRoomCardData,
  isReservationPlaceholderCustomerId,
  mapPisellReservationRowToFloorRoomCardData,
  rawToBooking,
  resolveBookingCardAmount,
  resolveBookingIdForHeader,
  resolveBookingProductQuantity,
  resolveBookingStripIdForUi,
  resolveFloorRoomCardHolder
});
