<script setup name="BasicInfo">
import { storeToRefs } from 'pinia'
import useFlowStore from '@/store/modules/flow'
import { ref, nextTick, onMounted, computed, watch, onBeforeUnmount } from 'vue'
import UseSelect from '@/components/scWorkflow/select'
import flowDefinition from '@/api/flow/definition'
import process from '@/api/flow/process'
import { useRoute } from 'vue-router'
const route = useRoute()

// 缓存 start
import { EVENT_ENUM, EVENT_BUS, cacheTriggerFunc } from '@/utils/cacheHelper'
const flowStore = useFlowStore()
const { flowName, flowProcessId } = storeToRefs(flowStore)
const cacheLoading = ref(false)
const cacheLoadingNum = ref(600)
const cacheLoadingFr = 1000
const cacheLoadingIndex = ref(null)
const cacheIndex = ref(null) // 缓存索引
const cacheUpdateFr = 3000 // 缓存更新频率
// 缓存 end
const visiblePopover = ref(false)
const selectVisible = ref(false)
const useSelectRef = ref(null)
const nodeRoleList = ref([])
const nodeRoleManageList = ref([])
const currentNode = ref('nodeRoleList')
const formRef = ref()
const options = ref([])
const flowInfo = ref({
	processKey: '', // 流程唯一标识 key
	processName: '', // 流程定义名称
	processIcon: 'https://lf3-ea.bytetos.com/obj/goofy/ee/approval/approval-admin/image/iconLib/v5/cart.svg', // 流程图标
	categoryId: '', // 流程组分类ID
	useScope: 0, // 使用范围 0，全员 1，指定人员（业务关联） 2，均不可提交
	processActorList: [
		{
			actorId: 0, // 参与者ID
			actorName: '', // 参与者
			actorType: 0 // 参与者类型 0，用户 1，部门 2，用户组
		}
	], // 流程参与者，当使用范围为指定人员时候设置
	processPermissionList: [
		{
			userId: 0, // 用户ID
			userName: '', // 用户名
			operateApproval: 0, // 允许编辑/停用/删除审批 0，否 1，
			operateOwner: 0, // 允许添加/移除审批负责人 0，否 1，是
			operateData: 0 // 允许审批数据查询与操作 0，否 1，是
		}
	] // 流程定义权限
})
const rules = {
	processIcon: [
		{
			required: true,
			message: '请选择图标'
		}
	],
	processKey: [
		{
			required: true,
			message: '请输入唯一标识'
		}
	],
	processName: [
		{
			required: true,
			message: '请输入名称'
		}
	],
	categoryId: [
		{
			required: true,
			message: '请选择分组'
		}
	]
}
const validate = () => {
	return new Promise((resolve, reject) => {
		formRef.value.validate((valid, errObj) => {
			if (valid) {
				console.error('valid 成功')
				// cb?.(form.value)
				resolve(form.value)
				// return form.value
				return
			}
			return reject(['基本信息', errObj])
		})
	})
}

const openApprovePerson = () => {
	selectVisible.value = !selectVisible.value
}

const selectHandle = (type, data, name) => {
	currentNode.value = name
	openApprovePerson()
	nextTick(() => {
		useSelectRef.value.open(type, data)
	})
}

const selectContentEv = item => {
	if (currentNode.value === 'nodeRoleList') {
		nodeRoleList.value = item
		const flag = !item.length
		flowInfo.value.useScope = flag ? 0 : 1
		let processActorList = []
		for (let i in item) {
			processActorList.push({
				actorId: item[i].id,
				actorName: item[i].name,
				actorType: 0
			})
		}
		flowInfo.value.processActorList = processActorList
	} else {
		let processPermissionList = []
		for (let i in item) {
			processPermissionList.push({
				userId: item[i].id,
				userName: item[i].name,
				operateApproval: 0,
				operateOwner: 0,
				operateData: 0
			})
		}
		nodeRoleManageList.value = item
		flowInfo.value.processPermissionList = processPermissionList
	}
}

const delRole = (index, itemName) => {
	if (itemName === 'nodeRoleList') {
		nodeRoleList.value.splice(index, 1)
	} else {
		nodeRoleManageList.value.splice(index, 1)
	}
}

const getGroupList = async () => {
	const data = await flowDefinition.flowDefinitionListCategoryApi({})
	options.value = data || []
}

