<template>
	<el-dialog
		v-model="state.dialogVisible"
		draggable
		title="延期申请"
		ref="dialogRef"
		@mouseup="mouseup"
		:style="'transform: ' + state.transform + ';'"
		append-to-body
		destroy-on-close
		:close-on-click-modal="false"
		@close="close"
	>
		<div v-loading="state.loading">
			<el-form :model="state.delayForm" label-width="110px" ref="delayFormRef">
				<el-row :gutter="10">
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="工单编码"> {{ state.orderDetail.no }} </el-form-item>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="工单标题"> {{ state.orderDetail.title }} </el-form-item>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="申请人"> {{ userInfos.name }} </el-form-item>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="申请部门"> {{ userInfos.orgName }} </el-form-item>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="申请时间"> {{ formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS') }} </el-form-item>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="当前期满时间"> {{ formatDate(state.orderDetail.expiredTime, 'YYYY-mm-dd HH:MM:SS') }} </el-form-item>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="下一环节" prop="nextStepCode" :rules="[{ required: true, message: '请选择下一环节', trigger: 'change' }]">
							<el-select v-model="state.delayForm.nextStepCode" placeholder="请选择下一环节" class="w100" @change="selectNextStep">
								<el-option v-for="item in state.nextStepOptions" :key="item.key" :label="item.value" :value="item.key" />
							</el-select>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-if="showHandlers">
						<el-form-item
							label="办理对象"
							prop="nextHandlers"
							:rules="[{ required: nextHandlersRequired, message: '请选择办理对象', trigger: 'change' }]"
						>
							<el-select-v2
								v-model="state.delayForm.nextHandlers"
								:options="state.handlerOptions"
								placeholder="请选择办理对象"
								class="w100"
								multiple
								clearable
								collapse-tags
								collapse-tags-tooltip
								filterable
								value-key="key"
								@change="selectHandlers"
								:multiple-limit="multipleLimit"
							/>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="12" v-loading="state.loading">
						<el-form-item prop="timeLimitCount" :rules="[{ required: true, message: '请填写延期申请数量', trigger: 'blur' }]" label-width="130px">
							<template #label>
								<div style="height: 34px; display: flex; align-items: center">
									延期申请数量
									<el-tooltip placement="top-start">
										<SvgIcon name="ele-QuestionFilled" size="18px" class="ml3" />
										<template #content> 延期申请数量为1-{{ AppConfigInfo.applyDelayTime }} </template>
									</el-tooltip>
								</div>
							</template>
							<el-row :gutter="10" class="w100">
								<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
									<el-input-number
										placeholder="延期申请数量"
										v-model="state.delayForm.timeLimitCount"
										controls-position="right"
										class="w100"
										:min="1"
										:max="AppConfigInfo.applyDelayTime"
									></el-input-number>
								</el-col>
								<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" v-loading="state.loading">
									<el-form-item
										label=""
										label-width="0"
										prop="timeLimitUnit"
										:rules="[{ required: true, message: '请选择延期申请单位', trigger: 'change' }]"
									>
										<el-select disabled v-model="state.delayForm.timeLimitUnit" placeholder="延期申请单位">
											<el-option v-for="item in timeType" :value="item.key" :key="item.key" :label="item.value" />
										</el-select>
									</el-form-item>
								</el-col>
							</el-row>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="" prop="isSms">
							<el-checkbox v-model="state.delayForm.isSms" label="短信通知" />
						</el-form-item>
					</el-col>
					<!--					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
						<el-form-item label="延期后期满时间"> {{ state.delayForm.endTime }} </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' }]">
							<common-advice
								@chooseAdvice="chooseAdviceDelay"
								v-model="state.delayForm.content"
								placeholder="请填写延期申请理由"
								:loading="state.loading"
								:commonEnum="commonEnum.Delay"
								:maxlength="AppConfigInfo.handleOpinionWordLimit"
							/>
						</el-form-item>
					</el-col>
					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
						<el-form-item label="附件">
							<annex-list name="延期附件" v-model:format="handleFilesDelay" :businessId="state.orderDetail.id" classify="延期上传" />
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
		</div>
		<template #footer>
			<span class="dialog-footer">
				<el-button @click="closeDialog" class="default-button">取 消</el-button>
				<el-button type="primary" @click="onSubmit(delayFormRef)" :loading="state.loading">确定</el-button>
			</span>
		</template>
	</el-dialog>
</template>

<script setup lang="ts" name="processApproval">
import { computed, defineAsyncComponent, reactive, ref } from 'vue';
import { ElMessage, FormInstance } from 'element-plus';
import other from '@/utils/other';
import { commonEnum } from '@/utils/constants';
import { transformFile } from '@/utils/tools';
import { formatDate } from '@/utils/formatTime';
import { delayApply, delayApproveParams, delayBaseData, delayDetail, delayModify, workflowDelayParams } from '@/api/business/delay';
import { useAppConfig } from '@/stores/appConfig';
import { storeToRefs } from 'pinia';
import { useUserInfo } from '@/stores/userInfo';

// 引入组件
const CommonAdvice = defineAsyncComponent(() => import('@/components/CommonAdvice/index.vue')); // 常用意见
const AnnexList = defineAsyncComponent(() => import('@/components/AnnexList/index.vue')); // 附件列表
// 定义子组件向父组件传值/事件
const emit = defineEmits(['orderProcessSuccess', 'orderProcessFailed']);

const storesUserInfo = useUserInfo();
const { userInfos } = storeToRefs(storesUserInfo); // 用户信息
const appConfigStore = useAppConfig();
const { AppConfigInfo } = storeToRefs(appConfigStore); // 系统配置信息
// 定义变量内容
const state = reactive<any>({
	dialogVisible: false, // 弹窗显示隐藏
	delayForm: {
		content: '', // 意见
		nextStepCode: '', // 下一节点
		nextStepName: '', // 下一节点名称
		backToCountersignEnd: false, // 是否回到会签结束节点
		nextHandlers: [], // 下一节点办理对象
		nextMainHandler: '', // 主办人
		isSms: false, // 是否短信通知
		isStartCountersign: false, // 是否发起会签
		stepId: '',
		timeLimitCount: null, // 延期申请数量
		timeLimitUnit: 2, // 延期申请单位 默认工作日
	},
	nextStepOptions: [], // 下一节点
	handlerOptions: [], // 办理对象
	transform: 'translate(0px, 0px)', // 滚动条位置
	loading: false, // 提交按钮loading
	workflowId: '', // 流程id
	handlerClassifies: [], //撤回办理对象
	handleId: '', // 流程处理ID
	annexName: '', // 附件标题
	inputPlaceholder: '', // 意见提示
	orderDetail: {}, // 工单详情
});
const timeType = ref<EmptyArrayType>([]); // 延期申请单位
// 打开弹窗
const openDialog = async (val: any) => {
	state.loading = true;
	state.dialogVisible = true;
	try {
		const [workflowDelayResponse, responseDelay] = await Promise.all([workflowDelayParams(), delayBaseData()]); //获取开启流程参数
		timeType.value = responseDelay.result?.timeType ?? []; // 延期时间单位
		handleResult(workflowDelayResponse);
		state.orderDetail = val.orderDetail;
		state.loading = false;
	} finally {
		state.loading = false;
	}
};
const canStartCountersign = ref<boolean>(false); // 是否可以发起会签
const handleResult = (res: any) => {
	state.nextStepOptions = res.result.steps; //办理对象选择内容
	canStartCountersign.value = res.result.canStartCountersign ?? false; // 是否可以发起会签
	if (state.nextStepOptions.length === 1) {
		// 下一节点是否只有一个 默认选中第一个
		setTimeout(() => {
			state.delayForm.nextStepCode = state.nextStepOptions[0].key; // 下一节点code
			state.delayForm.nextStepName = state.nextStepOptions[0].value; // 下一节点name
			state.delayForm.backToCountersignEnd = state.nextStepOptions[0].backToCountersignEnd ?? false; // 是否回到会签结束节点
		}, 0);
		selectNextStep(state.nextStepOptions[0].key); // 查询流程下一节点参数
	} else {
		state.delayForm.nextStepCode = '';
		state.delayForm.nextStepName = '';
	}
	state.delayForm.stepId = res.result.stepId;
	state.loading = false;
};
// 流程选择下一环节
const fastStepName = ref(''); // 推荐派单处理对象
const fastStepCode = ref(''); // 推荐派单处理对象code
const nextHandlersRequired = ref<Boolean>(false);
const selectNextStep = (val: any) => {
	delayFormRef.value?.resetFields('nextHandlers');
	const next = state.nextStepOptions.find((item: any) => item.key === val);
	const items = next.items; //获取下一节点
	state.delayForm.nextStepName = next.value; // 下一节点name
	state.delayForm.backToCountersignEnd = next.backToCountersignEnd ?? false; // 是否回到会签结束节点
	state.delayForm.handlerType = next.handlerType;
	state.delayForm.businessType = next.businessType;
	state.delayForm.flowDirection = next.flowDirection;
	state.handlerOptions = items ?? [];
	state.handlerOptions = state.handlerOptions.map((item: any) => {
		return {
			value: {
				...item,
			},
			label: item.value,
		};
	});
	fastStepName.value = next.recommendOrgName; // 推荐派单处理对象
	fastStepCode.value = next.recommendOrgId; // 推荐派单处理对象code
	// 办理对象是否必填
	// nextHandlersRequired.value = ![0].includes(next.handlerType) && !showStepsArr.includes(state.processType);
	nextHandlersRequired.value = ![0].includes(next.handlerType);

	if (items.length === 1) {
		// 如果办理对象只有一个默认选中
		state.delayForm.nextHandlers = [items[0]];
	}

};
// 办理对象是否能够选择多个(可以发起会签可以选择多个，不能发起会签只能选择一个)
const multipleLimit = computed(() => {
	return canStartCountersign.value ? 0 : 1;
});

// 是否展示办理对象 (只有结束节点不展示 next.stepType===2 表示为结束节点)
const showHandlers = computed(() => {
	const next = state.nextStepOptions.find((item: any) => item.key === state.delayForm.nextStepCode);
	if (!next) return true;
	return next.stepType !== 2;
});

// 选择办理对象
const selectHandlers = () => {
	if (state.delayForm.nextHandlers.length <= 1) {
		// 如果只有一个办理对象就不需要发起会签
		state.delayForm.isStartCountersign = false;
	}
};
// 设置抽屉
const dialogRef = ref<RefType>();
const mouseup = () => {
	state.transform = dialogRef.value.dialogContentRef.$el.style.transform;
};
// 关闭弹窗
const closeDialog = () => {
	state.dialogVisible = false;
};
// 重置表单方法
const restForm = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.resetFields();
	formEl.clearValidate();
	state.delayForm.files = [];
};
// 选择常用意见 填入填写框 延期
const chooseAdviceDelay = (item: any) => {
	state.delayForm.content += item.content;
};
const afterSubmit = (emitType?: 'orderProcessSuccess' | 'orderProcessFailed', showMessage?: boolean, message?: string) => {
	state.loading = false;
	closeDialog();
	const msg = message ?? '操作成功';
	if (showMessage) ElMessage.success(msg);
	if (emitType) emit(emitType);
};
const delayFormRef = ref<RefType>();
const close = () => {
	restForm(delayFormRef.value);
};
// 提交
const handleFilesDelay = ref<EmptyArrayType>([]); // 延期附件
const onSubmit = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.validate((valid: boolean) => {
		if (!valid) return;
		state.loading = true;
		const requestDelay = {
			data: {
				orderId: state.orderDetail.id,
				delayNum: state.delayForm.timeLimitCount,
				delayUnit: state.delayForm.timeLimitUnit,
				delayReason: state.delayForm.content,
				files: handleFilesDelay.value,
			},
			workflow: {
				nextStepCode: state.delayForm.nextStepCode,
				nextStepName: state.delayForm.nextStepName,
				backToCountersignEnd: state.delayForm.backToCountersignEnd,
				nextHandlers: state.delayForm.nextHandlers,
				flowDirection: state.delayForm.flowDirection,
				handlerType: state.delayForm.handlerType,
				stepType: state.delayForm.stepType,
				businessType: state.delayForm.businessType,
				isSms: state.delayForm.isSms,
				opinion: state.delayForm.content,
				files: handleFilesDelay.value,
			},
		};
		delayApply(requestDelay)
			.then(() => {
				afterSubmit('orderProcessSuccess', true, '延期申请成功');
			})
			.catch(() => {
				afterSubmit('orderProcessFailed');
			});
	});
};
// 暴露变量
defineExpose({
	openDialog,
	closeDialog,
});
</script>
