const require_runtime = require("../../_virtual/_rolldown/runtime.js");
const require_useEngineContext = require("../../hooks/useEngineContext.js");
const require_index = require("../../pro/Selector/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);
let _ant_design_icons = require("@ant-design/icons");
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";
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 defaultGetCardMeta(record) {
	var _record$id, _record$id2, _record$capacityLabel;
	const title = typeof record.title === "string" && record.title ? record.title : typeof record.name === "string" && record.name ? record.name : String((_record$id = record.id) !== null && _record$id !== void 0 ? _record$id : "");
	const subtitles = [];
	const idStr = String((_record$id2 = record.id) !== null && _record$id2 !== void 0 ? _record$id2 : "").trim();
	if (idStr && idStr !== title) subtitles.push(`#${idStr}`);
	const capRaw = (_record$capacityLabel = record.capacityLabel) !== null && _record$capacityLabel !== void 0 ? _record$capacityLabel : record.capacity;
	return {
		title,
		subtitles,
		capacity: capRaw != null ? String(capRaw) : void 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 _ref, _engine$props;
	const { open, onClose, onConfirm, records, mode = "multiple", value, title, disabledIds, categoryConfig, getSearchText, getCardMeta, renderCard, zIndex = 1100, width = 880, className } = props;
	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 prevOpenRef = (0, react.useRef)(false);
	const { engine } = require_useEngineContext.default();
	const engineLocale = (_ref = engine === null || engine === void 0 || (_engine$props = engine.props) === null || _engine$props === void 0 ? void 0 : _engine$props.locale) !== null && _ref !== void 0 ? _ref : "zh-CN";
	(0, react.useEffect)(() => {
		if (open) (0, _pisell_materials.initFloorMapLayoutLocales)(engineLocale);
	}, [open, engineLocale]);
	(0, react.useEffect)(() => {
		if (!open) {
			setKeyword("");
			setTabbarValue(["0"]);
			prevOpenRef.current = false;
			return;
		}
		if (!prevOpenRef.current) {
			setDraftSelected(normalizeIds(value));
			prevOpenRef.current = true;
		}
	}, [open, value]);
	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]);
	/**
	* 无类别数据时不渲染 Tabbar，改用简易搜索框（Tabbar 的 onSearch 入口随之消失）。
	*/
	const showTabbar = tabbarDataSource.length > 0;
	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$id3;
			const id = String((_record$id3 = record.id) !== null && _record$id3 !== void 0 ? _record$id3 : "").trim();
			const meta = resolveCardMeta(record);
			return {
				id,
				title: meta.title,
				label: meta.title,
				value: id,
				disabled: disabledSet.has(id),
				__record: record,
				__meta: meta
			};
		});
	}, [
		filteredRecords,
		disabledSet,
		resolveCardMeta
	]);
	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 allFilteredSelected = selectableFilteredIds.length > 0 && selectableFilteredIds.every((id) => draftSelected.includes(id));
	const someFilteredSelected = (0, react.useMemo)(() => draftSelected.some((id) => selectableFilteredIds.includes(id)), [draftSelected, selectableFilteredIds]);
	const handleSelectAllFiltered = (0, react.useCallback)(() => {
		setDraftSelected((prev) => {
			const set = new Set(prev);
			for (const id of selectableFilteredIds) set.add(id);
			return [...set];
		});
	}, [selectableFilteredIds]);
	const handleDeselectAllFiltered = (0, react.useCallback)(() => {
		if (mode === "single") {
			setDraftSelected([]);
			return;
		}
		setDraftSelected((prev) => prev.filter((id) => !selectableFilteredIds.includes(id)));
	}, [mode, selectableFilteredIds]);
	const handleSelectorChange = (0, react.useCallback)((next) => {
		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])];
		});
	}, [mode, selectableFilteredIds]);
	const selectorValue = (0, react.useMemo)(() => {
		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));
	}, [
		mode,
		draftSelected,
		selectableFilteredIds
	]);
	const handleConfirm = (0, react.useCallback)(() => {
		onConfirm(draftSelected.filter(Boolean));
		onClose();
	}, [
		draftSelected,
		onConfirm,
		onClose
	]);
	const renderSelectorItem = (0, react.useCallback)((renderProps) => {
		var _option$id, _meta$title, _meta$subtitles;
		const { dataSource, indicator, 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 = 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 });
		};
		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
			})
		}, /* @__PURE__ */ react.default.createElement("span", {
			className: `${PREFIX}-card-indicator`,
			onClick: (e) => e.stopPropagation()
		}, indicator), /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-card-body` }, customCard ? customCard : /* @__PURE__ */ react.default.createElement(react.default.Fragment, null, /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-card-title` }, (_meta$title = meta === null || meta === void 0 ? void 0 : meta.title) !== null && _meta$title !== void 0 ? _meta$title : 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.capacity) ? /* @__PURE__ */ react.default.createElement("span", { className: `${PREFIX}-card-cap` }, /* @__PURE__ */ react.default.createElement(_ant_design_icons.TeamOutlined, {
			className: `${PREFIX}-card-cap-icon`,
			"aria-hidden": true
		}), meta.capacity) : null)));
	}, [
		draftSelected,
		disabledSet,
		renderCard
	]);
	const confirmLabel = (0, react.useMemo)(() => {
		const base = _pisell_utils.locales.getText(`${I18N_RP}.confirm`);
		return draftSelected.length > 0 ? `${base} (${draftSelected.length})` : base;
	}, [draftSelected.length]);
	return /* @__PURE__ */ react.default.createElement(antd.Modal, {
		open,
		title,
		onCancel: onClose,
		destroyOnClose: true,
		width,
		zIndex,
		className: (0, classnames.default)(`${PREFIX}-modal`, className),
		styles: {
			content: { padding: 0 },
			header: {
				padding: 6,
				marginBottom: 0,
				background: "rgb(250, 250, 250)"
			},
			body: { padding: 0 },
			footer: {
				padding: 6,
				marginTop: 0
			}
		},
		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
		}, confirmLabel))
	}, /* @__PURE__ */ react.default.createElement("div", { className: PREFIX }, showTabbar ? /* @__PURE__ */ react.default.createElement(_pisell_materials.PisellTabbarTemplate1, {
		className: `${PREFIX}-tabbar`,
		style: {
			position: "sticky",
			top: 0,
			zIndex: 10,
			padding: 6,
			background: "rgb(250, 250, 250)"
		},
		dataSource: tabbarDataSource,
		value: tabbarValue,
		onChange: setTabbarValue,
		onSearch: setKeyword,
		maxLevel: 3
	}) : /* @__PURE__ */ react.default.createElement("div", { className: `${PREFIX}-search-fallback` }, /* @__PURE__ */ react.default.createElement(antd.Input.Search, {
		allowClear: true,
		placeholder: _pisell_utils.locales.getText(`${I18N_RP}.search-ph`),
		value: keyword,
		onChange: (e) => setKeyword(e.target.value)
	})), /* @__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: draftSelected.length === 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(draftSelected.length, 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: "primitive",
		variant: "card",
		itemLayout: "horizontal",
		showStepper: false,
		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;
