<template>
	<el-dialog v-model="visible" title="选择设备" width="800px" :close-on-click-modal="false" @close="onCancel">
		<div style="margin-bottom: 12px">
			<el-input ref="searchInput" 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="(row: any) => row.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="code" label="设备编号"/>
			<el-table-column prop="inventory.available_quantity" label="可用数量" />
			<el-table-column prop="category_name" label="设备分类" />
			<el-table-column prop="brand" label="品牌" />
			<el-table-column prop="specification" label="规格型号" />
			<el-table-column prop="warehouse" label="存放仓库" />
		</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 * as deviceApi from '../../../../device/api';
import * as storeapi from '../../../../storelist/api';
import type { ElTable } from 'element-plus';

interface Device {
	id: string | number;
	code: string;
	name?: string;
	category_name?: string;
	brand?: string;
	specification?: string;
	warehouse: number | string;
	available_quantity?: number;
	[key: string]: any;
}

const props = defineProps<{ 
    visible: boolean;
    deviceIds?: (string | number)[];
    returnMode?: boolean; // 归还模式：不再根据可用数量过滤
    selectedDeviceCodes?: any[];
    disabledDeviceIds?: (string | number)[]; // 已禁用的设备ID列表（不能取消选择）
}>();
const emit = defineEmits(['update:visible', 'confirm']);

const visible = ref(props.visible);
watch(
	() => props.visible,
	(v) => (visible.value = v)
);

const search = ref('');
const page = ref(1);
const pageSize = ref(20);
const total = ref(0);
const tableData = ref<Device[]>([]);
const selectedRows = ref<Device[]>([]);
const warehouseMap = ref<Record<number, string>>({});
const searchInput = ref<HTMLInputElement | null>(null);
const tableRef = ref<InstanceType<typeof ElTable>>();
// 用于存储所有已选中的项（跨页）- 用户主动选择的项
const selectedMap = ref<Map<number | string, Device>>(new Map());
// 用于存储初始化时自动选中的项（仅用于回显，不影响用户选择）
const initialSelectedMap = ref<Map<number | string, Device>>(new Map());
// 用于存储已禁用项的Map（这些项不能取消选择）
const disabledMap = ref<Map<number | string, Device>>(new Map());
// 标志位：是否正在恢复选中状态（避免触发 onSelectionChange 时误删数据）
const isRestoring = ref(false);

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 fetchDevicesByCodes(codes: any[]): Promise<Device[]> {
    if (!codes || codes.length === 0) return [];
    
    try {
        // 为每个 code 搜索设备
        const searchPromises = codes.map((code: any) => 
            deviceApi.GetList({ page: 1, limit: 100, code: code, status: 1 })
        );
        const results = await Promise.all(searchPromises);
        
        // 合并所有搜索结果
        const allDevices: Device[] = [];
        results.forEach((res: any) => {
            if (res.data && res.data.length > 0) {
                allDevices.push(...res.data);
            }
        });
        
        // 去重（根据设备ID）
        const uniqueDevices = Array.from(
            new Map(allDevices.map((device: Device) => [device.id, device])).values()
        );
        
        return uniqueDevices.map((device: Device) => ({
            ...device,
            warehouse: `${warehouseMap.value[device.warehouse as number] || `ID:${device.warehouse}`} (${device.available_quantity || 0})`
        }));
    } catch (error) {
        console.error('搜索设备失败:', error);
        return [];
    }
}

// 判断行是否可选择（禁用的行不能取消选择）
function isRowSelectable(row: Device) {
	// 如果该行在禁用列表中，则不可取消选择
	return !disabledMap.value.has(row.id);
}

// 从当前页数据中初始化禁用项
function initDisabledItemsFromCurrentPage() {
	if (!props.disabledDeviceIds || props.disabledDeviceIds.length === 0) {
		return;
	}
	
	// 将当前页中 disabledDeviceIds 的项添加到 disabledMap 和 selectedMap
	tableData.value.forEach((row: Device) => {
		if (props.disabledDeviceIds?.includes(row.id)) {
			disabledMap.value.set(row.id, row);
			selectedMap.value.set(row.id, row);
		}
	});
}

