<template>
	<div class="auxiliary-event-class-container layout-padding">
		<div class="layout-padding-auto layout-padding-view pd20">
			<el-row class="mb20" :gutter="10">
				<el-col :xs="24" :sm="12" :md="18" :lg="18" :xl="18">
					<el-form :model="state.queryParams" ref="ruleFormRef" inline @submit.native.prevent>
						<el-form-item label="关键字" prop="keyword" class="mb0">
							<el-input v-model="state.queryParams.keyword" placeholder="事件名称" @keyup.enter="handleQuery" class="keyword-input" />
						</el-form-item>
						<el-form-item class="mb0">
							<el-button type="primary" @click="handleQuery" :loading="state.loading"> <SvgIcon name="ele-Search" class="mr5" />查询 </el-button>
							<el-button @click="resetQuery(ruleFormRef)" v-waves class="default-button" :loading="state.loading">
								<SvgIcon name="ele-Refresh" class="mr5" />重置
							</el-button>
						</el-form-item>
					</el-form>
				</el-col>
				<el-col :xs="24" :sm="12" :md="6" :lg="6" :xl="6" style="text-align: right">
					<el-button type="primary" @click="expand" :loading="state.loading"
						><SvgIcon
							name="ele-ArrowDownBold"
							style="transition: transform var(--el-transition-duration)"
							:style="state.isExpand ? 'transform: none' : 'transform: rotateZ(180deg)'"
							class="mr5"
						/>
						{{ state.isExpand ? '收起' : '展开' }}</el-button
					>
					<el-button type="primary" @click="onAdd" v-auth="'auxiliary:eventClass:add'" :loading="state.loading">
						<SvgIcon name="ele-Plus" class="mr5" />新增
					</el-button>
					<el-button type="primary" @click="onDelete" v-auth="'auxiliary:eventClass:delete'" :loading="state.loading" :disabled="disabled">
						<SvgIcon name="ele-Delete" class="mr5" />删除
					</el-button>
				</el-col>
			</el-row>
			<!-- 表格 -->
			<el-auto-resizer class="table" v-loading="state.loading">
				<template #default="{ height, width }">
					<el-table-v2
						v-model:expanded-row-keys="state.expandedRowKeys"
						:columns="state.columns"
						:data="state.tableData"
						expand-column-key="eventFullName"
						fixed
						:width="width"
						:height="height"
						ref="virtuallyTableRef"
					>
						<template #empty>
							<Empty />
						</template>
					</el-table-v2>
				</template>
			</el-auto-resizer>
		</div>
		<event-add ref="eventRef" @updateList="queryList" />
	</div>
</template>
<script lang="tsx" setup name="auxiliaryEventClass">
import type { FunctionalComponent } from 'vue';
import { computed, defineAsyncComponent, onActivated, onMounted, reactive, ref, unref, watch } from 'vue';
import type { CheckboxValueType, FormInstance } from 'element-plus';
import { ElButton, ElMessage, ElMessageBox } from 'element-plus';
import { formatDate } from '@/utils/formatTime';
import { throttle } from '@/utils/tools';
import other from '@/utils/other';
import { treeEventClassAll, treeEventClassDelete } from '@/api/auxiliary/eventClass';
// 引入组件
const EventAdd = defineAsyncComponent(() => import('@/views/auxiliary/eventClass/component/Event-add.vue')); // 新增事件

type SelectionCellProps = {
	value: boolean;
	intermediate?: boolean;
	onChange: (value: CheckboxValueType) => void;
};
const SelectionCell: FunctionalComponent<SelectionCellProps> = ({ value, intermediate = false, onChange }) => {
	return <ElCheckbox onChange={onChange} modelValue={value} indeterminate={intermediate} />;
};
// 根据ID递归查找所有父级
const findParent = (arr, id) => {
	let result = [];
	const search = (data, nodeId) => {
		for (const node of data) {
			if (node.id === nodeId) {
				result.unshift(node);
				search(arr, node.parentId);
				break;
			} else if (node.children) {
				search(node.children, nodeId);
			}
		}
	};
	search(arr, id);
	return result;
};

