<template>
	<el-dialog v-model="visible" title="选择设备分类" width="800px" :close-on-click-modal="false" @close="onCancel">
		<div style="margin-bottom: 12px">
			<el-input v-model="search" placeholder="输入关键字搜索" style="width: 240px; margin-right: 8px" @keyup.enter="fetchData(true)" />
			<el-button type="primary" @click="fetchData(true)">搜索</el-button>
		</div>
		<el-table :data="tableData" border style="width: 100%" @selection-change="onSelectionChange" ref="tableRef" row-key="id">
			<el-table-column type="selection" width="50" :reserve-selection="true" :selectable="isRowSelectable" />
			<el-table-column type="index" label="序号" width="60" />
			<el-table-column prop="name" label="设备分类" />
			<el-table-column prop="description" label="描述" min-width="160" />
		</el-table>
		<el-pagination
			style="margin-top: 12px; text-align: right"
			:current-page="page"
			:page-size="pageSize"
			:total="total"
			@current-change="onPageChange"
		/>
		<template #footer>
			<el-button @click="onCancel">取消</el-button>
			<el-button type="primary" @click="onConfirm">确定</el-button>
		</template>
	</el-dialog>
</template>

<script setup lang="ts">
import { ref, watch, defineProps, defineEmits, nextTick } from 'vue';
import { ElMessage } from 'element-plus';
import * as deviceApi from '../../../deviceclass/api';
import * as storeapi from '../../../storelist/api';

const props = defineProps<{
	visible: boolean;
	/** 已在借用单中的分类 id，列表中不可再勾选（支持 number / string 混用） */
	disabledIds?: (number | string)[];
}>();
const emit = defineEmits(['update:visible', 'confirm']);

const visible = ref(props.visible);

const search = ref('');
const page = ref(1);
const pageSize = ref(10);
const total = ref(0);
const tableData = ref<any[]>([]);
const selectedRows = ref<any[]>([]);
const warehouseMap = ref<Record<number, string>>({});
const selectedMap = ref<Map<number | string, any>>(new Map());
const tableRef = ref();
const isRestoring = ref(false);

function isCategoryIdDisabled(rowId: any): boolean {
	const list = props.disabledIds;
	if (!list?.length) return false;
	return list.some((d) => d == rowId);
}

function fetchWarehouseMap() {
	storeapi.GetPermission().then((res: any) => {
		const map: Record<number, string> = {};
		res.data.forEach((item: any) => {
			map[item.id] = item.name;
		});
		warehouseMap.value = map;
	});
}

async function fetchData(resetPage = false) {
	if (resetPage) page.value = 1;
	await fetchWarehouseMap();
	deviceApi.GetList({ page: page.value, limit: pageSize.value, code: search.value, status: 1 }).then((res: any) => {
		const devices = Array.isArray(res.data) ? res.data : [];
		// 本页内将「已在借用单中的分类」排在前面，便于一眼看到
		tableData.value = [...devices].sort((a: any, b: any) => {
			const da = isCategoryIdDisabled(a.id) ? 0 : 1;
			const db = isCategoryIdDisabled(b.id) ? 0 : 1;
			return da - db;
		});
		total.value = res.total;
		nextTick(() => {
			restoreSelection();
		});
	});
}

function isRowSelectable(row: any) {
	return !isCategoryIdDisabled(row.id);
}

function restoreSelection() {
	if (!tableRef.value) return;
	isRestoring.value = true;

	tableData.value.forEach((row: any) => {
		tableRef.value.toggleRowSelection(row, false);
	});
	tableData.value.forEach((row: any) => {
		const inSession = selectedMap.value.has(row.id);
		const alreadyInForm = isCategoryIdDisabled(row.id);
		if (inSession || alreadyInForm) {
			tableRef.value.toggleRowSelection(row, true);
		}
	});

	isRestoring.value = false;
	updateSelectedRows();
}

function updateSelectedRows() {
	selectedRows.value = tableData.value.filter((row: any) => selectedMap.value.has(row.id));
}

function onSelectionChange(val: any[]) {
	if (isRestoring.value) {
		return;
	}

	const currentPageIds = new Set(tableData.value.map((row: any) => row.id));

	currentPageIds.forEach((id) => {
		if (isCategoryIdDisabled(id)) {
			return;
		}
		const isSelected = val.some((item: any) => item.id === id);
		if (!isSelected) {
			selectedMap.value.delete(id);
		}
	});

	val.forEach((item: any) => {
		if (isCategoryIdDisabled(item.id)) {
			return;
		}
		selectedMap.value.set(item.id, item);
	});

	updateSelectedRows();
}

function onPageChange(val: number) {
	page.value = val;
	fetchData();
}

function onConfirm() {
	const allSelected = Array.from(selectedMap.value.values()).filter((item: any) => !isCategoryIdDisabled(item.id));

	if (allSelected.length === 0) {
		ElMessage.warning('请选择设备分类（已在列表中的分类不可重复添加）');
		return;
	}

	emit('confirm', allSelected);
	emit('update:visible', false);
}

function onCancel() {
	selectedMap.value.clear();
	selectedRows.value = [];
	emit('update:visible', false);
}

watch(
	() => props.visible,
	(v) => {
		visible.value = v;
		if (v) {
			fetchData();
		}
	},
	{ immediate: true }
);

watch(
	() => props.disabledIds,
	() => {
		if (!visible.value) return;
		const toDel: (number | string)[] = [];
		selectedMap.value.forEach((_v, key) => {
			if (isCategoryIdDisabled(key)) {
				toDel.push(key);
			}
		});
		toDel.forEach((k) => selectedMap.value.delete(k));
		nextTick(() => {
			restoreSelection();
		});
	},
	{ deep: true }
);
</script>
