const require_objectSpread2 = require("../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
const require_floorRoomCardUtils = require("../floorRoomCard/floorRoomCardUtils.js");
const require_mapRowToFloorRoomCardData = require("../floorRoomCard/mapRowToFloorRoomCardData.js");
//#region src/plus/pisellReservation/data/mapReservationToVenueWallCards.ts
/**
* 合并桌位行 → 大屏资源墙卡片（首版：与平面图/列表展示字段对齐，灯控等可后续接接口）。
*
* **整分钟边界**：状态切换按「日程写在 HH:mm 的整分」对齐——例如结束 9:00 时 9:00 整段仍非 overtime，
* 从 9:01 起 expired；开始 8:00 时 8:00 整段仍 boardingSoon，从 8:01 起 late（见 floorRoomCardUtils 同名工具）。
*
* **大屏 Current / Next**：仅按预约起止时间与当前时刻划分，不用接口 `is_next` / `isNext`。
*/
function mapReservationRowsToVenueWallCards(rows) {
	return rows.map(mapReservationTableRowToVenueWallCard);
}
function formatResourceWallContactLine(row) {
	const data = require_mapRowToFloorRoomCardData.mapPisellReservationRowToFloorRoomCardData(row, String(row.code || row.main_field || row.id || "").trim());
	const primary = require_floorRoomCardUtils.getFloorRoomCardPrimaryBooking(data);
	const showPhoneOnRow = row.cardStatus === "booked";
	const primaryLine = primary ? require_floorRoomCardUtils.formatFloorRoomCardGuestDisplayLine(primary, showPhoneOnRow).trim() : "";
	if (primaryLine) return primaryLine;
	/**
	* 兜底：主 booking 未带 holder 时，尝试从同资源 bookings 中找第一条可展示的联系人。
	* 仍复用同一套格式化规则，但允许展示脱敏手机号，避免回退成场地名。
	*/
	for (const b of data.bookings) {
		const t = require_floorRoomCardUtils.formatFloorRoomCardGuestDisplayLine(b, showPhoneOnRow).trim();
		if (t) return t;
	}
	/** 无联系人可展示：不要回退成场地名，保持为空 */
	return "";
}
/**
* 与 {@link formatResourceWallContactLine} 一致：先按行态 `showPhone`，再允许脱敏手机号；
* 若模型上 holder 仍空，再对命中的 floor raw 走同一套 `resolveFloorRoomCardHolder`（与 rawToBooking 同源）。
*/
function formatResourceWallNextBookingGuestLine(row, nextBooking) {
	const showPhoneOnRow = row.cardStatus === "booked";
	const fromModel = require_floorRoomCardUtils.formatFloorRoomCardGuestDisplayLine(nextBooking, showPhoneOnRow).trim() || require_floorRoomCardUtils.formatFloorRoomCardGuestDisplayLine(nextBooking, true).trim();
	if (fromModel) return fromModel;
	const raw = resolveFloorRawForNextBooking(row, nextBooking);
	if (raw) {
		const h = require_mapRowToFloorRoomCardData.resolveFloorRoomCardHolder(raw);
		const fromRaw = require_floorRoomCardUtils.formatFloorRoomCardGuestDisplayLineFromHolder(h, showPhoneOnRow).trim() || require_floorRoomCardUtils.formatFloorRoomCardGuestDisplayLineFromHolder(h, true).trim();
		if (fromRaw) return fromRaw;
	}
	return require_floorRoomCardUtils.formatFloorRoomCardNextGuestStripLine(nextBooking).trim();
}
/** 在 `floorMapSourceBookings` 中定位 Next 对应 raw，供联系人解析与列表同源 */
function resolveFloorRawForNextBooking(row, nextBooking) {
	var _nextBooking$booking_;
	const src = row.floorMapSourceBookings;
	if (!Array.isArray(src) || src.length === 0) return void 0;
	const wantBid = String((_nextBooking$booking_ = nextBooking.booking_id) !== null && _nextBooking$booking_ !== void 0 ? _nextBooking$booking_ : "").trim();
	if (wantBid && !wantBid.startsWith("syn_")) {
		const byId = src.find((x) => {
			var _ref, _r$booking_id;
			const r = x;
			const id = String((_ref = (_r$booking_id = r.booking_id) !== null && _r$booking_id !== void 0 ? _r$booking_id : r.id) !== null && _ref !== void 0 ? _ref : "").trim();
			return id !== "" && id === wantBid;
		});
		if (byId) return byId;
	}
	return src.find((x) => {
		var _r$is_next;
		const r = x;
		const n = (_r$is_next = r.is_next) !== null && _r$is_next !== void 0 ? _r$is_next : r.isNext;
		return n === true || n === "true" || n === 1 || n === "1";
	});
}
function sortBookingsByStartAsc(bookings) {
	return [...bookings].sort((a, b) => {
		return require_floorRoomCardUtils.floorRoomCardBookingStartEndMs(a).start - require_floorRoomCardUtils.floorRoomCardBookingStartEndMs(b).start;
	});
}
/**
* 大屏专用：按时间段决定 Current / Next，不读 `isNext`。
* - 恰有一条进行中：展示 Current；若时间轴上还有下一条则同时展示 Next。
* - 无进行中、前一段已结束且下一段未开始（间隙）：仅展示 Next。
* - 多条时按开始时间排序后解析。
*/
function resolveVenueWallCurrentNextByTime(bookings, nowMs) {
	if (bookings.length === 0) return {
		mode: "empty",
		current: null,
		next: null
	};
	const s = sortBookingsByStartAsc(bookings);
	const activeIdx = s.findIndex((b) => require_floorRoomCardUtils.isFloorRoomCardBookingInProgress(b, nowMs));
	if (activeIdx >= 0) {
		const cur = s[activeIdx];
		const nx = activeIdx + 1 < s.length ? s[activeIdx + 1] : null;
		return {
			mode: nx ? "both" : "currentOnly",
			current: cur,
			next: nx
		};
	}
	const upcomingIdx = s.findIndex((b) => {
		const { start } = require_floorRoomCardUtils.floorRoomCardBookingStartEndMs(b);
		return Number.isFinite(start) && nowMs < start;
	});
	if (upcomingIdx >= 0) {
		const up = s[upcomingIdx];
		const { start: sUp } = require_floorRoomCardUtils.floorRoomCardBookingStartEndMs(up);
		if (upcomingIdx > 0) {
			const prev = s[upcomingIdx - 1];
			const { end: ePrev } = require_floorRoomCardUtils.floorRoomCardBookingStartEndMs(prev);
			if (Number.isFinite(ePrev) && nowMs >= ePrev && Number.isFinite(sUp) && nowMs < sUp) return {
				mode: "nextOnly",
				current: null,
				next: up
			};
		}
		const nx = upcomingIdx + 1 < s.length ? s[upcomingIdx + 1] : null;
		return {
			mode: nx ? "both" : "single",
			current: up,
			next: nx
		};
	}
	return {
		mode: "empty",
		current: null,
		next: null
	};
}
function buildNextListEntry(row, nextBooking, nowMs) {
	const booking = formatResourceWallNextBookingGuestLine(row, nextBooking).trim();
	const time = require_floorRoomCardUtils.formatFloorRoomCardBookingTimeRange(nextBooking).trim();
	const { start } = require_floorRoomCardUtils.floorRoomCardBookingStartEndMs(nextBooking);
	let startInMin = 0;
	if (Number.isFinite(start)) startInMin = Math.max(0, Math.ceil((start - nowMs) / 6e4));
	return {
		time: time || "—",
		booking: booking || "—",
		startInMin
	};
}
function applyStatusFromPrimaryBooking(primary, nowMs) {
	let status = "available";
	let remainingMin = void 0;
	let startsInMin = void 0;
	let lateMin = void 0;
	let sessionStartMs = void 0;
	let sessionEndMs = void 0;
	const host = primary.hostBookingStatus;
	if (host === "reserved") {
		const { start: s } = require_floorRoomCardUtils.floorRoomCardBookingStartEndMs(primary);
		if (Number.isFinite(s)) {
			const startMinuteMs = require_floorRoomCardUtils.reservationScheduleMinuteFloorMs(s);
			const lateThresholdMs = require_floorRoomCardUtils.reservationScheduleReservedLateThresholdMs(s);
			if (nowMs >= lateThresholdMs) {
				status = "late";
				lateMin = Math.max(0, Math.ceil((nowMs - lateThresholdMs) / 6e4));
			} else {
				status = "boardingSoon";
				startsInMin = Math.max(0, Math.ceil((startMinuteMs - nowMs) / 6e4));
			}
		} else status = "boardingSoon";
	} else if (host === "occupied") {
		const { start: s0, end: e } = require_floorRoomCardUtils.floorRoomCardBookingStartEndMs(primary);
		if (Number.isFinite(s0)) sessionStartMs = require_floorRoomCardUtils.reservationScheduleMinuteFloorMs(s0);
		if (Number.isFinite(e)) {
			const overtimeMs = require_floorRoomCardUtils.reservationScheduleOccupiedOvertimeThresholdMs(e);
			sessionEndMs = overtimeMs;
			const remainingNominalMin = Math.ceil((e - nowMs) / 6e4);
			remainingMin = Math.max(0, remainingNominalMin);
			const remainingUntilOvertimeMin = Math.ceil((overtimeMs - nowMs) / 6e4);
			if (nowMs >= overtimeMs) status = "expired";
			else if (remainingUntilOvertimeMin <= 10 && remainingUntilOvertimeMin > 0) status = "endingSoon";
			else status = "inUse";
		} else status = "inUse";
	}
	return {
		status,
		remainingMin,
		startsInMin,
		lateMin,
		sessionStartMs,
		sessionEndMs
	};
}
function mapReservationTableRowToVenueWallCard(row) {
	var _roomData$bookings;
	const { cardStatus } = row;
	const isAvailable = cardStatus === "available" || cardStatus === "maintenance";
	const nowMs = Date.now();
	const roomData = require_mapRowToFloorRoomCardData.mapPisellReservationRowToFloorRoomCardData(row, String(row.code || row.main_field || row.id || "").trim());
	const bookings = (_roomData$bookings = roomData.bookings) !== null && _roomData$bookings !== void 0 ? _roomData$bookings : [];
	let nextList = void 0;
	let wallUseNextLabelHideNextRow = void 0;
	let currentTime = "";
	let currentBookingDisplay = "";
	let statusPack = {
		status: "available",
		remainingMin: void 0,
		startsInMin: void 0,
		lateMin: void 0,
		sessionStartMs: void 0,
		sessionEndMs: void 0
	};
	if (bookings.length > 0) {
		const slot = resolveVenueWallCurrentNextByTime(bookings, nowMs);
		if (slot.mode === "nextOnly" && slot.next) {
			const b = slot.next;
			currentTime = require_floorRoomCardUtils.formatFloorRoomCardBookingTimeRange(b).trim();
			currentBookingDisplay = formatResourceWallNextBookingGuestLine(row, b).trim();
			if (!isAvailable) statusPack = applyStatusFromPrimaryBooking(b, nowMs);
			else statusPack = {
				status: "available",
				remainingMin: void 0,
				startsInMin: void 0,
				lateMin: void 0,
				sessionStartMs: void 0,
				sessionEndMs: void 0
			};
			nextList = void 0;
			wallUseNextLabelHideNextRow = true;
		} else if (slot.mode === "empty") {
			nextList = void 0;
			currentTime = "";
			currentBookingDisplay = "Available to Book";
			statusPack = {
				status: "available",
				remainingMin: void 0,
				startsInMin: void 0,
				lateMin: void 0,
				sessionStartMs: void 0,
				sessionEndMs: void 0
			};
		} else if (slot.current) {
			const primary = slot.current;
			const currentNotStarted = require_floorRoomCardUtils.isFloorRoomCardBookingNotStarted(primary, nowMs);
			currentTime = require_floorRoomCardUtils.formatFloorRoomCardBookingTimeRange(primary).trim();
			currentBookingDisplay = formatResourceWallNextBookingGuestLine(row, primary).trim();
			if (!isAvailable) statusPack = applyStatusFromPrimaryBooking(primary, nowMs);
			else statusPack = {
				status: "available",
				remainingMin: void 0,
				startsInMin: void 0,
				lateMin: void 0,
				sessionStartMs: void 0,
				sessionEndMs: void 0
			};
			if (slot.next && !currentNotStarted) nextList = [buildNextListEntry(row, slot.next, nowMs)];
			if (currentNotStarted) wallUseNextLabelHideNextRow = true;
		}
	} else {
		var _row$time, _row$timeEnd;
		const primary = require_floorRoomCardUtils.getFloorRoomCardPrimaryBooking(roomData);
		const currentTimeFromPrimary = primary ? require_floorRoomCardUtils.formatFloorRoomCardBookingTimeRange(primary).trim() : "";
		const start = String((_row$time = row.time) !== null && _row$time !== void 0 ? _row$time : "").trim();
		const end = String((_row$timeEnd = row.timeEnd) !== null && _row$timeEnd !== void 0 ? _row$timeEnd : "").trim();
		const currentTimeFallback = start && end ? `${start.replace(/ .*/, "")} - ${end.replace(/ .*/, "")}` : start || "";
		currentTime = currentTimeFromPrimary || currentTimeFallback;
		if (!isAvailable && primary) statusPack = applyStatusFromPrimaryBooking(primary, nowMs);
		currentBookingDisplay = isAvailable ? "Available to Book" : formatResourceWallContactLine(row);
		nextList = void 0;
	}
	if (!currentTime && bookings.length === 0) {
		var _row$time2, _row$timeEnd2;
		const fbStart = String((_row$time2 = row.time) !== null && _row$time2 !== void 0 ? _row$time2 : "").trim();
		const fbEnd = String((_row$timeEnd2 = row.timeEnd) !== null && _row$timeEnd2 !== void 0 ? _row$timeEnd2 : "").trim();
		currentTime = fbStart && fbEnd ? `${fbStart.replace(/ .*/, "")} - ${fbEnd.replace(/ .*/, "")}` : fbStart || "";
	}
	return require_objectSpread2._objectSpread2({
		resourceId: String(row.id),
		resource: row.code || row.main_field || String(row.id),
		area: row.area,
		status: statusPack.status,
		currentTime,
		currentBooking: currentBookingDisplay,
		remainingMin: statusPack.remainingMin,
		startsInMin: statusPack.startsInMin,
		lateMin: statusPack.lateMin,
		sessionStartMs: statusPack.sessionStartMs,
		sessionEndMs: statusPack.sessionEndMs,
		nextList
	}, wallUseNextLabelHideNextRow ? { wallUseNextLabelHideNextRow: true } : {});
}
//#endregion
exports.mapReservationRowsToVenueWallCards = mapReservationRowsToVenueWallCards;
