package com.yifu.cloud.plus.v1.yifu.archives.utils;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
import com.yifu.cloud.plus.v1.yifu.archives.config.WxConfig;
import com.yifu.cloud.plus.v1.yifu.archives.entity.*;
import com.yifu.cloud.plus.v1.yifu.archives.service.*;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.UpmsDaprUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * @Description: 法大大专业版异步任务
 * @Author: hgw
 * @Date: 2025/10/29 15:20
 **/
@Slf4j
@Component
public class DoFascTask {

	@Autowired
	private FascService fascService;
	@Autowired
	private TFascPushLogService tFascPushLogService;
	@Autowired
	private TEmployeeContractPreService tEmployeeContractPreService;
	@Autowired
	private TEmployeeContractPreHistoryService tEmployeeContractPreHistoryService;
	@Autowired
	private TEmployeeContractInfoService tEmployeeContractInfoService;
	@Autowired
	private TEmployeeContractAuditService tEmployeeContractAuditService;
	@Autowired
	private TContractAutoLogService contractAutoLogService;
	@Autowired
	private WxConfig wxConfig;
	@Autowired
	private UpmsDaprUtils upmsDaprUtils;

	private static String FASC_BIZ_CONTENT_STR = "；fddBizContent：";

	/**
	 * @Description: 合同-批量更换负责人
	 * @Author: huyc
	 * @Date: 2022-7-8
	 * @return: void
	 **/
	@Async
	public void doFascOkCore(TFascPushLog pushLog, String fddEvent, String fddBizContent, String signTaskId
			, String terminationNote) throws Exception {
		log.info("法大大-电子签完成与归档开始");
		pushLog.setTypeKey("fddEvent：" + fddEvent);
		pushLog.setReturnData("初始无事件：fddEvent：" + fddEvent + "fddBizContent：" + fddBizContent);

		if (Common.isNotNull(signTaskId)) {
			// 根据requestId获取信息：
			TEmployeeContractPre pre = tEmployeeContractPreService.getOne(Wrappers.<TEmployeeContractPre>query().lambda()
					.eq(TEmployeeContractPre::getRequestId, signTaskId).last(CommonConstants.LAST_ONE_SQL));
			YifuUser user = getNewYifuUser();
			if (pre != null) {
				TEmployeeContractInfo contractInfo = null;
				if (Common.isNotNull(pre.getContractId())) {
					//如果存在合同申请审核数据，将状态更新成待提交
					contractInfo = tEmployeeContractInfoService.getById(pre.getContractId());
				}
				if (contractInfo != null) {
					if (fddEvent.equals("sign-task-finished")) {
						if (Common.isNotNull(pre.getProcessStatus()) && !pre.getProcessStatus().equals(CommonConstants.dingleDigitStrArray[9])) {
							// 1：签署任务完成事件
							// 8电子待归档
							pre.setProcessStatus(CommonConstants.dingleDigitStrArray[8]);

							// 加日志
							this.saveAuditLogSuccess(pre, "签署成功");

							// 尝试获取归档文件
							boolean flag = fascService.getFileByRequestId(pre.getId());

							contractInfo.setAuditStatus(CommonConstants.TWO_INT);
							// 传了false，就不要审核日志
							tEmployeeContractInfoService.auditContract(contractInfo, user, false);
							if (flag) {
								// 加日志
								this.saveAuditLogSuccess(pre, "归档成功");
								pre.setProcessStatus(CommonConstants.dingleDigitStrArray[9]);

								contractInfo.setIsFile(CommonConstants.ZERO_STRING);
								contractInfo.setContractNo(pre.getRequestId());
								tEmployeeContractInfoService.updateById(contractInfo);
								//瓜子项目编码：皖A694302
								if (CommonConstants.GZ_DEPT_NO.equals(contractInfo.getDeptNo())) {
									//合同归档瓜子合同状态更新已归档
									tEmployeeContractInfoService.updateGzOfferStatus(contractInfo, CommonConstants.EIGHT_STRING, CommonConstants.NINETY_NINE, user.getId(), user.getNickname());
								}
							}
							tEmployeeContractPreService.updateById(pre);


							pushLog.setReturnData("签署任务完成事件：fddEvent：" + fddEvent + FASC_BIZ_CONTENT_STR + fddBizContent);
						}
					} else if (fddEvent.equals("sign-task-canceled") || fddEvent.equals("sign-task-abolish")) {
						// 2：签署任务撤销事件 || 4：签署任务作废事件
						if (fddEvent.equals("sign-task-canceled")) {
							// 4：签署任务作废事件
							pushLog.setReturnData("签署任务撤销事件：fddEvent：" + fddEvent + FASC_BIZ_CONTENT_STR + fddBizContent);
						} else {
							// 4：签署任务作废事件
							pushLog.setReturnData("签署任务作废事件：fddEvent：" + fddEvent + FASC_BIZ_CONTENT_STR + fddBizContent);
						}
						//电子待归档、线下签待归档、已完结的不能撤销签署
						if (Common.isNotNull(pre) && !CommonConstants.NINE_STRING.equals(pre.getProcessStatus()) &&
								!CommonConstants.FOUR_STRING.equals(pre.getProcessStatus()) &&
								!CommonConstants.EIGHT_STRING.equals(pre.getProcessStatus())) {
							//如果不是待确认和待发起，需要记录操作记录
							if (!CommonConstants.ZERO_STRING.equals(pre.getProcessStatus()) &&
									!CommonConstants.ONE_STRING.equals(pre.getProcessStatus()) &&
									Common.isNotNull(pre.getContractId())) {
								// 加日志
								this.saveAuditLogFail(pre, "撤销签署成功", terminationNote);
							}
							pre.setProcessStatus(CommonConstants.TEN_STRING);
							pre.setSignFlag(CommonConstants.ZERO_STRING);
							pre.setRevokeReason(terminationNote);
							tEmployeeContractPreService.updateById(pre);
						}
						//如果存在合同申请审核数据，将状态更新成5撤销签署
						contractInfo.setAuditStatus(CommonConstants.FIVE_INT);
						contractInfo.setInUse(CommonConstants.ONE_STRING);
						tEmployeeContractInfoService.updateById(contractInfo);
					} else if (fddEvent.equals("sign-task-sign-failed")
							|| fddEvent.equals("sign-task-sign-rejected")
							|| fddEvent.equals("sign-task-ignore")
							|| fddEvent.equals("sign-task-fill-rejected")) {
						// 3：签署任务参与方签署失败事件
						pre.setProcessStatus(CommonConstants.dingleDigitStrArray[7]);
						pre.setRequestId("");
						tEmployeeContractPreService.updateById(pre);

						//如果存在合同申请审核数据，将状态更新成6签署失败
						contractInfo.setAuditStatus(CommonConstants.SIX_INT);
						contractInfo.setInUse(CommonConstants.ONE_STRING);
						tEmployeeContractInfoService.updateById(contractInfo);

						UUID uuid = UUID.randomUUID();
						//生成快照数据
						TContractAutoLog contractAutoLog = new TContractAutoLog();
						contractAutoLog.setContractId(uuid.toString());
						contractAutoLog.setEmpName(pre.getEmployeeName());
						contractAutoLog.setEmpIdcard(pre.getEmpIdcard());
						contractAutoLog.setPhone(pre.getEmpPhone());
						contractAutoLog.setMainId(pre.getId());
						contractAutoLog.setErrorInfo(null == terminationNote ? "法大大签署失败" : terminationNote);
						contractAutoLogService.save(contractAutoLog);
						//签署失败发送企微消息
						sendFddFalureInfoToWx(pre, contractAutoLog.getId());

						// 加日志
						this.saveAuditLogFail(pre, "签署失败", terminationNote);
						pushLog.setReturnData("签署任务参与方签署失败事件：fddEvent：" + fddEvent + FASC_BIZ_CONTENT_STR + fddBizContent);
					}
				}
			} else {
				// 历史的日志
				TEmployeeContractPreHistory preHistory = tEmployeeContractPreHistoryService.getOne(Wrappers.<TEmployeeContractPreHistory>query().lambda()
						.eq(TEmployeeContractPreHistory::getRequestId, signTaskId).last(CommonConstants.LAST_ONE_SQL));
				if (preHistory != null) {
					TEmployeeContractInfo contractInfo = null;
					if (Common.isNotNull(preHistory.getContractId())) {
						//如果存在合同申请审核数据，将状态更新成待提交
						contractInfo = tEmployeeContractInfoService.getById(preHistory.getContractId());
					}
					if (contractInfo != null) {
						if (fddEvent.equals("sign-task-canceled") || fddEvent.equals("sign-task-abolish")) {
							// 2：签署任务撤销事件 || 4：签署任务作废事件
							if (fddEvent.equals("sign-task-canceled")) {
								// 4：签署任务作废事件
								pushLog.setReturnData("签署任务撤销事件：fddEvent：" + fddEvent + FASC_BIZ_CONTENT_STR + fddBizContent);
							} else {
								// 4：签署任务作废事件
								pushLog.setReturnData("签署任务作废事件：fddEvent：" + fddEvent + FASC_BIZ_CONTENT_STR + fddBizContent);
							}
							//电子待归档、线下签待归档、已完结的不能撤销签署
							if (Common.isNotNull(preHistory) && !CommonConstants.NINE_STRING.equals(preHistory.getProcessStatus()) &&
									!CommonConstants.FOUR_STRING.equals(preHistory.getProcessStatus()) &&
									!CommonConstants.EIGHT_STRING.equals(preHistory.getProcessStatus())) {
								//如果不是待确认和待发起，需要记录操作记录
								if (!CommonConstants.ZERO_STRING.equals(preHistory.getProcessStatus()) &&
										!CommonConstants.ONE_STRING.equals(preHistory.getProcessStatus()) &&
										Common.isNotNull(preHistory.getContractId())) {
									// 加日志
									this.saveAuditLogFail(preHistory, "撤销签署成功", terminationNote);
								}
								preHistory.setProcessStatus(CommonConstants.TEN_STRING);
								preHistory.setSignFlag(CommonConstants.ZERO_STRING);
								preHistory.setRevokeReason(terminationNote);
								tEmployeeContractPreHistoryService.updateById(preHistory);
							}
							//如果存在合同申请审核数据，将状态更新成5撤销签署
							contractInfo.setAuditStatus(CommonConstants.FIVE_INT);
							contractInfo.setInUse(CommonConstants.ONE_STRING);
							tEmployeeContractInfoService.updateById(contractInfo);
						} else if (fddEvent.equals("sign-task-sign-failed")
								|| fddEvent.equals("sign-task-sign-rejected")
								|| fddEvent.equals("sign-task-ignore")
								|| fddEvent.equals("sign-task-fill-rejected")) {
							// 3：签署任务参与方签署失败事件
							preHistory.setProcessStatus(CommonConstants.dingleDigitStrArray[7]);
							preHistory.setRequestId("");
							tEmployeeContractPreHistoryService.updateById(preHistory);

							//如果存在合同申请审核数据，将状态更新成6签署失败
							contractInfo.setAuditStatus(CommonConstants.SIX_INT);
							contractInfo.setInUse(CommonConstants.ONE_STRING);
							tEmployeeContractInfoService.updateById(contractInfo);
							// 加日志
							this.saveAuditLogFail(preHistory, "签署失败", terminationNote);
							pushLog.setReturnData("签署任务参与方签署失败事件：fddEvent：" + fddEvent + FASC_BIZ_CONTENT_STR + fddBizContent);
						}
					}
				}
			}
		}
		tFascPushLogService.updateById(pushLog);
		log.info("法大大-电子签完成与归档结束");
	}

