function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
/**
 * 画布日历：sceneElements 顺序资源行 + floorDayBooking 列表 → RecordBoard 日历受控数据。
 */
import dayjs from 'dayjs';
import { sceneElementsToBoundRecordIdStrings } from "../floorMap/floorMapBoundRecordIds";
import { customerBrief, extractResourceRecordIds } from "./bookingToReservationTables";
function parseBookingStart(b) {
  var raw = b.start_at || (b.start_date && b.start_time ? "".concat(b.start_date, " ").concat(b.start_time) : '');
  if (!raw) return null;
  var d = dayjs(raw);
  return d.isValid() ? d : null;
}
function parseBookingEnd(b) {
  var raw = b.end_at || (b.end_date && b.end_time ? "".concat(b.end_date, " ").concat(b.end_time) : '');
  if (!raw) return null;
  var d = dayjs(raw);
  return d.isValid() ? d : null;
}
function calendarDisplayEnd(b, start) {
  var _ref, _ref2, _b$status;
  var explicit = parseBookingEnd(b);
  if (explicit) return explicit;
  var st = String((_ref = (_ref2 = (_b$status = b.status) !== null && _b$status !== void 0 ? _b$status : b.booking_status) !== null && _ref2 !== void 0 ? _ref2 : b.order_status) !== null && _ref !== void 0 ? _ref : '').trim().toLowerCase();
  if (st === 'occupied' || st === 'locked') {
    return start.endOf('day');
  }
  return start.add(2, 'hour');
}
function isAggregateParentShell(booking) {
  var meta = booking.metadata;
  if ((meta === null || meta === void 0 ? void 0 : meta.multiple_resource_flag) !== 1) return false;
  var uid = booking.product_uid;
  if (uid != null && String(uid) !== '') return false;
  var res = booking.resources;
  return !Array.isArray(res) || res.length === 0;
}
function statusToCalendarTag(b) {
  var _ref3, _ref4, _b$status2;
  var st = String((_ref3 = (_ref4 = (_b$status2 = b.status) !== null && _b$status2 !== void 0 ? _b$status2 : b.booking_status) !== null && _ref4 !== void 0 ? _ref4 : b.order_status) !== null && _ref3 !== void 0 ? _ref3 : '').trim().toLowerCase();
  if (st === 'locked') return 'block';
  if (st === 'occupied') return 'checked_in';
  if (st === 'reserved') {
    var _b$reserved_status;
    var rs = String((_b$reserved_status = b.reserved_status) !== null && _b$reserved_status !== void 0 ? _b$reserved_status : '');
    if (rs === 'late') return 'late';
    return 'new';
  }
  return undefined;
}
function fractionHourOf(d, dayStart) {
  return d.diff(dayStart, 'minute', true) / 60;
}

/** 日历浮点小时 → dayjs（与 RecordBoard `dayAndHourToDayjs` 一致） */
export function dayjsFromCalendarHour(dateStr, hourFloat) {
  var h = Math.floor(hourFloat);
  var m = Math.round((hourFloat - h) * 60);
  var mm = Math.min(59, Math.max(0, m));
  return dayjs("".concat(dateStr, " ").concat(String(h).padStart(2, '0'), ":").concat(String(mm).padStart(2, '0')), 'YYYY-MM-DD HH:mm');
}

/** 与 {@link sceneElementsToBoundRecordIdStrings} 同序：画布已绑定资源 id（string），与预约 `relation_id` 对齐 */
export function orderedCanvasResourceRecordIdStrings(sceneElements, gridDataSourceKey) {
  return sceneElementsToBoundRecordIdStrings(sceneElements, gridDataSourceKey);
}
export function buildCalendarResourcesFromMergedTables(options) {
  var orderedResourceIds = options.orderedResourceIds,
    tables = options.tables;
  var byId = new Map(tables.map(function (r) {
    return [String(r.id), r];
  }));
  return orderedResourceIds.map(function (id) {
    var row = byId.get(id);
    return {
      id: id,
      name: (row === null || row === void 0 ? void 0 : row.code) || (row === null || row === void 0 ? void 0 : row.main_field) || id,
      groupType: row === null || row === void 0 ? void 0 : row.area,
      form_id: id
    };
  });
}

/**
 * 在合并后的 `tables` 中查找与宿主 raw booking 对应的行（用于详情弹窗）。
 */
