<template>
	<!-- 同意 拒绝 弹窗  同意/拒绝审批 -->
	<el-dialog v-model="operaVisibleDialog" class="le-dialog" :title="currentTip + '审批'" width="700" destroy-on-close :close-on-click-modal="false">
		<el-form ref="formRef" v-loading="uploadLoading" label-position="top" element-loading-text="图片上传中..." :model="form" label-width="80px">
			<el-form-item
				v-if="rejectStrategy === 3 && currentType === 'reject'"
				label="回退节点"
				prop="nodeKey"
				:rules="[{ required: true, message: '请选择回退节点' }]"
			>
				<el-select v-model="form.nodeKey" placeholder="请选择回退节点">
					<el-option v-for="item in rollbackOptions" :key="item.nodeKey" :label="item.nodeName" :value="item.nodeKey" />
				</el-select>
			</el-form-item>

			<el-form-item label="审批意见" prop="content" :rules="[{ required: true, message: '审批意见不能为空' }]">
				<el-input v-model="form.content" type="textarea" placeholder="请输入内容" maxlength="64" show-word-limit> </el-input>
			</el-form-item>

			<el-form-item
				v-if="nodeModelsData.length"
				label="下一节点审批人"
				prop="assigneeMap"
				required
				:rules="[{ required: true, message: '请选择下一节点审批人' }]"
			>
				<el-timeline>
					<el-timeline-item v-for="(item, index) in nodeModelsData" :key="index" placement="top" :timestamp="item.nodeName">
						<div class="flex">
							<!-- type： 1[审核人]   2[抄送人]   4[条件路由]   5[子流程]  6[延时处理] 7[触发器]   8[并行路由]  9[包容路由]  10[路由分支]-->
							<template v-if="item.type === 1">
								<div v-if="[2, 5].indexOf(item.setType) > -1">
									<el-tag v-if="item.setType === 5" type="primary">{{ setTypeOptions_config[item.setType] }}</el-tag>
									<el-tag v-if="item.setType === 2" type="primary">{{
										item.examineLevel === 1 ? '直接主管' : `发起人的第${item.examineLevel}级主管`
									}}</el-tag>
								</div>

								<template v-if="item.setType === 4">
									<!-- item.nodeCandidate里面的type属性  type:1|0  角色|用户-->
									<div v-if="item.nodeCandidate.type === 1" class="mr-2">
										<el-tooltip content="添加角色" placement="bottom">
											<el-button style="width: 32px" @click="selectHandler(item, 3)">
												<svg-icon style="font-size: 18px" icon-class="flow-group-add" />
											</el-button>
										</el-tooltip>
									</div>

									<div v-if="item.nodeCandidate.type === 0" class="mr-2">
										<el-tooltip content="添加用户" placement="bottom">
											<el-button style="width: 32px" @click="selectHandler(item, 1)">
												<svg-icon style="font-size: 18px" icon-class="flow-user-add" />
											</el-button>
										</el-tooltip>
									</div>
								</template>
							</template>

							<template v-else>{{ item.nodeName }}</template>

							<div v-if="item.selectMode === 1" class="flex flex-wrap gap-[6px]">
								<FlowNodeAvatar v-for="(childItem, childIndex) in item.nodeAssigneeList" :key="childIndex" :name="childItem.name" />
							</div>

							<div v-if="item.selectMode !== 1" class="flex flex-wrap gap-[6px]">
								<FlowNodeAvatar v-for="(childItem, childIndex) in item.nodeAssigneeList" :key="childIndex" :name="childItem.name">
									<template #avatar>
										<svg-icon icon-class="flow-group" color="#fff" />
									</template>
								</FlowNodeAvatar>
							</div>
						</div>
					</el-timeline-item>
				</el-timeline>
			</el-form-item>

			<el-form-item v-if="currentType !== 'reject'" label="推荐回复">
				<el-tag v-for="(label, index) in buttonLabels" :key="index" type="info" class="ml-2 cursor-pointer" @click="appendToApprovalComments(label)">
					{{ label }}
				</el-tag>
			</el-form-item>
			<el-form-item v-if="currentType === 'reject'" prop="termination">
				<el-checkbox v-model="form.termination" label="终止流程" />
			</el-form-item>
			<el-form-item v-if="false" prop="attachment" label="附件" class="example-img-box">
				<!--'.docx', '.doc', '.pptx', '.ppt', '.xlsx', '.xls', '.zip', '.csv', '.pdf', '.png', '.jpg'  因前端不支持图片以外格式,所以注释 -->
				<FileUpload
					v-model="form.attachment"
					source="project"
					return="array"
					:limit="5"
					:file-size="10"
					:accept="['.png', '.jpg']"
					@success="clearValidate"
				/>
			</el-form-item>
		</el-form>
		<template #footer>
			<span class="dialog-footer">
				<el-button :loading="btnDisabled" class="dialog-btn" @click="closeDialog">取 消</el-button>
				<el-button type="primary" :loading="btnDisabled" class="dialog-btn" @click="submitForm">确 定</el-button>
			</span>
		</template>

		<!--  选择人员/角色-->
		<use-select ref="useSelectRef" v-bind="active_selectOpts" @update:selected="updateActive_assigneeMap"></use-select>
	</el-dialog>
