<template>
	<el-dialog v-model="state.dialogVisible" width="70%" draggable :title="dialogTitle" @close="close">
		<el-form :model="state.ruleForm" label-width="110px" ref="ruleFormRef" v-loading="loading" scroll-to-error>
			<template v-if="dialogTitle === '编辑通知'">
				<el-row :gutter="10">
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="通知类型" prop="circularObj" :rules="[{ required: true, message: '请选择通知类型型', trigger: 'change' }]">
							<el-select
								v-model="state.ruleForm.circularObj"
								placeholder="请选择通知类型型"
								value-key="dicDataValue"
								class="w100"
								@change="
									(e) => {
										state.ruleForm.circularTypeId = e.dicDataValue;
										state.ruleForm.circularTypeName = e.dicDataName;
									}
								"
							>
								<el-option v-for="item in circularTypeOptions" :value="item" :key="item.dicDataValue" :label="item.dicDataName" />
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
						<el-form-item label="通知标题" prop="title" :rules="[{ required: true, message: '请填写通知标题', trigger: 'blur' }]">
							<el-input v-model="state.ruleForm.title" placeholder="请填写通知标题" clearable show-word-limit maxlength="200"></el-input>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
						<el-form-item label="必须阅读" prop="isMustRead" :rules="[{ required: true, message: '请选择必须阅读', trigger: 'change' }]">
							<el-radio-group v-model="state.ruleForm.isMustRead">
								<el-radio :value="true">是</el-radio>
								<el-radio :value="false">否</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
						<el-form-item label="来源单位" prop="sourceOrgId" :rules="[{ required: true, message: '请选择来源单位', trigger: 'change' }]">
							<el-cascader
								:options="orgsOptions"
								filterable
								:props="{ value: 'id', label: 'name', emitPath: false, checkStrictly: true }"
								placeholder="请选择来源单位"
								class="w100"
								v-model="state.ruleForm.sourceOrgId"
								ref="orgRef"
								@change="changeOrg"
							>
							</el-cascader>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
						<el-form-item label="通知内容" prop="content" :rules="[{ required: true, message: '请填写通知内容', trigger: 'blur' }]">
							<editor v-model:get-html="state.ruleForm.content" placeholder="请填写通知内容" height="350px" />
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
						<el-form-item label="附件" prop="files" :rules="[{ required: false, message: '请填选择附件', trigger: 'blur' }]">
							<annex-list classify="通知上传" v-model="state.ruleForm.files" v-model:format="filesFormatCircular" />
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
						<el-form-item label="通知对象" prop="circularType" :rules="[{ required: true, message: '请选择通知对象', trigger: 'change' }]">
							<el-radio-group v-model="state.ruleForm.circularType">
								<el-radio :value="item.key" v-for="item in circularTypeEnum" :key="item.key">{{ item.value }}</el-radio>
							</el-radio-group>
						</el-form-item>
					</el-col>
					<el-col
						:xs="24"
						:sm="24"
						:md="24"
						:lg="24"
						:xl="24"
						v-if="state.ruleForm.circularType === 1"
						style="border: var(--el-border); border-radius: var(--el-border-radius-base)"
						class="pd15 mb20"
					>
						<div class="flex-center-align mb10">
							<el-input v-model="state.searchContent" placeholder="通知人姓名/账号" class="w100" clearable>
								<template #prefix>
									<SvgIcon name="ele-Search" />
								</template>
							</el-input>
						</div>
						<div style="height: 400px">
							<el-auto-resizer>
								<template #default="{ height, width }">
									<el-table-v2
										:columns="columns"
										:data="tables"
										:width="width"
										:height="height"
										fixed
										:scrollbar-always-on="true"
										:row-height="40"
										:header-height="40"
									/>
								</template>
							</el-auto-resizer>
						</div>
					</el-col>
					<el-col
						:xs="24"
						:sm="24"
						:md="24"
						:lg="24"
						:xl="24"
						v-if="state.ruleForm.circularType === 2"
						style="border: var(--el-border); border-radius: var(--el-border-radius-base)"
						class="pd15 mb20"
					>
						<div style="height: 400px">
							<v-tree-search
								:data="circularOrgOptions"
								titleField="name"
								keyField="id"
								checkable
								searchPlaceholder="部门名称"
								ref="treeSearchRef"
								v-model="checkOrgList"
								:expandOnFilter="false"
								:cascade="false"
							>
								<template #actions>
									<el-button class="ml10" @click="selectOrgOne"> {{ isOrgOneChecked ? '取消全选一级部门' : '全选一级部门' }} </el-button>
									<el-button @click="selectOrgTwo">{{ isOrgTwoChecked ? '取消全选二级部门' : '全选二级部门' }} </el-button>
								</template>
							</v-tree-search>
						</div>
					</el-col>
				</el-row>
			</template>
			<template v-if="dialogTitle === '编辑公告'">
				<el-row :gutter="10">
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="公告类型" prop="bulletinObj" :rules="[{ required: true, message: '请选择公告类型', trigger: 'change' }]">
							<el-select
								v-model="state.ruleForm.bulletinObj"
								placeholder="请选择公告类型"
								value-key="dicDataValue"
								class="w100"
								@change="
									(e) => {
										state.ruleForm.bulletinTypeId = e.dicDataValue;
										state.ruleForm.bulletinTypeName = e.dicDataName;
									}
								"
							>
								<el-option v-for="item in bulletinTypeOptions" :value="item" :key="item.dicDataValue" :label="item.dicDataName" />
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
						<el-form-item label="公告标题" prop="title" :rules="[{ required: true, message: '请填写公告标题', trigger: 'blur' }]">
							<el-input v-model="state.ruleForm.title" placeholder="请填写公告标题" clearable show-word-limit maxlength="200"></el-input>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
						<el-form-item label="来源单位" prop="sourceOrgId" :rules="[{ required: true, message: '请选择来源单位', trigger: 'change' }]">
							<el-cascader
								:options="orgsOptions"
								filterable
								:props="{ value: 'id', label: 'name', emitPath: false, checkStrictly: true }"
								placeholder="请选择来源单位"
								class="w100"
								v-model="state.ruleForm.sourceOrgId"
								ref="orgRef"
								@change="changeOrg"
							>
							</el-cascader>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
						<el-form-item label="公告范围" prop="pushRangesArray" :rules="[{ required: true, message: '请选择公告范围', trigger: 'change' }]">
							<el-checkbox-group v-model="state.ruleForm.pushRangesArray">
								<el-checkbox :value="item" v-for="item in pushRangesOptions" :key="item.dicDataValue">{{ item.dicDataName }}</el-checkbox>
							</el-checkbox-group>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
						<el-form-item label="公告位置" prop="displayLocationArr" :rules="[{ required: false, message: '请选择公告位置', trigger: 'change' }]">
							<el-checkbox-group v-model="state.ruleForm.displayLocationArr">
								<el-checkbox :value="item" v-for="item in bulletinDisplayLocation" :key="item.dicDataValue">{{ item.dicDataName }}</el-checkbox>
							</el-checkbox-group>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
						<el-form-item label="公告内容" prop="content" :rules="[{ required: true, message: '请填写公告内容', trigger: 'blur' }]">
							<editor v-model:get-html="state.ruleForm.content" placeholder="请填写公告内容" height="350px" />
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
						<el-form-item label="附件" prop="files" :rules="[{ required: false, message: '请填选择附件', trigger: 'blur' }]">
							<annex-list classify="公告上传" v-model="state.ruleForm.files" v-model:format="filesFormatBulletin" />
						</el-form-item>
					</el-col>
				</el-row>
			</template>
		</el-form>
		<template #footer>
			<span class="dialog-footer">
				<el-button @click="closeDialog" class="default-button">取 消</el-button>
				<el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="loading">确 定</el-button>
			</span>
		</template>
	</el-dialog>