	private YifuUser getNewYifuUser() {
		Set<String> dbAuthsSet = new HashSet<>();
		Collection<? extends GrantedAuthority> authorities = AuthorityUtils
				.createAuthorityList(dbAuthsSet.toArray(new String[0]));
		return new YifuUser("2", 1L, "", "法大大电子签",
				"法大大电子签", "0", SecurityConstants.BCRYPT + "123456",
				"12345678911", true, true, true,
				true,
				"1", authorities, "1",
				null, null,
				null, null);
	}

	// 加合同里的流程进展明细的日志——成功
	public void saveAuditLogSuccess(TEmployeeContractPre tEmployeeContractPre, String rootName) {
		// 加流程进展明细
		if (tEmployeeContractPre != null && Common.isNotNull(tEmployeeContractPre.getContractId())) {
			this.saveAuditLogInfo(tEmployeeContractPre.getContractId(), rootName, null);
		}
	}

	// 加合同里的流程进展明细的日志——失败
	public void saveAuditLogFail(TEmployeeContractPre tEmployeeContractPre, String rootName, String remark) {
		// 加流程进展明细
		if (tEmployeeContractPre != null && Common.isNotNull(tEmployeeContractPre.getContractId())) {
			this.saveAuditLogInfo(tEmployeeContractPre.getContractId(), rootName, remark);
		}
	}