async function fetchData(resetPage = false) {
	if (resetPage) page.value = 1;
	await fetchWarehouseMap(); 
	
	// 只在归还模式下启用 selectedDeviceCodes 的回显功能，避免影响领取模式
	// 如果有 selectedDeviceCodes 且当前没有搜索条件，且是归还模式，则根据 codes 搜索
	if (props.returnMode && props.selectedDeviceCodes && props.selectedDeviceCodes.length > 0 && !search.value.trim()) {
		const devicesByCodes = await fetchDevicesByCodes(props.selectedDeviceCodes);
		
		// 应用过滤条件
		let devices = devicesByCodes;
		
		// 归还模式不做数量判断（已在 returnMode 判断中）
		
		// 如果有deviceIds，只显示指定的设备
		if (props.deviceIds && props.deviceIds.length > 0) {
			devices = devices.filter((device: Device) => props.deviceIds?.includes(device.id));
		}
		
		tableData.value = devices;
		total.value = devices.length;
		
		// 自动选中匹配的设备，但不添加到 selectedMap（仅用于回显）
		initialSelectedMap.value.clear();
		devices.forEach((device: Device) => {
			initialSelectedMap.value.set(device.id, device);
		});
		
		// 初始化禁用项并恢复选中状态
		nextTick(() => {
			initDisabledItemsFromCurrentPage();
			restoreSelection();
		});
		return;
	}
	
	// 原有搜索逻辑（领取模式和其他情况都走这里）
	deviceApi.GetList({ page: page.value, limit: pageSize.value, code: search.value,status:1 })
	.then((res: any) => {
		let devices: Device[] = res.data.map((device: Device) => ({
            ...device,
            warehouse: `${warehouseMap.value[device.warehouse as number] || `ID:${device.warehouse}`} (${device.available_quantity || 0})`
        }));
        
        // 借用模式下过滤掉可用数量为 0 的设备；归还模式不做数量判断
        if (!props.returnMode) {
            devices = devices.filter((device: Device) => (device.available_quantity || 0) > 0);
        }
        
        // 如果有deviceIds，只显示指定的设备
        if (props.deviceIds && props.deviceIds.length > 0) {
            devices = devices.filter((device: Device) => props.deviceIds?.includes(device.id));
        }
        
		tableData.value = devices;
		total.value = res.total;
		
		// 只在归还模式下自动选中匹配的设备，避免影响领取模式
		// 这些自动选中的项只用于回显，不记录到 selectedMap
		if (props.returnMode && props.selectedDeviceCodes && props.selectedDeviceCodes.length > 0) {
			initialSelectedMap.value.clear();
			devices.forEach((device: Device) => {
				// 检查设备的 code 是否在 selectedDeviceCodes 中
				if (props.selectedDeviceCodes?.includes(device.code)) {
					initialSelectedMap.value.set(device.id, device);
				}
			});
		} else {
			// 如果不是归还模式或没有 selectedDeviceCodes，清空初始选中
			initialSelectedMap.value.clear();
		}
		
		// 数据加载完成后，初始化禁用项并回显选中状态
		nextTick(() => {
			initDisabledItemsFromCurrentPage();
			restoreSelection();
		});
	});
}
// 恢复当前页的选中状态
function restoreSelection() {
	if (!tableRef.value) return;
	// 设置标志位，避免 onSelectionChange 误删数据
	isRestoring.value = true;
	
	// 先清空当前页的所有选中
	tableData.value.forEach((row: Device) => {
		tableRef.value?.toggleRowSelection(row, false);
	});
	// 根据 selectedMap、initialSelectedMap 和 disabledMap 设置当前页的选中状态
	// 优先显示用户主动选择的项，其次显示初始化时自动选中的项，最后显示禁用的项
	tableData.value.forEach((row: Device) => {
		if (selectedMap.value.has(row.id) || initialSelectedMap.value.has(row.id) || disabledMap.value.has(row.id)) {
			tableRef.value?.toggleRowSelection(row, true);
		}
	});
	
	// 恢复标志位
	isRestoring.value = false;
	// 更新当前页的选中数组
	updateSelectedRows();
}

// 更新当前页的选中数组（包括用户选择、初始化选中和禁用的项）
function updateSelectedRows() {
	selectedRows.value = tableData.value.filter((row: Device) => 
		selectedMap.value.has(row.id) || initialSelectedMap.value.has(row.id) || disabledMap.value.has(row.id)
	);
}