// 递归改变选中状态
const changeChecked = (data: any, value: string | number | boolean) => {
	data.checked = value;
	const parent = findParent(state.tableData, data.parentId);
	// 判断父级是否存在
	if (parent) {
		// 判断父级是否有选中
		for (const node of parent) {
			node.checked = node.children.every((v: any) => v.checked);
		}
	}
	const arr = data.children;
	const change = (arr: any) => {
		if (!arr || !arr.length || !Array.isArray(arr)) return;
		arr.map((item: any) => {
			item.checked = value;
			if (item.children && item.children.length) {
				change(item.children);
			}
		});
	};
	if (arr && arr.length) {
		change(arr);
	} else {
		data.checked = value;
	}
};
// 递归判断全部选中
const isAllCheck = (arr: unknown, data?: any) => {
	if (!arr || !arr.length || !Array.isArray(arr)) return false;
	return arr.every((v: any) => {
		if (v.checked) return true;
		if (v.children && v.children.length) {
			return isAllCheck(v.children);
		}
	});
};
// 递归判断是否有选中
const isCheck = (arr: unknown, data?: any) => {
	if (!arr || !arr.length || !Array.isArray(arr)) return false;
	return arr.some((v: any) => {
		if (v.checked) return true;
		if (v.children && v.children.length) {
			return isCheck(v.children);
		}
	});
};
// 全选
const allCheck = (arr: any, value: string | number | boolean) => {
	if (!arr || !arr.length || !Array.isArray(arr)) return;
	arr.map((item: any) => {
		item.checked = value;
		if (item.children && item.children.length) {
			allCheck(item.children, value);
		}
	});
};
// 定义变量内容
const state = reactive<any>({
	tableData: [], // 获取所有菜单
	staticArr: [], // 静态数据
	loading: false, // 加载状态
	queryParams: {
		keyword: null, // 关键字
	},
	expandedRowKeys: [], // 展开行
	columns: [
		{
			key: 'selection',
			width: 50,
			align: 'center',
			cellRenderer: ({ rowData }) => {
				const onChange = (value: CheckboxValueType) => {
					return changeChecked(rowData, value);
				};
				const containsChecked = isCheck(rowData.children, rowData);
				const allSelected = isAllCheck(rowData.children, rowData);
				return <SelectionCell value={rowData.checked || allSelected} intermediate={containsChecked && !allSelected} onChange={onChange} />;
			},
			headerCellRenderer: () => {
				const _data = unref(state.tableData);
				const onChange = (value: CheckboxValueType) => {
					return allCheck(_data, value);
				};
				const allSelected = isAllCheck(_data);
				const containsChecked = isCheck(_data);

				return <SelectionCell value={allSelected} intermediate={containsChecked && !allSelected} onChange={onChange} />;
			},
		},
		{
			key: 'eventFullName',
			dataKey: 'eventFullName',
			title: '区域名称',
			width: 600,
		},
		{
			key: 'id',
			dataKey: 'id',
			title: 'id',
			width: 400,
		},
		{
			key: 'orderBy',
			dataKey: 'orderBy',
			title: '排序',
			width: 100,
		},
		{
			key: 'creationTime',
			dataKey: 'creationTime',
			title: '创建时间',
			width: 200,
			cellRenderer: (data: any) => {
				return <span>{formatDate(new Date(data.rowData.creationTime), 'YYYY-mm-dd HH:MM:SS')}</span>;
			},
		},
	],
	isExpand: false, // 是否展开
});
const ruleFormRef = ref<RefType>(); // 搜索表单ref
// 搜索
const formatTable = (list: any[], keyword: string) => {
	if (!list.length || !Array.isArray(list)) return [];
	let emptyArr: any[] = [];
	list.map((item) => {
		if (item.eventFullName.includes(keyword)) {
			if (item.children && Array.isArray(item.children) && item.children.length > 0) {
				item.children = formatTable(item.children, keyword);
			}
			emptyArr.push(item);
		} else if (item.children && Array.isArray(item.children) && item.children.length > 0) {
			item.children = formatTable(item.children, keyword);
			if (item.children.length) {
				emptyArr.push(item);
			}
		}
	});
	return emptyArr;
};
let emptyArr: any[] = [];
const getExpand = (list: any[]) => {
	if (!list.length || !Array.isArray(list)) return [];
	list.map((item) => {
		if (item.children && Array.isArray(item.children) && item.children.length > 0) {
			getExpand(item.children);
		}
		emptyArr.push(item.id);
	});
	return emptyArr;
};
/** 搜索按钮操作 节流操作 */
const handleQuery = throttle(() => {
	if (state.queryParams.keyword) {
		state.loading = true;
		state.expandedRowKeys = [];
		emptyArr = [];
		state.tableData = formatTable(other.deepClone(state.staticArr), state.queryParams.keyword);
		state.expandedRowKeys = getExpand(state.tableData);
		state.isExpand = true;
		state.loading = false;
	} else {
		queryList();
	}
}, 300);
/** 重置按钮操作 */
const resetQuery = throttle((formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.resetFields();
	queryList();
	state.expandedRowKeys = [];
	emptyArr = [];
	state.isExpand = false;
}, 300);
// 打开新增弹窗
const eventRef = ref<RefType>(); // 新增组织机构ref
const onAdd = (row?: any) => {
	eventRef.value.openDialog(state.tableData, row);
};
const expand = () => {
	state.isExpand = !state.isExpand;
};
watch(
	() => state.isExpand,
	(old: Boolean) => {
		if (old) getAllIds(state.tableData);
		else state.expandedRowKeys = [];
	}
);
const getAllIds = (arr: any) => {
	if (!arr) return [];
	arr.forEach((v: any) => {
		if (v.children?.length) {
			getAllIds(v.children);
			state.expandedRowKeys.push(v.id);
		}
	});
};
const disabled = computed(() => {
	return !isCheck(state.tableData);
});
// 获取并返回选中的id
const ids = ref<EmptyArrayType>([]);
const getIds = (arr: any) => {
	if (!arr) return [];
	arr.forEach((v: any) => {
		if (v.checked) {
			ids.value.push(v.id);
		}
		if (v.children?.length) {
			getIds(v.children);
		}
	});
	return ids;
};
// 获取选中的名字
const names = ref<EmptyArrayType>([]);
const getNames = (arr: any) => {
	if (!arr) return [];
	arr.forEach((v: any) => {
		if (v.checked) {
			names.value.push(v.eventFullName);
		}
		if (v.children?.length) {
			getNames(v.children);
		}
	});
	return names.value.join(',');
};
// 删除当前行
const onDelete = () => {
	ids.value = [];
	names.value = [];
	const idArray = getIds(state.tableData);
	const nameArray = getNames(state.tableData);
	ElMessageBox.confirm(`此操作将永久删除事件：【${nameArray}】, 是否继续?`, '提示', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		type: 'warning',
	})
		.then(() => {
			treeEventClassDelete(idArray).then(() => {
				ElMessage.success('删除成功');
				queryList();
			});
		})
		.catch(() => {});
};
// 获取所有部门结构
const queryList = async () => {
	state.loading = true;
	try {
		const { result } = await treeEventClassAll();
		state.tableData = result ?? [];
		state.staticArr = result ?? [];
		state.loading = false;
		state.isExpand = false;
	} catch (error) {
		console.log(error);
		state.loading = false;
	}
};
// 页面加载时
onMounted(() => {
	queryList();
});
const virtuallyTableRef = ref<RefType>();
onActivated(() => {
	virtuallyTableRef.value.scrollToTop(0); // 回到顶部
});
</script>
<style lang="scss" scoped>
.auxiliary-event-class-container {
	.table {
		flex: 1;
	}
}
</style>