export function findMergedTableRowForBookingRaw(raw, tables) {
  var _ref5, _ref6, _raw$booking_id;
  var bid = String((_ref5 = (_ref6 = (_raw$booking_id = raw.booking_id) !== null && _raw$booking_id !== void 0 ? _raw$booking_id : raw.booking_uid) !== null && _ref6 !== void 0 ? _ref6 : raw.id) !== null && _ref5 !== void 0 ? _ref5 : '').trim();
  if (!bid) return undefined;
  var _iterator = _createForOfIteratorHelper(tables),
    _step;
  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var row = _step.value;
      var list = row.floorMapSourceBookings;
      if (!Array.isArray(list)) continue;
      if (list.some(function (bk) {
        var _r$id, _r$booking_id, _r$booking_uid;
        var r = bk;
        var id = String((_r$id = r.id) !== null && _r$id !== void 0 ? _r$id : '').trim();
        var bookingId = String((_r$booking_id = r.booking_id) !== null && _r$booking_id !== void 0 ? _r$booking_id : '').trim();
        var bookingUid = String((_r$booking_uid = r.booking_uid) !== null && _r$booking_uid !== void 0 ? _r$booking_uid : '').trim();
        return id === bid || bookingId === bid || bookingUid === bid;
      })) {
        return row;
      }
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }
  return undefined;
}

/**
 * 在已匹配到的 `tableRow.floorMapSourceBookings` 中取出与 `raw` 同一条预约的那条数据（引用随合并刷新）。
 * 供详情弹窗在收到实时推送、合并 tables 后同步更新内容。
 */
export function extractFloorMapSourceBookingForRow(raw, row) {
  var _ref7, _ref8, _raw$booking_id2;
  var bid = String((_ref7 = (_ref8 = (_raw$booking_id2 = raw.booking_id) !== null && _raw$booking_id2 !== void 0 ? _raw$booking_id2 : raw.booking_uid) !== null && _ref8 !== void 0 ? _ref8 : raw.id) !== null && _ref7 !== void 0 ? _ref7 : '').trim();
  if (!bid) return undefined;
  var list = row.floorMapSourceBookings;
  if (!Array.isArray(list)) return undefined;
  var _iterator2 = _createForOfIteratorHelper(list),
    _step2;
  try {
    for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
      var _r$id2, _r$booking_id2, _r$booking_uid2;
      var bk = _step2.value;
      if (!bk || _typeof(bk) !== 'object') continue;
      var r = bk;
      var id = String((_r$id2 = r.id) !== null && _r$id2 !== void 0 ? _r$id2 : '').trim();
      var bookingId = String((_r$booking_id2 = r.booking_id) !== null && _r$booking_id2 !== void 0 ? _r$booking_id2 : '').trim();
      var bookingUid = String((_r$booking_uid2 = r.booking_uid) !== null && _r$booking_uid2 !== void 0 ? _r$booking_uid2 : '').trim();
      if (id === bid || bookingId === bid || bookingUid === bid) {
        return r;
      }
    }
  } catch (err) {
    _iterator2.e(err);
  } finally {
    _iterator2.f();
  }
  return undefined;
}

/**
 * 将 GET booking 列表（与 floorDayBookingData 一致）映射为日历条；仅画布已绑定资源。
 *
 * 跨日 booking 不再按天切片：每个 (booking × resourceId) 只产出 1 条带 `endDate` 的 item，
 * 由日历视图层（日 / 周 / 月 / 资源）按整段做 absolute overlay，pill 一条连续。
 * 单日 booking（start/end 同一营业日）`endDate === date`，行为与旧版一致。
 */