	// 加合同里的流程进展明细的日志
	public void saveAuditLogInfo(String contractId, String rootName, String remark) {
		// 加流程进展明细
		if (Common.isNotNull(contractId)) {
			TEmployeeContractAudit audit = new TEmployeeContractAudit();
			audit.setRootName(rootName);
			audit.setLinkId(contractId);
			audit.setLinkType(CommonConstants.ONE_INT);
			if (Common.isNotNull(remark)) {
				audit.setRemark(remark);
			}
			audit.setCreateBy("1");
			audit.setCreateName("法大大电子签");
			tEmployeeContractAuditService.save(audit);
		}
	}

	/**
	 * 发送法大大失败提醒通知到企微
	 *
	 * @param pre 合同待购买
	 */
	private void sendFddFalureInfoToWx(TEmployeeContractPre pre, String id) {
		//获取前端客服
		SysUser user;
		if (Common.isEmpty(pre.getCustomerUserLoginname())) {
			return;
		}
		R<SysUser> res = upmsDaprUtils.getSimpleUserByLoginName(pre.getCustomerUserLoginname());
		if (Common.isNotNull(res) && Common.isNotNull(res.getData())) {
			user = res.getData();
		} else {
			return;
		}
		StringBuilder sendUser = null;
		if (Common.isNotKong(user.getWxMessage())) {
			sendUser = new StringBuilder(user.getWxMessage());
		}
		if (sendUser != null) {
			RestTemplate restTemplate = new RestTemplate();
			Map<String, Object> requestMap = new HashMap<>();
			Map<String, Object> textcard = new HashMap<>();
			String authUrl = String.format(SecurityConstants.WX_GET_MESSAGE_AUTH_URL, wxConfig.getCorpid()
					, wxConfig.getDomainName() + "/auth/oauth/wxLogin", "72" + id);
			StringBuilder description = new StringBuilder();
			String title = "作业自动化——电子合同签署失败提醒";
			description.append(pre.getEmployeeName() + "-" + pre.getEmpIdcard() + "-" + pre.getEmpPhone() +
					"，电子合同签署失败").append("<br>");
			description.append("请及时处理，以免产生用工风险！").append("<br>");
			textcard.put("title", title);
			textcard.put("url", authUrl);
			textcard.put("description", description.toString());
			requestMap.put("touser", sendUser);
			requestMap.put("agentid", wxConfig.getAgentid());
			requestMap.put("msgtype", "textcard");
			requestMap.put("textcard", textcard);
			// 必须加上header说明
			if (!wxConfig.sendTextCard(restTemplate, requestMap)) {
				wxConfig.sendTextCard(restTemplate, requestMap);
			}
		}
	}

}