</template>

<script setup>
import { computed, reactive, watch, toRefs, nextTick } from 'vue'
import FileUpload from '@/components/FileUpload.vue'
import FlowNodeAvatar from '@/components/Flow/FlowNodeAvatar.vue'
import { nextNodesApi, processConsentTaskApi, processPreviousNodeNameApi, processRejectionTaskApi } from '@/api/flow/processTask'
import { ElMessage } from 'element-plus'
import { debounce } from 'lodash-es'
import UseSelect from '@/components/scWorkflow/select.vue'
import { setTypeOptions_config } from '@/components/scWorkflow/nodes/config'

const props = defineProps({
	// 弹窗是否显示
	modelValue: {
		type: Boolean,
		default: false
	},
	// 审核id
	taskId: {
		type: String,
		default: undefined
	},
	// 审核类型 同意(agree) or 拒绝(reject)
	currentType: {
		type: String,
		default: 'agree'
	},
	// 额外 表单数据
	formData: {
		type: Object,
		default: () => ({})
	},
	// 拒绝策略
	rejectStrategy: {
		type: Number || undefined,
		default: undefined
	},
	instanceId: {
		type: String,
		default: ''
	}
})
const buttonLabels = ['同意', '已阅', '收到', '已核对', '合格', '情况属实', '确认', '已复核', '知悉', '辛苦了', '已安排']
const form = reactive({
	nodeKey: undefined,
	content: '',
	assigneeMap: null
	// attachment: []
})
const datas = reactive({
	formRef: null,
	uploadLoading: false,
	rollbackOptions: [],
	btnDisabled: false,
	nodeModelsData: [],
	active_selectOpts: {},
	useSelectRef: null,
	active_assigneeKey: null
})
const { formRef, uploadLoading, rollbackOptions, btnDisabled, nodeModelsData, active_selectOpts, useSelectRef, active_assigneeKey } =
	toRefs(datas)
const $myEmit = defineEmits(['update:modelValue', 'successCb'])

const closeDialog = () => {
	$myEmit('update:modelValue', false)
}

const operaVisibleDialog = computed({
	get() {
		return props.modelValue
	},
	set(val) {
		$myEmit('update:modelValue', val)
	}
})

const currentTip = computed(() => {
	return props.currentType === 'agree' ? '同意' : '拒绝'
})

const clearValidate = () => {}

// 回退节点列表
const getProcessPreviousNodeNameApi = async () => {
	const res = await processPreviousNodeNameApi(props.taskId)
	rollbackOptions.value = res || []
}

const appendToApprovalComments = label => {
	form.content += (form.content ? '' : '') + label
}