export function mapFloorDayBookingsToCalendarItems(options) {
  var bookings = options.bookings,
    canvasResourceIdSet = options.canvasResourceIdSet;
  if (!Array.isArray(bookings)) return [];

  /** 集合为空时不再按画布过滤（与顶栏「tables 回退列 id」等策略一致，避免交集被误杀） */
  var filterByCanvas = canvasResourceIdSet.size > 0;
  var out = [];
  var seq = 0;
  var _iterator3 = _createForOfIteratorHelper(bookings),
    _step3;
  try {
    for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
      var _ref9, _b$relation_form_name, _ref10, _b$phone, _ref11, _b$booking_id, _ref12, _ref13, _b$status3;
      var raw = _step3.value;
      if (!raw || _typeof(raw) !== 'object') continue;
      var b = raw;
      // 不再用 `isMonitorScheduleBookingSkipped`：那是给资源墙 / monitor schedule 用的「白名单」过滤
      // （只保留 reserved/occupied/locked），但日历视图在非 SSE 路径（compact_fields 关闭）下后端
      // 返回的 `status` 字段统一是 'normal'，真实状态在 `appointment_status` 里 → 全部被白名单过滤
      // → 日视图全空。日历需要展示所有非聚合壳的 booking（取消/迟到等仍带徽标显示）。
      if (isAggregateParentShell(b)) continue;
      var rids = extractResourceRecordIds(b).filter(function (id) {
        return filterByCanvas ? canvasResourceIdSet.has(id) : Boolean(id);
      });
      if (rids.length === 0) continue;
      var start = parseBookingStart(b);
      if (!start) continue;
      var end = calendarDisplayEnd(b, start);
      if (!end.isAfter(start)) continue;
      var name = customerBrief(b) || String((_ref9 = (_b$relation_form_name = b.relation_form_name) !== null && _b$relation_form_name !== void 0 ? _b$relation_form_name : b.booking_id) !== null && _ref9 !== void 0 ? _ref9 : 'Booking');
      var phoneRaw = (_ref10 = (_b$phone = b.phone) !== null && _b$phone !== void 0 ? _b$phone : b.mobile) !== null && _ref10 !== void 0 ? _ref10 : b.customer_phone;
      var phone = typeof phoneRaw === 'string' ? phoneRaw : undefined;
      var statusTag = statusToCalendarTag(b);
      var baseId = String((_ref11 = (_b$booking_id = b.booking_id) !== null && _b$booking_id !== void 0 ? _b$booking_id : b.id) !== null && _ref11 !== void 0 ? _ref11 : "bk_".concat(seq++));
      var statusNorm = String((_ref12 = (_ref13 = (_b$status3 = b.status) !== null && _b$status3 !== void 0 ? _b$status3 : b.booking_status) !== null && _ref13 !== void 0 ? _ref13 : b.order_status) !== null && _ref12 !== void 0 ? _ref12 : '').trim().toLowerCase();
      var kind = statusNorm === 'locked' ? 'block' : 'booking';

      /**
       * 起始 / 结束日（自然日）+ 各自小时（含小数 0.5 步进）。
       * `endHour` 为 24 的特殊情况：当 booking 结束于次日 00:00（即恰好跨日切线），
       * 把它归到前一天的 24:00 而不是次日的 0:00，保持「区间右开」的语义直观。
       *
       * 营业日跨自然日（`operating_day_boundary` 不为 00:00）的对齐由日视图
       * `buildOverlayBookings` 在 grid 上对早段 booking 做 +24 偏移处理；
       * 此处保持自然日语义。
       */
      var startDayStart = start.startOf('day');
      var startHour = fractionHourOf(start, startDayStart);
      var endDayStart = end.startOf('day');
      var endIsExactMidnight = end.hour() === 0 && end.minute() === 0 && end.second() === 0;
      var effectiveEndDayStart = endIsExactMidnight ? endDayStart.subtract(1, 'day') : endDayStart;
      var endHour = endIsExactMidnight ? 24 : fractionHourOf(end, effectiveEndDayStart);
      var dateStr = startDayStart.format('YYYY-MM-DD');
      var endDateStr = effectiveEndDayStart.format('YYYY-MM-DD');
      var _iterator4 = _createForOfIteratorHelper(rids),
        _step4;
      try {
        for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
          var courtId = _step4.value;
          out.push({
            id: "".concat(baseId, "_").concat(courtId),
            courtId: courtId,
            date: dateStr,
            startHour: startHour,
            endDate: endDateStr === dateStr ? undefined : endDateStr,
            endHour: endHour,
            name: name,
            kind: kind,
            phone: phone,
            statusTag: statusTag,
            raw: b
          });
        }
      } catch (err) {
        _iterator4.e(err);
      } finally {
        _iterator4.f();
      }
    }

    // 去重：同 id 只保留首条，避免上游接口重复给同 booking_id 时日历拿到两条
    // (court, booking_id) 相同的 item 进入 lane 抢占后被压到同一 lane 上重叠渲染。
  } catch (err) {
    _iterator3.e(err);
  } finally {
    _iterator3.f();
  }
  var seen = new Set();
  var dedup = [];
  for (var _i = 0, _out = out; _i < _out.length; _i++) {
    var it = _out[_i];
    if (seen.has(it.id)) continue;
    seen.add(it.id);
    dedup.push(it);
  }
  return dedup;
}