</template>

<script setup lang="tsx" name="noticeDetail">
import { reactive, ref, defineAsyncComponent, computed, FunctionalComponent, unref, nextTick } from 'vue';
import {
	bulletinAddBaseData,
	bulletinDetail,
	circularUpdate,
	circularAddBaseData,
	circularDetail,
	getAllUsers,
	bulletinUpdate,
} from '@/api/auxiliary/notice';
import { filterByLevel, throttle, transformFile } from '@/utils/tools';
import { CheckboxValueType, ElCheckbox, ElMessage, FormInstance } from 'element-plus';
import { disabledDate } from '@/utils/constants';
import { VTreeSearch } from '@wsfe/vue-tree';
// 引入组件
const Editor = defineAsyncComponent(() => import('@/components/Editor/index.vue')); // 富文本编辑器
const AnnexList = defineAsyncComponent(() => import('@/components/AnnexList/index.vue')); // 附件列表
// 定义子组件向父组件传值/事件
const emit = defineEmits(['updateList']);
const props = defineProps({
	commonType: {
		type: Array,
		default: () => [],
	},
});
// 定义变量内容
const state = reactive<any>({
	dialogVisible: false,
	ruleForm: {
		isMustRead: false, // 是否必须阅读
		displayLocationArr: [],
	},
	searchContent: '', // 搜索内容
});
let loading = ref<boolean>(false); // 加载状态
// 打开弹窗
const ruleFormRef = ref<RefType>();
const dialogTitle = ref<string>('编辑通知');