const initBaseicInfEv = item => {
	// item = {
	// 	processId: '1728240012964925441',
	// 	processForm:yu
	// 		'[{"type":"input","field":"userName","title":"输入框","info":"","$required":false,"_fc_drag_tag":"input","hidden":false,"display":true}]',
	// 	processKey: '003key',
	// 	processName: '003名称',
	// 	processIcon: 'https://lf3-ea.bytetos.com/obj/goofy/ee/approval/approval-admin/image/iconLib/v5/cart.svg',
	// 	categoryId: '1725778939021541378',
	// 	remark: '003说明',
	// 	useScope: 1,
	// 	processActorList: [{ actorId: '1705067852272607233', actorName: 'lanceJiang', actorType: 0 }],
	// 	processPermissionList: [{ userId: '1705067852272607233', userName: 'lanceJiang', operateApproval: 0, operateOwner: 0, operateData: 0 }]
	// }
	const { processForm, modelContent, ...rest } = item
	flowInfo.value = rest
	flowStore.setProcessForm(processForm)
	flowStore.setModelContent(modelContent)
	// updateRemoteCache()
	flowProcessId.value = queryObj.value.id // 赋值流程id
	if (item.useScope === 1) {
		nodeRoleList.value = item.processActorList.map(item => {
			return {
				id: item.actorId,
				name: item.actorName,
				actorType: 0
			}
		})
	}

	if (item.processPermissionList && item.processPermissionList.length) {
		nodeRoleManageList.value = item.processPermissionList.map(item => {
			return {
				id: item.userId,
				name: item.userName,
				operateApproval: 0,
				operateOwner: 0,
				operateData: 0
			}
		})
	}
}

// 更新申请信息缓存
const updateRemoteCache = async () => {
	try {
		const params = flowProcessId.value ? { ...flowInfo.value, processId: flowProcessId.value } : flowInfo.value
		const data = await process.progressCreateApi(params)
		flowProcessId.value = data
		Object.keys(flowInfo.value).forEach(key => {
			flowStore.setKeysBasicInfo(key, flowInfo.value[key])
		})
		console.log('updateRemoteCache 实际调用接口, params = ', params, new Date().getTime())
	} catch (e) {
		console.log(e)
	}
}

const handleRemoteCacheRefresh = () => {
	cacheIndex.value && clearTimeout(cacheIndex.value)
	cacheIndex.value = setTimeout(() => {
		// updateRemoteCache()
	}, cacheUpdateFr)
}

// 初始化缓存倒计时
const handleCacheLoading = () => {
	cacheLoading.value = true
	cacheLoadingNum.value = 5
	cacheLoadingIndex.value && clearInterval(cacheLoadingIndex.value)
	cacheLoadingIndex.value = setInterval(() => {
		cacheLoadingNum.value = cacheLoadingNum.value - 1
		if (cacheLoadingNum.value <= 0) {
			cacheLoading.value = false
			cacheLoadingIndex.value && clearInterval(cacheLoadingIndex.value)
			bindCacheEvt()
		}
	}, cacheLoadingFr)
}

const closeCacheLoading = () => {
	console.log('组件销毁时： 关闭定时器---------')
	cacheLoadingIndex.value && clearInterval(cacheLoadingIndex.value)
}

const bindCacheEvt = () => {
	EVENT_BUS.off(EVENT_ENUM.UPDATE_CACHE)
	EVENT_BUS.on(EVENT_ENUM.UPDATE_CACHE, res => {
		console.log('dev.2 EVENT_ENUM.UPDATE_CACHE', res)
		handleRemoteCacheRefresh()
	})
}

// 根据id获取详情
const getCurrentProcessDetailEv = id => {
	process.processDetailApi(id).then(res => {
		initBaseicInfEv(res)
	})
}

// ----- 缓存相关 start ------
const flowBaseInfoWatcher = computed(() => {
	const { processKey, processName, processIcon, categoryId, remark, useScope, processActorList, processPermissionList } = flowInfo.value
	// 只关注参数相关的数据变更
	const _s = {
		processKey, // 流程显示名称
		processName, // 流程定义名称
		processIcon, // 流程图标
		categoryId, // 流程组分类ID
		remark, // 备注说明
		useScope, // 使用范围 0，全员 1，指定人员（业务关联） 2，均不可提交
		processActorList, // 流程参与者，当使用范围为指定人员时候设置
		processPermissionList // 流程定义权限
	}
	console.log('第一步：监听的对象属性 ------', _s)
	return _s
})

// 当前是否是编辑
const queryObj = computed(() => route.query)

watch(
	flowBaseInfoWatcher,
	(newVal, oldVal) => {
		console.log('第二步：执行同步emit方法 ------', newVal, oldVal)
		cacheTriggerFunc()
	},
	{ deep: true }
)

// 流程名称变化
watch(
	() => flowInfo.value.processName,
	newVal => {
		flowName.value = newVal
	}
)

// ----- 缓存相关 end ------

onMounted(() => {
	getGroupList()
	handleCacheLoading()
	flowStore.$reset() // 重置缓存

	if (queryObj.value.id) {
		getCurrentProcessDetailEv(queryObj.value.id)
	}
})

onBeforeUnmount(() => {
	closeCacheLoading()
})

defineExpose({
	formRef,
	validate
})
</script>