const getNextNodesEv = async params => {
	const { nodeModels } = await nextNodesApi(params)
	nodeModelsData.value = nodeModels || []
	/**
	 * "nodeModels": [
            {
                "nodeName": "CEO审批",
                "nodeKey": "flk1720532364452",
                "nodeAssigneeList": [
                    {
                        "id": "0",
                        "name": "CEO"
                    },
										{
                        "id": "1",
                        "name": "CEO1"
                    }
                ],
                "selectMode": 1
            },
        ],
        "nodeType": 1
	 */
}
const findNodeByKey = nodeKey => {
	return nodeModelsData.value.find(node => node.nodeKey === nodeKey)
}

const validateNodeAssigneeLists = () => {
	return (nodeModelsData.value || []).every(node => node.nodeAssigneeList && node.nodeAssigneeList.length > 0)
}

const updateActive_assigneeMap = assignees => {
	const _cur = findNodeByKey(active_assigneeKey.value)
	if (_cur) {
		_cur.nodeAssigneeList = assignees
	}
}
const selectHandler = (item, type) => {
	// nodeModelsData.value数组中查找和nodeKey相匹配的对象值
	const foundNode = findNodeByKey(item.nodeKey)

	let config = foundNode ? { assignees: foundNode.nodeAssigneeList, type } : { assignees: [], type }
	if (item.selectMode === 1) {
		config.selectOpts = { maxSelected: 1 }
	}
	// 插入备选列表 candidateAssignees
	config.selectOpts = { ...config.selectOpts, candidateAssignees: foundNode.nodeCandidate?.assignees }

	active_assigneeKey.value = item.nodeKey
	active_selectOpts.value = config.selectOpts || {}
	nextTick(() => {
		useSelectRef.value.open(type, config.assignees)
	})
}

const submitForm = debounce(() => {
	const isAgree = props.currentType === 'agree'
	if (isAgree && nodeModelsData.value.length) {
		const areAllAssigneeListsValid = validateNodeAssigneeLists()
		form.assigneeMap = !areAllAssigneeListsValid ? null : nodeModelsData.value
	}
	const formData = { taskId: props.taskId, ...props.formData, ...form }
	formRef.value
		.validate()
		.then(async valid => {
			if (valid) {
				btnDisabled.value = true
				let data = null
				if (isAgree) {
					// 同意
					formData.termination = false
					const validNodes = nodeModelsData.value.filter(node => node.selectMode)
					if (validNodes.length) {
						formData.assigneeMap = validNodes.reduce((acc, node) => {
							acc[node.nodeKey] = { assigneeList: node.nodeAssigneeList, type: node.nodeCandidate.type }
							return acc
						}, {}) // 组装成后台需要的格式
					} else {
						formData.assigneeMap = undefined
					}
					data = await processConsentTaskApi(formData)
				} else {
					// 拒绝
					data = await processRejectionTaskApi(formData)
				}
				if (!data) {
					ElMessage({
						message: '执行失败',
						type: 'error'
					})
					return false
				}
				$myEmit('successCb')
				closeDialog()
				btnDisabled.value = false
			}
		})
		.catch(err => {
			btnDisabled.value = false
		})
})

// 驳回 && rejectStrategy === 3
watch(
	() => props.rejectStrategy,
	item => {
		if (item && Number(item) === 3 && props.currentType !== 'agree') {
			getProcessPreviousNodeNameApi()
		}
	},
	{
		immediate: true
	}
)

watch(
	() => operaVisibleDialog.value,
	newVal => {
		if (newVal && props.currentType === 'agree') {
			const t = JSON.parse(props.formData.processForm || '{}')?.formData
			const _param = {
				instanceId: props.instanceId,
				args: t
			}
			getNextNodesEv(_param)
		}
	},
	{ immediate: true }
)
</script>

<style scoped lang="scss">
.example-img-box {
	width: 100% !important;
}

.example-img-box .el-form-item__content {
	display: block;
}
</style>
