import { _objectSpread2 } from "../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
import { tCal } from "./calendarI18n.js";
import { formatDateLoose, formatHourLabel, getDisplayStatusTag, getLateMinutes, statusTagMetaParts } from "./utils/bookingCalendarDateUtils.js";
import { getBookingStateClasses } from "./utils/BookingCalendarStyle.js";
import React, { useEffect, useRef } from "react";
import { Tooltip } from "antd";
//#region src/components/pisellRecordBoard/shellFrame/Calendar/bookingCalendarViewShared.tsx
/** UI 层：状态徽标文案走 i18n（utils 侧为 {@link statusTagMetaParts}） */
function statusTagMeta(tag) {
	const p = statusTagMetaParts(tag);
	return p ? {
		label: tCal(p.labelI18nKey),
		className: p.className
	} : null;
}
/** 锁台卡片副标题：操作人、锁台时间等拼接一行 */
function getBlockMetaLine(item) {
	if (item.kind !== "block") return "";
	const bits = [];
	if (item.blockBy) bits.push(tCal("pisell2.recordBoard.calendar.card.blockBy", { name: item.blockBy }));
	if (item.blockedAt) bits.push(formatDateLoose(item.blockedAt));
	return bits.join(" · ");
}
function getRemainingToneClass(ratio, isLight = false) {
	if (ratio <= .2) return isLight ? "text-red-600" : "text-red-300";
	if (ratio <= .4) return isLight ? "text-amber-600" : "text-amber-300";
	return isLight ? "theme-text-muted" : "text-zinc-400";
}
/**
* @param options.flattenWhenAllGroupsCollapsed
*   若为 `true`：全部分组折叠时仅有 group 头、无 court 行，会退化为平铺 court（易与「全部展开」混淆）。
*   日/周/月日历统一为默认 `false`，保留分组头行与折叠态（与底部「全部关闭」预期一致）。
*
* 若全部资源只属于**一个**分组（含仅 VIP、仅 Standard、或仅一种自定义 type），日/周视图不展示分组头行，
* 直接平铺资源行（单组折叠时也同样平铺资源，避免只剩一条分组栏）。
*/
function buildGroupedCourtRows(courts, collapsedGroups = {}, options = {}) {
	const { flattenWhenAllGroupsCollapsed = false } = options;
	const predefined = ["VIP", "Standard"];
	const rows = [];
	const consumedIds = /* @__PURE__ */ new Set();
	predefined.forEach((group) => {
		const items = courts.filter((court) => court.type === group);
		if (items.length === 0) return;
		items.forEach((c) => consumedIds.add(c.id));
		rows.push({
			kind: "group",
			id: `group-${group}`,
			label: group,
			count: items.length,
			collapsed: !!collapsedGroups[group]
		});
		if (!collapsedGroups[group]) items.forEach((court) => rows.push(_objectSpread2(_objectSpread2({ kind: "court" }, court), {}, { group })));
	});
	/** 低代码接入：桌位 type 多为 Resource / 自定义 groupType，不能只剩 VIP/Standard 两行否则日周视图为空 */
	const remainder = courts.filter((c) => !consumedIds.has(c.id));
	const byType = {};
	remainder.forEach((court) => {
		const label = court.type && String(court.type).trim() !== "" ? String(court.type) : tCal("pisell2.recordBoard.calendar.common.resourceFallback");
		if (!byType[label]) byType[label] = [];
		byType[label].push(court);
	});
	Object.keys(byType).forEach((label) => {
		const items = byType[label];
		if (!items.length) return;
		const idSafe = String(label).replace(/\s+/g, "-");
		rows.push({
			kind: "group",
			id: `group-${idSafe}`,
			label,
			count: items.length,
			collapsed: !!collapsedGroups[label]
		});
		if (!collapsedGroups[label]) items.forEach((court) => rows.push(_objectSpread2(_objectSpread2({ kind: "court" }, court), {}, { group: label })));
	});
	/** 仅存在一个资源分组：日/周不展示分组头，直接平铺 court（与同组折叠态无关，避免只显示一行分组栏） */
	if (rows.filter((r) => r.kind === "group").length === 1 && courts.length > 0) {
		const fallbackLabel = tCal("pisell2.recordBoard.calendar.common.resourceFallback");
		return courts.map((c) => _objectSpread2(_objectSpread2({ kind: "court" }, c), {}, { group: c.type && String(c.type).trim() !== "" ? String(c.type) : fallbackLabel }));
	}
	const courtRowsOnly = rows.filter((r) => r.kind === "court");
	/** 可选：全部分组折叠且仍须展示 court 行时再平铺（日历默认不走此分支） */
	if (flattenWhenAllGroupsCollapsed && courtRowsOnly.length === 0 && courts.length > 0) return courts.map((c) => ({
		kind: "court",
		id: c.id,
		name: c.name,
		type: c.type,
		group: c.type
	}));
	return rows;
}
/** 日视图 overlay 内单条预约/锁台：窄宽自适应与 Tooltip */
function BookingCard({ booking, dayKey, onOpenDetail, onDragStart, onJumpNext, overlayWidthPx }) {
	var _item$name;
	/** HTML5 拖拽结束后浏览器常对源元素追加一次 click，避免误开详情 */
	const suppressDetailClickAfterDragRef = useRef(false);
	const suppressDetailClickTimerRef = useRef(null);
	useEffect(() => {
		return () => {
			if (suppressDetailClickTimerRef.current != null) window.clearTimeout(suppressDetailClickTimerRef.current);
		};
	}, []);
	const armSuppressDetailClickAfterDrag = () => {
		suppressDetailClickAfterDragRef.current = true;
		if (suppressDetailClickTimerRef.current != null) window.clearTimeout(suppressDetailClickTimerRef.current);
		suppressDetailClickTimerRef.current = window.setTimeout(() => {
			suppressDetailClickAfterDragRef.current = false;
			suppressDetailClickTimerRef.current = null;
		}, 500);
	};
	const { item, span, start, continuesNext } = booking;
	const displayTag = getDisplayStatusTag(item, dayKey);
	const lateMinutes = getLateMinutes(item, dayKey);
	const stateClass = getBookingStateClasses(item, dayKey);
	const w = overlayWidthPx != null && Number.isFinite(overlayWidthPx) ? overlayWidthPx : Number.POSITIVE_INFINITY;
	const narrow = w < 88;
	const micro = w < 32;
	const microMark = Array.from(String((_item$name = item.name) !== null && _item$name !== void 0 ? _item$name : "").trim())[0] || "·";
	const tooltipTitle = /* @__PURE__ */ React.createElement("div", { className: "max-w-[260px] space-y-1 text-left" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold" }, item.name), item.kind === "block" && item.note && /* @__PURE__ */ React.createElement("div", { className: "text-xs opacity-90" }, item.note), /* @__PURE__ */ React.createElement("div", { className: "text-xs tabular-nums opacity-90" }, formatHourLabel(start), " - ", formatHourLabel(start + span)), item.kind === "block" && getBlockMetaLine(item) && /* @__PURE__ */ React.createElement("div", { className: "text-[11px] opacity-80" }, getBlockMetaLine(item)), continuesNext && /* @__PURE__ */ React.createElement("div", { className: "text-[11px] text-violet-200" }, tCal("pisell2.recordBoard.calendar.card.continuesNext")), item.kind !== "block" && displayTag && statusTagMeta(displayTag) && /* @__PURE__ */ React.createElement("div", { className: "text-[11px] opacity-90" }, statusTagMeta(displayTag).label, lateMinutes && displayTag === "late" ? ` · ${tCal("pisell2.recordBoard.calendar.card.lateMinutesDetail", { n: lateMinutes })}` : ""));
	const wrapNarrow = (node) => narrow ? /* @__PURE__ */ React.createElement(Tooltip, {
		title: tooltipTitle,
		placement: "top",
		mouseEnterDelay: .12,
		destroyTooltipOnHide: true
	}, node) : node;
	if (item.kind === "block") {
		const blockWide = /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "truncate text-sm font-medium" }, item.name), item.note && /* @__PURE__ */ React.createElement("div", { className: "mt-1 truncate text-xs text-zinc-200/90" }, item.note), getBlockMetaLine(item) && /* @__PURE__ */ React.createElement("div", { className: "mt-1 truncate text-[10px] text-zinc-300/80" }, getBlockMetaLine(item)));
		const blockCompact = micro ? /* @__PURE__ */ React.createElement("span", { className: "flex h-full w-full items-center justify-center text-[11px] font-semibold leading-none" }, microMark) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "truncate text-[11px] font-medium leading-tight" }, item.name), getBlockMetaLine(item) && /* @__PURE__ */ React.createElement("div", { className: "mt-0.5 truncate text-[10px] opacity-80" }, getBlockMetaLine(item)));
		const blockPad = micro ? "px-0.5 py-0.5 flex items-center justify-center" : narrow ? "px-2 py-2" : "px-3 py-3 text-left";
		return wrapNarrow(/* @__PURE__ */ React.createElement("button", {
			type: "button",
			"aria-label": narrow ? `${item.name}, ${formatHourLabel(start)} - ${formatHourLabel(start + span)}` : void 0,
			onClick: (e) => {
				e.stopPropagation();
				onOpenDetail(item);
			},
			className: `absolute inset-x-0 inset-y-0 rounded-2xl overflow-hidden ${blockPad} ${narrow && !micro ? "text-left" : ""} ${stateClass}`
		}, narrow ? blockCompact : blockWide));
	}
	/** 宽卡片：纵向紧密排列，去掉 flex-1 + mt-auto，避免单 lane 时在标题与徽标之间留出「假第二行」空白 */
	const bookingWide = /* @__PURE__ */ React.createElement("div", { className: "flex min-h-0 min-w-0 w-full flex-col gap-1 overflow-hidden text-left" }, /* @__PURE__ */ React.createElement("div", { className: "truncate text-sm font-medium leading-tight" }, item.name), /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs opacity-90 tabular-nums" }, formatHourLabel(start), " - ", formatHourLabel(start + span)), continuesNext && /* @__PURE__ */ React.createElement("span", {
		role: "button",
		tabIndex: 0,
		onClick: (e) => {
			e.stopPropagation();
			onJumpNext();
		},
		onKeyDown: (e) => {
			if (e.key === "Enter" || e.key === " ") {
				e.preventDefault();
				e.stopPropagation();
				onJumpNext();
			}
		},
		className: "inline-flex max-w-full cursor-pointer truncate rounded-lg bg-white/10 px-2 py-1 text-left text-[10px] leading-tight text-violet-100 sm:text-[11px]"
	}, tCal("pisell2.recordBoard.calendar.card.continuesNext")), (displayTag || lateMinutes) && /* @__PURE__ */ React.createElement("div", { className: "flex shrink-0 flex-wrap items-center justify-end gap-1" }, lateMinutes && displayTag === "late" && /* @__PURE__ */ React.createElement("span", { className: "rounded-md bg-black/25 px-1.5 py-0.5 text-[10px] font-semibold text-white/90 backdrop-blur-[2px] opacity-80 sm:px-2" }, tCal("pisell2.recordBoard.calendar.card.lateMinutesBadge", { n: lateMinutes })), displayTag && statusTagMeta(displayTag) && /* @__PURE__ */ React.createElement("span", { className: `rounded-lg px-1.5 py-0.5 text-[10px] font-semibold backdrop-blur-[2px] sm:px-2 ${statusTagMeta(displayTag).className} ${lateMinutes ? "opacity-80" : ""}` }, statusTagMeta(displayTag).label)));
	const bookingCompact = micro ? /* @__PURE__ */ React.createElement("span", { className: "flex h-full w-full items-center justify-center text-[11px] font-semibold leading-none" }, microMark) : /* @__PURE__ */ React.createElement("div", { className: "flex min-h-0 min-w-0 flex-col justify-start overflow-hidden" }, /* @__PURE__ */ React.createElement("div", { className: "truncate text-[11px] font-medium leading-tight tabular-nums" }, item.name, " · ", formatHourLabel(start), "–", formatHourLabel(start + span)));
	const bookingPad = micro ? "px-0.5 py-0.5" : narrow ? "px-1.5 py-1.5" : "px-2 py-2 sm:px-4 sm:py-3";
	const bookingFlexMain = micro ? "flex items-center justify-center" : "flex min-h-0 flex-col justify-start";
	const bookingAlign = !narrow ? "text-left" : micro ? "" : "justify-start";
	return wrapNarrow(/* @__PURE__ */ React.createElement("button", {
		type: "button",
		draggable: true,
		"aria-label": narrow ? `${item.name}, ${formatHourLabel(start)} - ${formatHourLabel(start + span)}` : void 0,
		onDragStart: (e) => {
			e.stopPropagation();
			onDragStart(item);
		},
		onDragEnd: (e) => {
			e.stopPropagation();
			armSuppressDetailClickAfterDrag();
		},
		onClick: (e) => {
			if (suppressDetailClickAfterDragRef.current) {
				suppressDetailClickAfterDragRef.current = false;
				if (suppressDetailClickTimerRef.current != null) {
					window.clearTimeout(suppressDetailClickTimerRef.current);
					suppressDetailClickTimerRef.current = null;
				}
				e.preventDefault();
				e.stopPropagation();
				return;
			}
			e.stopPropagation();
			onOpenDetail(item);
		},
		className: `absolute inset-x-0 inset-y-0 rounded-2xl overflow-hidden ${bookingFlexMain} ${bookingAlign} ${bookingPad} ${stateClass}`
	}, narrow ? bookingCompact : bookingWide));
}
//#endregion
export { BookingCard, buildGroupedCourtRows, getBlockMetaLine, getRemainingToneClass, statusTagMeta };