<template>
	<div class="base-info">
		<div v-if="false" style="font-size: 18px; position: absolute; left: 10px; top: 20px; z-index: 9999; color: red">
			{{ cacheLoadingNum }}秒之后开启自动缓存...
		</div>

		<div class="base-info-panel" style="position: relative">
			<div style="font-size: 18px; position: absolute; right: 10px; top: 20px; z-index: 9999">
				<el-button type="primary" @click="updateRemoteCache">暂存</el-button>
			</div>
			<el-form ref="formRef" :model="flowInfo" :rules="rules" label-position="top">
				<el-form-item label="图标" prop="processIcon">
					<el-space>
						<div class="icon-shower">
							<img :src="flowInfo.processIcon" alt="" />
						</div>
					</el-space>

					<el-popover placement="right-end" :width="450" trigger="focus" class="base-popover" :visible="visiblePopover">
						<div class="icon-selector__dialog__content">
							<div class="icon-selector-list">
								<div v-for="item in 27" :key="item" class="icon-selector-item" @click="visiblePopover = !visiblePopover">
									<img src="https://lf3-ea.bytetos.com/obj/goofy/ee/approval/approval-admin/image/iconLib/v5/cart.svg" alt="" />
								</div>
							</div>
						</div>
						<template #reference>
							<el-link :underline="false" @click="visiblePopover = !visiblePopover">修改</el-link>
						</template>
					</el-popover>
				</el-form-item>
				<el-form-item label="唯一标识 key" prop="processKey">
					<el-input v-model="flowInfo.processKey" clearable></el-input>
				</el-form-item>
				<el-form-item label="名称" prop="processName">
					<el-input v-model="flowInfo.processName" clearable></el-input>
				</el-form-item>
				<el-form-item label="说明" prop="remark">
					<el-input v-model="flowInfo.remark" type="textarea" clearable></el-input>
				</el-form-item>
				<el-form-item label="分组" prop="categoryId">
					<el-select v-model="flowInfo.categoryId">
						<el-option v-for="item in options" :key="item.categoryId" :label="item.categoryName" :value="item.categoryId" />
					</el-select>
				</el-form-item>
				<el-form-item label="谁可以发起该流程（不选择，默认全员）" prop="谁可以发起该流程">
					<div class="add-btn" @click="selectHandle(1, nodeRoleList, 'nodeRoleList')">
						<el-icon :size="18"><Plus /></el-icon>
					</div>
					<div class="tags-list" style="margin-top: 15px; width: 100%">
						<el-tag
							v-for="(role, index) in nodeRoleList"
							:key="role.id"
							type="info"
							closable
							style="margin-right: 8px"
							@close="delRole(index, 'nodeRoleList')"
							>{{ role.name }}</el-tag
						>
					</div>
				</el-form-item>
				<el-form-item label="管理员" prop="管理员">
					<div class="add-btn" @click="selectHandle(1, nodeRoleManageList, 'nodeRoleManageList')">
						<el-icon :size="18"><Plus /></el-icon>
					</div>
					<div class="tags-list" style="margin-top: 15px; width: 100%">
						<el-tag
							v-for="(role, index) in nodeRoleManageList"
							:key="role.id"
							type="info"
							closable
							style="margin-right: 8px"
							@close="delRole(index, 'nodeRoleManageList')"
							>{{ role.name }}</el-tag
						>
					</div>
				</el-form-item>
			</el-form>
		</div>
		<use-select v-if="selectVisible" ref="useSelectRef" @closed="selectVisible = false" @content-ev="selectContentEv"></use-select>
	</div>
</template>

<style scoped lang="scss">
.basic-info-wrap {
	//background: var(--el-color-danger);
}
.flow-name {
	padding-right: 4px;
	color: var(--el-color-danger);
}

.base-info {
	margin: 0 auto;
	padding: 24px 0;
	height: 100%;
	text-align: center;
	overflow-y: auto;
	background-color: #eff0f1;
	position: relative;
	&-panel {
		display: inline-block;
		width: 1128px;
		padding: 24px 288px;
		background-color: #fff;
		text-align: left;
	}
}

.icon-selector__dialog__content {
	height: 384px;
	overflow-x: visible;
	overflow-y: scroll;
	scrollbar-width: none;
	-ms-overflow-style: none;
	.icon-selector-list {
		display: grid;
		grid-template-columns: repeat(5, 64px);
		grid-template-rows: repeat(auto, 64px);
		grid-gap: 16px;
		justify-content: flex-start;
		align-items: flex-start;
		flex-wrap: wrap;
		.icon-selector-item {
			width: 64px;
			height: 64px;
			padding: 8px;
			border: 1px solid #d0d3d6;
			box-sizing: border-box;
			border-radius: 6px;
			cursor: pointer;
			&:hover {
				border-color: #3370ff;
			}
			img {
				width: 100%;
				height: 100%;
				border-radius: 4px;
				overflow: hidden;
			}
		}
	}
}

.icon-shower {
	width: 48px;
	height: 48px;
	border-radius: 50%;
	overflow: hidden;
	img {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}
}

.add-btn {
	width: 48px;
	height: 48px;
	font-family: PingFang SC, Microsoft YaHei;
	font-size: 14px;
	line-height: 20px;
	background-color: #eff0f1;
	border-radius: 50%;
	cursor: pointer;
	display: flex;
	justify-content: center;
	align-items: center;
}
</style>
