const require_runtime = require("../../_virtual/_rolldown/runtime.js");
const require_objectSpread2 = require("../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
const require_useEngineContext = require("../../hooks/useEngineContext.js");
const require_index = require("../../pro/Selector/index.js");
const require_index$1 = require("../../pro/compensatedPisellContainer/index.js");
const require_utils = require("./utils.js");
let react = require("react");
react = require_runtime.__toESM(react);
let antd = require("antd");
let _pisell_utils = require("@pisell/utils");
let _pisell_materials = require("@pisell/materials");
let classnames = require("classnames");
classnames = require_runtime.__toESM(classnames);
require("./PisellProResourcePickerModal.less");
//#region src/plus/pisellProResourcePickerModal/PisellProResourcePickerModal.tsx
/**
* Pro 版资源选择 Modal
* - 顶部：使用 `PisellTabbarTemplate1` 替换搜索 + 类别筛选
* - 列表：使用 `Selector` (`@pisell/private-materials/pro/Selector`) 替换 checkbox 列表
* - Props 与 `FloorMapResourcePickerSlotProps` 兼容，可作为 PisellFloorMapLayout
*   `renderResourcePickerModal` 槽位实现（通用基础 modal 已下线，统一由此组件承担）
*/
const PREFIX = "pisell-pro-resource-picker";
const I18N_RP = "pisell-floor-map-layout.resource-picker";
/**
* 通用默认卡片 meta：仅依赖 record.title/name + record.subtitle/desc 等常见字段，
* 不引入业务专属（如 floor map 的人数 badge）。业务场景请显式传 `getCardMeta`。
*/
function defaultGetCardMeta(record) {
	var _ref, _ref2, _ref3, _record$title, _ref4, _record$subtitle;
	const titleRaw = (_ref = (_ref2 = (_ref3 = (_record$title = record.title) !== null && _record$title !== void 0 ? _record$title : record.name) !== null && _ref3 !== void 0 ? _ref3 : record.label) !== null && _ref2 !== void 0 ? _ref2 : record.id) !== null && _ref !== void 0 ? _ref : "";
	const subtitleRaw = (_ref4 = (_record$subtitle = record.subtitle) !== null && _record$subtitle !== void 0 ? _record$subtitle : record.desc) !== null && _ref4 !== void 0 ? _ref4 : record.description;
	const subtitle = subtitleRaw == null ? "" : String(subtitleRaw).trim();
	return {
		title: String(titleRaw).trim(),
		subtitles: subtitle ? [subtitle] : []
	};
}
function formatSelectedCount(count, total) {
	return _pisell_utils.locales.getText(`${I18N_RP}.selected-count`).replace("{count}", String(count)).replace("{total}", String(total));
}
/**
* `PisellTabbarTemplate1` 内部会注入以下非分类的特殊按钮：
* - `level1`: `search` (id=-1) + `all` (id='0')
* - `level2/3`: `expand` (id=-2) + `all` (id='0')
* 它们不是真实分类 key，落到 selection 时需还原为 null（不参与过滤），
* 等价于「显示全部」。
*/
const TABBAR_NON_CATEGORY_IDS = new Set([
	"-1",
	"-2",
	"0"
]);
function tabbarValueToSelection(value) {
	const out = [
		null,
		null,
		null
	];
	if (!value) return out;
	for (let i = 0; i < 3; i++) {
		const seg = value[i];
		if (seg == null || seg === "") continue;
		out[i] = String(seg);
	}
	return out;
}
function normalizeIds(value) {
	if (!value) return [];
	return value.map((v) => String(v !== null && v !== void 0 ? v : "").trim()).filter(Boolean);
}
function PisellProResourcePickerModal(props) {
	var _ref5, _engine$props;
	const { open, onClose, onConfirm, records, mode = "multiple", value, title, disabledIds, categoryConfig, getSearchText, getCardMeta, renderCard, renderFilterBar, selectorValueType = "primitive", selectorShowStepper = "auto", getOptionRuleConfig, zIndex = 1100, width = 880, className, platform = "pc" } = props;
	const isObjectMode = selectorValueType === "object";
	const resolveCardMeta = getCardMeta !== null && getCardMeta !== void 0 ? getCardMeta : defaultGetCardMeta;
	const resolveSearchText = getSearchText !== null && getSearchText !== void 0 ? getSearchText : require_utils.defaultGetSearchText;
	const disabledSet = (0, react.useMemo)(() => new Set((disabledIds !== null && disabledIds !== void 0 ? disabledIds : []).map((id) => String(id))), [disabledIds]);
	const [keyword, setKeyword] = (0, react.useState)("");
	/**
	* Tabbar 受控值；默认选中 `PisellTabbarTemplate1` 注入的 `all` 按钮（id='0'），
	* 视觉上有「全部」高亮反馈。`TABBAR_NON_CATEGORY_IDS` 会把 `0/-1/-2`
	* 还原为 null，等价于「不过滤」。切到真实分类后按分类 key 过滤。
	*/
	const [tabbarValue, setTabbarValue] = (0, react.useState)(["0"]);
	const [draftSelected, setDraftSelected] = (0, react.useState)([]);
	const [draftObjectValues, setDraftObjectValues] = (0, react.useState)([]);
	const prevOpenRef = (0, react.useRef)(false);
	const { engine } = require_useEngineContext.default();
	const engineLocale = (_ref5 = engine === null || engine === void 0 || (_engine$props = engine.props) === null || _engine$props === void 0 ? void 0 : _engine$props.locale) !== null && _ref5 !== void 0 ? _ref5 : "zh-CN";
	/**
	* 生产低码产物中 `@pisell/utils` 在 BaseMaterials / PrivateMaterials 各有一份，
	* 须在本包 locales 单例上 init 文案表，不可调用 materials 内的 initFloorMapLayoutLocales。
	*/
	(0, react.useEffect)(() => {
		if (open) _pisell_utils.locales.init(_pisell_materials.floorMapLayoutLocales, engineLocale);
	}, [open, engineLocale]);
	(0, react.useEffect)(() => {
		if (!open) {
			setKeyword("");
			setTabbarValue(["0"]);
			prevOpenRef.current = false;
			return;
		}
		if (!prevOpenRef.current) {
			if (isObjectMode) setDraftObjectValues([]);
			else setDraftSelected(normalizeIds(value));
			prevOpenRef.current = true;
		}
	}, [
		open,
		value,
		isObjectMode
	]);
	const tabbarDataSource = (0, react.useMemo)(() => require_utils.buildTabbarDataSourceFromRecords(records, categoryConfig), [records, categoryConfig]);
	const selection = (0, react.useMemo)(() => {
		return tabbarValueToSelection(tabbarValue).map((s) => s != null && TABBAR_NON_CATEGORY_IDS.has(s) ? null : s);
	}, [tabbarValue]);
	const filterBarCtx = (0, react.useMemo)(() => ({
		keyword,
		onKeywordChange: setKeyword,
		tabbarDataSource,
		tabbarValue,
		onTabbarValueChange: setTabbarValue
	}), [
		keyword,
		tabbarDataSource,
		tabbarValue
	]);
	const filteredRecords = (0, react.useMemo)(() => {
		const q = keyword.trim().toLowerCase();
		return records.filter((record) => {
			if (!require_utils.matchesSelection(record, selection, categoryConfig)) return false;
			if (!q) return true;
			return resolveSearchText(record).includes(q);
		});
	}, [
		records,
		selection,
		categoryConfig,
		keyword,
		resolveSearchText
	]);
	const selectorOptions = (0, react.useMemo)(() => {
		return filteredRecords.map((record) => {
			var _record$id;
			const id = String((_record$id = record.id) !== null && _record$id !== void 0 ? _record$id : "").trim();
			const meta = resolveCardMeta(record);
			return require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({
				id,
				title: meta.title,
				label: meta.title,
				value: id,
				disabled: disabledSet.has(id)
			}, getOptionRuleConfig ? { ruleConfig: getOptionRuleConfig(record) } : {}), {}, {
				__record: record,
				__meta: meta
			});
		});
	}, [
		filteredRecords,
		disabledSet,
		resolveCardMeta,
		getOptionRuleConfig
	]);
	const selectableFilteredIds = (0, react.useMemo)(() => selectorOptions.map((o) => {
		var _o$id;
		return String((_o$id = o.id) !== null && _o$id !== void 0 ? _o$id : "");
	}).filter((id) => id && !disabledSet.has(id)), [selectorOptions, disabledSet]);
	/** 已选「种数」（有数量的条目数），非数量步进器之和 */
	const selectedKindCount = (0, react.useMemo)(() => {
		if (isObjectMode) return draftObjectValues.filter((item) => item.quantity > 0).length;
		return draftSelected.length;
	}, [
		isObjectMode,
		draftObjectValues,
		draftSelected
	]);
	const allFilteredSelected = (0, react.useMemo)(() => {
		if (selectableFilteredIds.length === 0) return false;
		if (isObjectMode) return selectableFilteredIds.every((id) => draftObjectValues.some((x) => x.value === id && x.quantity > 0));
		return selectableFilteredIds.every((id) => draftSelected.includes(id));
	}, [
		isObjectMode,
		selectableFilteredIds,
		draftObjectValues,
		draftSelected
	]);
	const someFilteredSelected = (0, react.useMemo)(() => {
		if (isObjectMode) return draftObjectValues.some((x) => selectableFilteredIds.includes(x.value) && x.quantity > 0);
		return draftSelected.some((id) => selectableFilteredIds.includes(id));
	}, [
		isObjectMode,
		draftObjectValues,
		draftSelected,
		selectableFilteredIds
	]);
	const handleSelectAllFiltered = (0, react.useCallback)(() => {
		if (isObjectMode) {
			setDraftObjectValues((prev) => {
				const map = new Map(prev.map((x) => [x.value, x]));
				for (const id of selectableFilteredIds) {
					const existing = map.get(id);
					map.set(id, {
						value: id,
						quantity: (existing === null || existing === void 0 ? void 0 : existing.quantity) && existing.quantity > 0 ? existing.quantity : 1
					});
				}
				return [...map.values()].filter((x) => x.quantity > 0);
			});
			return;
		}
		setDraftSelected((prev) => {
			const set = new Set(prev);
			for (const id of selectableFilteredIds) set.add(id);
			return [...set];
		});
	}, [isObjectMode, selectableFilteredIds]);
	const handleDeselectAllFiltered = (0, react.useCallback)(() => {
		if (mode === "single") {
			if (isObjectMode) setDraftObjectValues([]);
			else setDraftSelected([]);
			return;
		}
		if (isObjectMode) {
			setDraftObjectValues((prev) => prev.filter((x) => !selectableFilteredIds.includes(x.value)));
			return;
		}
		setDraftSelected((prev) => prev.filter((id) => !selectableFilteredIds.includes(id)));
	}, [
		mode,
		isObjectMode,
		selectableFilteredIds
	]);
	const parseObjectSelection = (0, react.useCallback)((next) => {
		if (next == null || next === "") return [];
		if (!Array.isArray(next)) {
			if (typeof next === "object" && next !== null && "value" in next) {
				var _next$value, _next$quantity;
				const valueKey = String((_next$value = next.value) !== null && _next$value !== void 0 ? _next$value : "").trim();
				if (!valueKey) return [];
				return [{
					value: valueKey,
					quantity: Math.max(0, Math.floor(Number((_next$quantity = next.quantity) !== null && _next$quantity !== void 0 ? _next$quantity : 0)))
				}];
			}
			const primitive = String(next).trim();
			return primitive ? [{
				value: primitive,
				quantity: 1
			}] : [];
		}
		return next.map((v) => {
			if (typeof v === "object" && v !== null && "value" in v) {
				var _v$value, _v$quantity;
				return {
					value: String((_v$value = v.value) !== null && _v$value !== void 0 ? _v$value : "").trim(),
					quantity: Math.max(0, Math.floor(Number((_v$quantity = v.quantity) !== null && _v$quantity !== void 0 ? _v$quantity : 0)))
				};
			}
			const valueKey = String(v !== null && v !== void 0 ? v : "").trim();
			return valueKey ? {
				value: valueKey,
				quantity: 1
			} : null;
		}).filter((x) => Boolean(x === null || x === void 0 ? void 0 : x.value));
	}, []);
	const handleSelectorChange = (0, react.useCallback)((next) => {
		if (isObjectMode) {
			setDraftObjectValues(parseObjectSelection(next).filter((x) => x.quantity > 0));
			return;
		}
		if (mode === "single") {
			if (next == null || next === "") setDraftSelected([]);
			else if (typeof next === "object" && next !== null && "value" in next) setDraftSelected([String(next.value)]);
			else setDraftSelected([String(next)]);
			return;
		}
		if (!Array.isArray(next)) return;
		const visible = new Set(selectableFilteredIds);
		const newVisibleSelection = next.map((v) => typeof v === "object" && v !== null && "value" in v ? String(v.value) : String(v)).filter((id) => visible.has(id));
		setDraftSelected((prev) => {
			const keptOutsideView = prev.filter((id) => !visible.has(id));
			return [...new Set([...keptOutsideView, ...newVisibleSelection])];
		});
	}, [
		isObjectMode,
		mode,
		selectableFilteredIds,
		parseObjectSelection
	]);
	const selectorValue = (0, react.useMemo)(() => {
		if (isObjectMode) return draftObjectValues;
		if (mode === "single") {
			var _draftSelected$;
			return (_draftSelected$ = draftSelected[0]) !== null && _draftSelected$ !== void 0 ? _draftSelected$ : "";
		}
		const visible = new Set(selectableFilteredIds);
		return draftSelected.filter((id) => visible.has(id));
	}, [
		isObjectMode,
		mode,
		draftObjectValues,
		draftSelected,
		selectableFilteredIds
	]);
	const handleConfirm = (0, react.useCallback)(() => {
		/**
		* TS 在 union of function 上有 contravariance 限制，需要在窄化分支内
		* 把 onConfirm 收敛成具体签名再调用，而不是直接对实参做强转。
		*/
		if (isObjectMode) onConfirm(draftObjectValues.filter((x) => x.quantity > 0));
		else onConfirm(draftSelected.filter(Boolean));
		onClose();
	}, [
		isObjectMode,
		draftObjectValues,
		draftSelected,
		onConfirm,
		onClose
	]);
	const renderSelectorItem = (0, react.useCallback)((renderProps) => {
		var _option$id, _meta$title, _meta$title2, _meta$subtitles;
		const { dataSource, indicator, numberSelector, actions } = renderProps;
		const option = dataSource;
		const record = option.__record;
		const meta = option.__meta;
		const id = String((_option$id = option.id) !== null && _option$id !== void 0 ? _option$id : "");
		const selected = isObjectMode ? Boolean(option.selected) : draftSelected.includes(id);
		const disabled = disabledSet.has(id);
		const customCard = record && renderCard ? renderCard(record, {
			selected,
			disabled
		}) : null;
		const onCardClick = () => {
			var _key;
			if (disabled) return;
			const key = (_key = option._key) !== null && _key !== void 0 ? _key : id;
			actions.update(key, { quantity: selected ? 0 : 1 });
		};
		/**
		* 卡片整体竖向排列且水平居中：body（image / title / subtitles / badges）+ 底部 actions。
		* - body：传 renderCard 时完全交给业务；否则按 image / title / subtitles / badges 顺序竖排居中
		* - actions：勾选 indicator 或数量步进器，统一放在卡片底部居中
		*/
		const image = meta === null || meta === void 0 ? void 0 : meta.image;
		const imageNode = image == null ? null : typeof image === "string" ? /* @__PURE__ */ react.default.createElement("img", {
			className: `${PREFIX}-card-image-img`,
			src: image,
			alt: (_meta$title = meta === null || meta === void 0 ? void 0 : meta.title) !== null && _meta$title !== void 0 ? _meta$title : "",
			draggable: false
		}) : image;
		return /* @__PURE__ */ react.default.createElement("button", {
			type: "button",
			disabled,
			onClick: onCardClick,
			className: (0, classnames.default)(`${PREFIX}-card`, {
				[`${PREFIX}-card--selected`]: selected,
				[`${PREFIX}-card--disabled`]: disabled,
				[`${PREFIX}-card--with-stepper`]: Boolean(numberSelector)
			})
		}, /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-card-body` }, customCard ? customCard : /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, imageNode ? /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-card-image` }, imageNode) : null, /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-card-text` }, /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-card-title` }, (_meta$title2 = meta === null || meta === void 0 ? void 0 : meta.title) !== null && _meta$title2 !== void 0 ? _meta$title2 : option.title), meta === null || meta === void 0 || (_meta$subtitles = meta.subtitles) === null || _meta$subtitles === void 0 ? void 0 : _meta$subtitles.map((sub, index) => /* @__PURE__ */ react.default.createElement("span", {
			key: `${id}-sub-${index}`,
			className: `${PREFIX}-card-sub`
		}, sub)), (meta === null || meta === void 0 ? void 0 : meta.badges) && meta.badges.length > 0 ? /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-card-badges` }, meta.badges.map((badge, index) => /* @__PURE__ */ react.default.createElement("span", {
			key: `${id}-badge-${index}`,
			className: `${PREFIX}-card-badge`
		}, badge.icon ? /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-card-badge-icon` }, badge.icon) : null, badge.text))) : null))), /* @__PURE__ */ react.default.createElement("span", {
			className: `${PREFIX}-card-actions`,
			onClick: (e) => e.stopPropagation()
		}, numberSelector !== null && numberSelector !== void 0 ? numberSelector : indicator));
	}, [
		isObjectMode,
		draftSelected,
		disabledSet,
		renderCard
	]);
	const confirmLabel = (0, react.useMemo)(() => {
		const base = _pisell_utils.locales.getText(`${I18N_RP}.confirm`);
		return selectedKindCount > 0 ? `${base} (${selectedKindCount})` : base;
	}, [selectedKindCount]);
	return /* @__PURE__ */ react.default.createElement(require_index$1.default, {
		renderType: "modal",
		props: {
			platform,
			open,
			title,
			onCancel: onClose,
			destroyOnClose: true,
			width,
			zIndex,
			wrapClassName: (0, classnames.default)(`${PREFIX}-modal`, className),
			headerDivider: false,
			footerDivider: false,
			footer: /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-footer` }, /* @__PURE__ */ react.default.createElement(antd.Button, { onClick: onClose }, _pisell_utils.locales.getText(`${I18N_RP}.cancel`)), /* @__PURE__ */ react.default.createElement(antd.Button, {
				type: "primary",
				onClick: handleConfirm,
				disabled: selectedKindCount === 0
			}, confirmLabel))
		}
	}, /* @__PURE__ */ react.default.createElement("div", { className: PREFIX }, /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-filter-bar` }, renderFilterBar ? renderFilterBar(filterBarCtx) : /* @__PURE__ */ react.default.createElement(_pisell_materials.PisellFind, {
		triggerType: "input",
		value: keyword,
		onChange: setKeyword,
		onSearch: setKeyword,
		placeholder: _pisell_utils.locales.getText(`${I18N_RP}.search-ph`),
		showHistory: false,
		showConfirmButton: false
	})), /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-toolbar` }, mode === "multiple" ? /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-toolbar-left` }, /* @__PURE__ */ react.default.createElement(antd.Checkbox, {
		indeterminate: someFilteredSelected && !allFilteredSelected,
		checked: allFilteredSelected,
		disabled: selectableFilteredIds.length === 0,
		onChange: (e) => {
			if (e.target.checked) handleSelectAllFiltered();
			else handleDeselectAllFiltered();
		}
	}, _pisell_utils.locales.getText(`${I18N_RP}.select-all`)), /* @__PURE__ */ react.default.createElement("button", {
		type: "button",
		className: `${PREFIX}-link`,
		onClick: handleDeselectAllFiltered,
		disabled: selectedKindCount === 0
	}, _pisell_utils.locales.getText(`${I18N_RP}.deselect-all`))) : /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-hint` }, _pisell_utils.locales.getText(`${I18N_RP}.single-hint`)), /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-count` }, formatSelectedCount(selectedKindCount, records.length))), /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-list` }, selectorOptions.length === 0 ? /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-empty` }, _pisell_utils.locales.getText(`${I18N_RP}.empty`)) : /* @__PURE__ */ react.default.createElement(require_index.default, {
		dataSource: selectorOptions,
		mode,
		valueType: selectorValueType,
		variant: "card",
		itemLayout: "horizontal",
		showStepper: selectorShowStepper,
		value: selectorValue,
		onChange: handleSelectorChange,
		renderItem: renderSelectorItem,
		layout: {
			type: "antdGrid",
			responsive: {
				minWidth: 160,
				maxColumns: 4,
				gap: 4,
				defaultColumns: 2
			}
		},
		headerProps: { visible: false }
	}))));
}
//#endregion
exports.default = PisellProResourcePickerModal;