const bulletinTypeOptions = ref<EmptyArrayType>([]); // 公告类型
const circularTypeOptions = ref<EmptyArrayType>([]); // 通知类型
const circularTypeEnum = ref<EmptyArrayType>([]); // 通知对象
const pushRangesOptions = ref<EmptyArrayType>([]); // 公告范围
const orgsOptions = ref<EmptyArrayType>([]); // 来源单位
const circularOrgOptions = ref<EmptyArrayType>([]); // 通知对象 部门
const userTables = ref<EmptyArrayType>([]); // 通知对象 个人
const bulletinDisplayLocation = ref<EmptyArrayType>([]); // 公告位置
const checkOrgList = ref<EmptyArrayType>([]); // 选择的部门
const openDialog = async (row: any, type: string) => {
	dialogTitle.value = type;
	loading.value = true;
	state.dialogVisible = true;
	switch (type) {
		case '编辑通知':
			try {
				const [circularResponse, userResponse, circularDetailResponse] = await Promise.all([
					circularAddBaseData(),
					getAllUsers(),
					circularDetail(row.id),
				]);
				circularTypeOptions.value = circularResponse.result?.circularType ?? [];
				orgsOptions.value = circularResponse.result?.orgsOptions ?? [];
				circularTypeEnum.value = circularResponse.result?.circularTypeEnum ?? [];
				circularOrgOptions.value = circularResponse.result?.orgsOptions ?? [];
				userTables.value = userResponse.result ?? [];
				state.ruleForm = circularDetailResponse.result ?? {};
				state.ruleForm.circularObj = {
					dicDataValue: circularDetailResponse.result?.circularTypeId,
					dicDataName: circularDetailResponse.result?.circularTypeName,
				};
				state.ruleForm.files = transformFile(circularDetailResponse?.result?.files);
				if (state.ruleForm.circularType === 1) {
					// 个人
					for (let i of state.ruleForm.circularReadGroups) {
						for (let j of userTables.value) {
							if (i.userId === j.id) {
								j.checked = true;
							}
						}
					}
				} else if (state.ruleForm.circularType === 2) {
					// 部门
					await nextTick();
					const keys = state.ruleForm.circularReadGroups.map((item: any) => {
						return item.orgId;
					});
					checkOrgList.value = keys;
				}
				loading.value = false;
			} catch (error) {
				console.log(error);
				loading.value = false;
			}
			break;
		case '编辑公告':
			try {
				const [responseAnnounce, bulletinDetailResponse] = await Promise.all([bulletinAddBaseData(), bulletinDetail(row.id)]);
				bulletinTypeOptions.value = responseAnnounce.result?.bulletinType ?? [];
				pushRangesOptions.value = responseAnnounce.result?.pushRanges ?? [];
				orgsOptions.value = responseAnnounce.result?.orgsOptions ?? [];
				bulletinDisplayLocation.value = responseAnnounce.result?.bulletinDisplayLocation ?? [];
				state.ruleForm = bulletinDetailResponse.result ?? {};
				state.ruleForm.bulletinObj = {
					dicDataValue: bulletinDetailResponse.result?.bulletinTypeId,
					dicDataName: bulletinDetailResponse.result?.bulletinTypeName,
				};
				state.ruleForm.files = transformFile(bulletinDetailResponse?.result?.files);
				state.ruleForm.pushRangesArray = [];
				const arr = state.ruleForm.pushRanges.map((item: any) => {
					return item.key;
				});
				for (let i of arr) {
					for (let j of pushRangesOptions.value) {
						if (i === j.dicDataValue) {
							state.ruleForm.pushRangesArray.push(j);
						}
					}
				}
				if (state.ruleForm.displayLocation) {
					state.ruleForm.displayLocationArr = [];
					const arr1 = state.ruleForm.displayLocation?.map((item: any) => {
						return item.key;
					});
					for (let i of arr1) {
						for (let j of bulletinDisplayLocation.value) {
							if (i === j.dicDataValue) {
								state.ruleForm.displayLocationArr.push(j);
							}
						}
					}
				}
				loading.value = false;
			} catch (error) {
				console.log(error);
				loading.value = false;
			}
			break;
	}
};
const orgRef = ref<RefType>(); //来源单位
const changeOrg = (type: string) => {
	const currentNode = orgRef.value.getCheckedNodes();
	state[type].sourceOrgName = currentNode[0].label;
};

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} />;
};
const tables = computed({
	get() {
		// 注意： filter() 不会改变原始数组。
		// 模糊搜索
		if (!state.searchContent) return userTables.value;
		// filter() 方法创建一个新的数组，新数组中的元素是通过检查指定数组中符合条件的所有元素。
		// 注意： filter() 不会对空数组进行检测。
		return userTables.value.filter((data: any) => {
			// some() 方法用于检测数组中的元素是否满足指定条件;
			// some() 方法会依次执行数组的每个元素：
			// 如果有一个元素满足条件，则表达式返回true , 剩余的元素不会再执行检测;
			// 如果没有满足条件的元素，则返回false。
			// 注意： some() 不会对空数组进行检测。
			// 注意： some() 不会改变原始数组。
			return Object.keys(data).some((key) => {
				// indexOf() 返回某个指定的字符在某个字符串中首次出现的位置，如果没有找到就返回-1；
				// 该方法对大小写敏感！所以之前需要toLowerCase()方法将所有查询到内容变为小写。
				return String(data[key]).toLowerCase().indexOf(state.searchContent) > -1;
			});
		});
	},
	set(val) {
		// userTables.value = val;
	},
});
const columns = [
	{
		key: 'selection',
		width: 50,
		align: 'center',
		cellRenderer: ({ rowData }) => {
			const onChange = (value: CheckboxValueType) => (rowData.checked = value);
			return <SelectionCell value={rowData.checked} onChange={onChange} />;
		},
		headerCellRenderer: () => {
			const _data = unref(tables);
			const onChange = (value: CheckboxValueType) =>
				(tables.value = _data.map((row) => {
					row.checked = value;
					return row;
				}));
			const allSelected = _data.every((row) => row.checked);
			const containsChecked = _data.some((row) => row.checked);

			return <SelectionCell value={allSelected} intermediate={containsChecked && !allSelected} onChange={onChange} />;
		},
	},
	{
		key: 'name',
		dataKey: 'name',
		title: '姓名',
		width: 300,
		align: 'center',
	},
	{
		key: 'name',
		dataKey: 'userName',
		title: '账号',
		width: 150,
		align: 'center',
	},
	{
		key: 'organization.name',
		dataKey: 'organization.name',
		title: '所属部门',
		width: 150,
		align: 'center',
	},
	{
		key: 'staffNo',
		dataKey: 'staffNo',
		title: '工号',
		width: 100,
		align: 'center',
	},
	{
		key: 'organization.orgTypeText',
		dataKey: 'organization.orgTypeText',
		title: '部门类别',
		width: 100,
		align: 'center',
	},
];