function onSelectionChange(val: Device[]) {
	// 如果正在恢复选中状态，不更新 selectedMap（避免误删数据）
	if (isRestoring.value) {
		return;
	}
	
	// 获取当前页所有行的 id
	const currentPageIds = new Set(tableData.value.map((row: Device) => row.id));
	
	// 处理当前页的选中状态变化
	currentPageIds.forEach((id) => {
		const isSelected = val.some((item: Device) => item.id === id);
		const wasInitialSelected = initialSelectedMap.value.has(id);
		const wasUserSelected = selectedMap.value.has(id);
		const isDisabled = disabledMap.value.has(id);
		
		if (isSelected) {
			// 如果当前选中
			if (wasInitialSelected && !wasUserSelected && !isDisabled) {
				// 如果只是初始化选中的，用户现在主动选中了，则从 initialSelectedMap 移除，添加到 selectedMap
				initialSelectedMap.value.delete(id);
				const device = tableData.value.find((row: Device) => row.id === id);
				if (device) {
					selectedMap.value.set(id, device);
				}
			} else if (!wasUserSelected && !isDisabled) {
				// 如果之前没有选中，现在选中了，添加到 selectedMap（但不禁用的项）
				const device = tableData.value.find((row: Device) => row.id === id);
				if (device) {
					selectedMap.value.set(id, device);
				}
			}
		} else {
			// 如果当前未选中
			if (isDisabled) {
				// 如果禁用的项被取消选择，强制重新选中
				nextTick(() => {
					const row = tableData.value.find((r: Device) => r.id === id);
					if (row && tableRef.value) {
						tableRef.value.toggleRowSelection(row, true);
					}
				});
			} else {
				// 非禁用的项可以正常取消选择
				if (wasInitialSelected) {
					// 如果之前是初始化选中的，用户现在取消了，从 initialSelectedMap 移除
					initialSelectedMap.value.delete(id);
				}
				if (wasUserSelected) {
					// 如果之前是用户选中的，从 selectedMap 移除
					selectedMap.value.delete(id);
				}
			}
		}
	});
	
	// 更新当前页的选中数组
	selectedRows.value = val;
}
function onPageChange(val: number) {
	page.value = val;
	fetchData();
}
function onConfirm() {
	// 返回所有选中的项（跨页）- 包括用户选择和初始化时选中的项，但排除已禁用的项（避免重复添加）
	const allSelected = Array.from(selectedMap.value.values()).filter((device: Device) => {
		// 只返回新选中的项，不在 disabledDeviceIds 中的项
		return !props.disabledDeviceIds?.includes(device.id);
	});
	// 添加初始化时选中但用户未操作过的项（排除已禁用的项）
	initialSelectedMap.value.forEach((device, id) => {
		if (!selectedMap.value.has(id) && !props.disabledDeviceIds?.includes(device.id)) {
			allSelected.push(device);
		}
	});
	
	// 如果没有新选中的项，提示用户
	if (allSelected.length === 0) {
		emit('update:visible', false);
		return;
	}
	
	emit('confirm', allSelected);
	emit('update:visible', false);
}
function onCancel() {
	// 重置状态
	search.value = '';
	selectedRows.value = [];
	selectedMap.value.clear();
	initialSelectedMap.value.clear();
	page.value = 1;
	emit('update:visible', false);
}
watch([visible], async (v) => {
	if (visible.value) {
		// 重置搜索条件，以便根据 selectedDeviceCodes 回显
		search.value = '';
		selectedRows.value = [];
		// 清空选中状态，让 fetchData 根据 selectedDeviceCodes 重新初始化（如果是归还模式）
		// 如果是普通模式，则让用户重新选择
		selectedMap.value.clear();
		initialSelectedMap.value.clear();
		// 清空禁用Map，等待数据加载后重新初始化
		disabledMap.value.clear();
		// 如果 disabledDeviceIds 存在，先标记这些ID为禁用（数据加载后会在 initDisabledItemsFromCurrentPage 中完善）
		if (props.disabledDeviceIds && props.disabledDeviceIds.length > 0) {
			props.disabledDeviceIds.forEach((id) => {
				disabledMap.value.set(id, { id } as Device);
			});
		}
		page.value = 1;
		await fetchData();
		nextTick(() => {
			searchInput.value?.focus();
		});
	} else {
		// 对话框关闭时清理状态
		search.value = '';
		selectedRows.value = [];
		selectedMap.value.clear();
		initialSelectedMap.value.clear();
		disabledMap.value.clear();
		page.value = 1;
	}
});

// 监听 disabledDeviceIds 变化
watch(() => props.disabledDeviceIds, () => {
	if (visible.value) {
		// 清空并重新初始化禁用项
		disabledMap.value.clear();
		if (props.disabledDeviceIds && props.disabledDeviceIds.length > 0) {
			props.disabledDeviceIds.forEach((id) => {
				disabledMap.value.set(id, { id } as Device);
			});
		}
		initDisabledItemsFromCurrentPage();
		nextTick(() => {
			restoreSelection();
		});
	}
}, { deep: true });
</script>