// 全选一级部门
const treeSearchRef = ref<RefType>();
const isOrgOneChecked = ref<boolean>(false);
const selectOrgOne = () => {
	// 先筛选出数组层级为一级的部门
	const oneOrg = filterByLevel(circularOrgOptions.value, 1);
	// 获取一级部门的id
	const oneOrgId = oneOrg.map((item: any) => item.id);
	treeSearchRef.value.setCheckedKeys(oneOrgId, !isOrgOneChecked.value);
	isOrgOneChecked.value = !isOrgOneChecked.value;
};
// 全选二级部门
const isOrgTwoChecked = ref<boolean>(false);
const selectOrgTwo = () => {
	// 先筛选出数组层级为二级的部门
	const twoOrg = filterByLevel(circularOrgOptions.value, 2);
	// 获取二级部门的id
	const twoOrgId = twoOrg.map((item: any) => item.id);
	treeSearchRef.value.setCheckedKeys(twoOrgId, !isOrgTwoChecked.value);
	isOrgTwoChecked.value = !isOrgTwoChecked.value;
};
// 保存
const filesFormatCircular = ref<EmptyArrayType>([]); // 通知附件列表格式化
const filesFormatBulletin = ref<EmptyArrayType>([]); // 公告附件列表格式化
const onSubmit = throttle(async (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	await formEl.validate((valid: boolean) => {
		if (!valid) return;
		loading.value = true;
		switch (dialogTitle.value) {
			case '编辑通知':
				const checkedTable = tables.value?.filter((item: any) => item.checked).map((item: any) => item);
				const nodesOrg = treeSearchRef.value?.getCheckedNodes();
				if (state.ruleForm.circularType === 1 && !checkedTable.length) {
					ElMessage.warning('请选择通知人');
					loading.value = false;
					return;
				}
				if (state.ruleForm.circularType === 2 && !nodesOrg.length) {
					ElMessage.warning('请选择通知部门');
					loading.value = false;
					return;
				}
				let circularReadGroups: { userId: any; userName: any }[] | { orgId: any; orgName: any }[] = [];
				if (state.ruleForm.circularType === 1) {
					//个人
					circularReadGroups = checkedTable.map((item: any) => {
						return {
							userId: item.id,
							userName: item.name,
						};
					});
				} else if (state.ruleForm.circularType === 2) {
					// 部门
					circularReadGroups = nodesOrg.map((item: any) => {
						return {
							orgId: item.id,
							orgName: item.name,
						};
					});
				}
				const circularRequest = {
					id: state.ruleForm.id,
					title: state.ruleForm.title,
					content: state.ruleForm.content,
					circularTypeId: state.ruleForm.circularTypeId,
					circularTypeName: state.ruleForm.circularTypeName,
					circularType: state.ruleForm.circularType,
					isMustRead: state.ruleForm.isMustRead,
					lostEfficacyTime: state.ruleForm.lostEfficacyTime,
					sourceOrgId: state.ruleForm.sourceOrgId,
					sourceOrgName: state.ruleForm.sourceOrgName,
					circularReadGroups,
					files: filesFormatCircular.value,
				};
				circularUpdate(circularRequest)
					.then(() => {
						ElMessage.success('操作成功');
						emit('updateList');
						closeDialog();
						loading.value = false;
					})
					.catch((err: any) => {
						console.log(err);
						loading.value = false;
					});
				break;
			case '编辑公告':
				const pushRanges = state.ruleForm.pushRangesArray.map((item: any) => {
					return {
						key: item.dicDataValue,
						value: item.dicDataName,
					};
				});
				const displayLocation = state.ruleForm.displayLocationArr.map((item: any) => {
					return {
						key: item.dicDataValue,
						value: item.dicDataName,
					};
				});
				const bulletinRequest = {
					id: state.ruleForm.id,
					title: state.ruleForm.title,
					content: state.ruleForm.content,
					bulletinTypeId: state.ruleForm.bulletinTypeId,
					bulletinTypeName: state.ruleForm.bulletinTypeName,
					loseEfficacyTime: state.ruleForm.loseEfficacyTime,
					sourceOrgId: state.ruleForm.sourceOrgId,
					sourceOrgName: state.ruleForm.sourceOrgName,
					pushRanges,
					displayLocation,
					files: filesFormatBulletin.value,
				};
				bulletinUpdate(bulletinRequest)
					.then(() => {
						ElMessage.success('操作成功');
						emit('updateList');
						closeDialog();
						loading.value = false;
					})
					.catch((err: any) => {
						console.log(err);
						loading.value = false;
					});
				break;
		}
	});
}, 300);
// 关闭弹窗
const closeDialog = () => {
	state.dialogVisible = false;
};
const close = () => {
	ruleFormRef.value?.clearValidate();
	ruleFormRef.value?.resetFields();
	checkOrgList.value = [];
};
// 暴露变量
defineExpose({
	openDialog,
	closeDialog,
});
</script>
