/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.yifu.archives.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdcardUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fadada.api.bean.req.account.NoticeReq;
import com.fadada.api.bean.req.document.GetBySignFileIdReq;
import com.fadada.api.bean.req.revise.CancelReviseTaskReq;
import com.fadada.api.bean.req.revise.CreateReviseTaskReq;
import com.fadada.api.bean.req.revise.GetFillFileUrlReq;
import com.fadada.api.bean.req.revise.ReviseTaskDetailReq;
import com.fadada.api.bean.req.sign.CancelSignTaskReq;
import com.fadada.api.bean.req.sign.GetSignPreviewUrlReq;
import com.fadada.api.bean.req.sign.GetSignUrlReq;
import com.fadada.api.bean.req.sign.TaskSenderReq;
import com.fadada.api.bean.req.sign.draft.CreateTaskByDraftIdReq;
import com.fadada.api.bean.rsp.BaseRsp;
import com.fadada.api.bean.rsp.document.DownLoadFileRsp;
import com.fadada.api.bean.rsp.revise.CreateReviseTaskRsp;
import com.fadada.api.bean.rsp.revise.GetFillFileUrlRsp;
import com.fadada.api.bean.rsp.revise.ReviseTaskDetailRsp;
import com.fadada.api.bean.rsp.sign.CreateTaskByDraftIdRsp;
import com.fadada.api.bean.rsp.sign.GetSignPreviewUrlRsp;
import com.fadada.api.bean.rsp.sign.GetSignUrlRsp;
import com.fadada.api.bean.rsp.sign.SignUrlRsp;
import com.fadada.api.client.DocumentClient;
import com.fadada.api.client.ReviseTaskClient;
import com.fadada.api.client.SignTaskClient;
import com.fadada.api.exception.ApiException;
import com.google.common.collect.Maps;
import com.yifu.cloud.plus.v1.yifu.archives.entity.*;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.FddContractAttachInfoMapper;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.FddContractInfoMapper;
import com.yifu.cloud.plus.v1.yifu.archives.service.*;
import com.yifu.cloud.plus.v1.yifu.archives.utils.FddUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.CheckedException;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.LocalDateTimeUtils;
import com.yifu.cloud.plus.v1.yifu.common.core.util.OSSUtil;
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.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 法大大合同与员工合同信息
 * @author fxj
 * @date 2022-06-29 16:21:51
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FddContractInfoServiceImpl extends ServiceImpl<FddContractInfoMapper, FddContractInfo> implements FddContractInfoService {

	public static final String FILL_FILE_ID_NULL = "定稿任务id为空";

	public static final String NOT_FOUND_FDD_USER = "未获取到当前登录用户对应的组织下实名法大大用户";

	@Autowired
	private FddUtil fddUtil;
	@Autowired
	private FddReqLogService reqLogService;
	@Autowired
	private FddContractTemplateService fddContractTemplateService;
	@Autowired
	private FddPersonAccountService fddPersonAccountService;
	@Autowired
	private FddContractTemplateFileService fddContractTemplateFileService;
	@Autowired
	private FddCompanyInfoService fddCompanyInfoService;
	@Autowired
	private FddSealPersonAuthService fddSealPersonAuthService;
	@Autowired
	private FddContractAttachInfoMapper fddContractAttachInfoMapper;
	@Autowired
	private TEmployeeContractInfoService employeeContractInfoService;
	@Autowired
	private FddTemplateFieldInfoService fieldInfoService;
	// 阿里云文件上传服务
	@Autowired
	private OSSUtil ossUtil;
	@Autowired
	private TSettleDomainService tSettleDomainService;

	@Override
	public R<String> saveEmpContract(FddContractAttachInfo fddContractAttachInfo,YifuUser user) throws ApiException {
		if (!user.getId().equals(fddContractAttachInfo.getCreateBy())) {
			return R.failed("当前用户不是电子合同导入用户,不能操作");
		}
		//法大大合同模板
		TSettleDomain settleDomain = tSettleDomainService.getOne(Wrappers.<TSettleDomain>query().lambda().eq(TSettleDomain::getDepartNo, fddContractAttachInfo.getDepartNo()));
		if (settleDomain == null) {
			return R.failed("未获取到对应的结算主体");
		}
		List<FddContractTemplate> fddContractTemplateList = fddContractTemplateService.list(Wrappers.<FddContractTemplate>query().lambda()
				.eq(FddContractTemplate::getModifyUploadStatus, CommonConstants.dingleDigitStrArray[1])
				.eq(FddContractTemplate::getFddTemplateId,fddContractAttachInfo.getFddTemplateId()));
		//如果模板存在则生成法大大电子合同数据
		if (fddContractTemplateList.size() == CommonConstants.ZERO_INT) {
			return R.failed("未获取到有效的合同模板");
		}
		if (fddContractTemplateList.size() != CommonConstants.ONE_INT) {
			return R.failed("法大大合同有效合同模板存在多条");
		}
		//校验登录用户和法大大实名用户是否名称和手机号一致
		FddPersonAccount fddCompanyPersonAccount = fddPersonAccountService.getOne(Wrappers.<FddPersonAccount>query().lambda().eq(FddPersonAccount::getMoblie, user.getPhone())
				.eq(FddPersonAccount::getRealStatus, CommonConstants.ONE_STRING).eq(FddPersonAccount::getSystemFlag, CommonConstants.ZERO_STRING).isNotNull(FddPersonAccount::getCompanyInfoId));
		if (fddCompanyPersonAccount == null) {
			return R.failed(NOT_FOUND_FDD_USER);
		}
		//获取员工法大大用户id
		FddPersonAccount fddEmpAccount = fddPersonAccountService.getOne(Wrappers.<FddPersonAccount>query().lambda().eq(FddPersonAccount::getMoblie, fddContractAttachInfo.getEmpPhone())
				.eq(FddPersonAccount::getRealStatus, CommonConstants.ONE_STRING).eq(FddPersonAccount::getSystemFlag, CommonConstants.ONE_STRING));
		if (fddEmpAccount == null) {
			return R.failed(NOT_FOUND_FDD_USER);
		}
		if (!StringUtils.equals(CommonConstants.ONE_STRING, fddEmpAccount.getRealStatus())) {
			return R.failed("当前用户未实名通过");
		}
		//获取法大大组织
		List<String> companyInfoIdList = Arrays.asList(fddCompanyPersonAccount.getCompanyInfoId().split(","));
		List<FddCompanyInfo> fddCompanyInfo = fddCompanyInfoService.list(Wrappers.<FddCompanyInfo>query().lambda().in(FddCompanyInfo::getId, companyInfoIdList));
		if (fddCompanyInfo == null) {
			return R.failed("未获取到对应法大大组织");
		}
		FddContractTemplate fddContractTemplate = fddContractTemplateList.get(CommonConstants.ZERO_INT);
		//获取法大大模板下附件
		FddContractTemplateFile fddContractTemplateFile = fddContractTemplateFileService.getOne(Wrappers.<FddContractTemplateFile>query().lambda().eq(FddContractTemplateFile::getFddTemplateId, fddContractTemplate.getFddTemplateId()));
		ReviseTaskClient reviseTaskClient = new ReviseTaskClient(fddUtil.getFadadaApiClient());
		CreateReviseTaskReq req = new CreateReviseTaskReq();
		req.setTemplateId(fddContractTemplate.getFddTemplateId());
		req.setTaskSubject("员工合同");
		req.setFinalizeWay(1);
		req.setSort(1);
		//定义persion角色开始
		CreateReviseTaskReq.FillRoleInfo persionFillRoleInfo = new CreateReviseTaskReq.FillRoleInfo();
		persionFillRoleInfo.setRoleName(FddUtil.PERSON);
		NoticeReq perSionNoticeReq = new NoticeReq();
		perSionNoticeReq.setNotifyWay(1);
		perSionNoticeReq.setNotifyAddress(fddContractAttachInfo.getEmpPhone());
		persionFillRoleInfo.setNotice(perSionNoticeReq);
		persionFillRoleInfo.setUnionId(fddEmpAccount.getUnionid());
		//文件参数预先填充
		List<CreateReviseTaskReq.FillTemplateFileInfo> fileInfoList = new ArrayList<>();
		CreateReviseTaskReq.FillTemplateFileInfo fileInfo = new CreateReviseTaskReq.FillTemplateFileInfo();
		fileInfo.setFileId(fddContractTemplateFile.getFddFileId());
		//员工填充数据
		List<FddTemplateFieldInfo> personFields = fieldInfoService.getFddFields(fddContractTemplate.getFddTemplateId(),CommonConstants.ZERO_STRING);
		if (Common.isNotNull(personFields)){
			initPersonFields(fddContractAttachInfo,personFields);
			fileInfo.setFormFields(JSON.toJSONString(personFields.stream().collect(HashMap::new, (m, v)->m.put(v.getFiledName(), v.getFieldValue()),HashMap::putAll)));
		}
		fileInfoList.add(fileInfo);
		persionFillRoleInfo.setFillTemplateFiles(fileInfoList);
		//定义persion角色结束

		//定义company角色开始
		CreateReviseTaskReq.FillRoleInfo companyFillRoleInfo = new CreateReviseTaskReq.FillRoleInfo();
		companyFillRoleInfo.setRoleName(FddUtil.COMPANY);
		NoticeReq companyionNoticeReq = new NoticeReq();
		companyionNoticeReq.setNotifyWay(1);
		companyionNoticeReq.setNotifyAddress(fddCompanyPersonAccount.getMoblie());
		companyFillRoleInfo.setNotice(companyionNoticeReq);
		companyFillRoleInfo.setUnionId(fddCompanyPersonAccount.getUnionid());
		//文件参数预先填充
		List<CreateReviseTaskReq.FillTemplateFileInfo> companyFileInfoList = new ArrayList<>();
		CreateReviseTaskReq.FillTemplateFileInfo companyFileInfo = new CreateReviseTaskReq.FillTemplateFileInfo();
		companyFileInfo.setFileId(fddContractTemplateFile.getFddFileId());
		//公司填充数据
		List<FddTemplateFieldInfo> compamyFields = fieldInfoService.getFddFields(fddContractTemplate.getFddTemplateId(),CommonConstants.ONE_STRING);
		if (Common.isNotNull(compamyFields)){
			Map<String,String> companyFieldMap = compamyFields.stream().collect(Collectors.toMap(k->k.getFiledName(), k->k.getFiledName()));
			R<String> employeeParamR = generalEmployeeParamNew(fddContractAttachInfo,companyFieldMap);
			if (Common.isEmpty(employeeParamR) || employeeParamR.getCode() == CommonConstants.FAIL.intValue()){
				return employeeParamR;
			}
			companyFileInfo.setFormFields(employeeParamR.getData());
		}
		companyFileInfoList.add(companyFileInfo);
		companyFillRoleInfo.setFillTemplateFiles(companyFileInfoList);
		//定义company角色结束

		//文件id
		List<CreateReviseTaskReq.TemplateFileInfo> templateFileInfos = new ArrayList<>();
		CreateReviseTaskReq.TemplateFileInfo templateFileInfo = new CreateReviseTaskReq.TemplateFileInfo();
		templateFileInfo.setFileId(fddContractTemplateFile.getFddFileId());
		templateFileInfo.setFileName("员工合同");
		templateFileInfos.add(templateFileInfo);
		req.setTemplateFiles(templateFileInfos);
		//发送请求
		List<CreateReviseTaskReq.FillRoleInfo> fillRoles = new ArrayList<>();
		fillRoles.add(persionFillRoleInfo);
		fillRoles.add(companyFillRoleInfo);
		req.setFillRoles(fillRoles);
		//设置token
		req.setToken(fddUtil.getToken());

		BaseRsp<CreateReviseTaskRsp> rsp = reviseTaskClient.createReviseTask(req);
		//保存日志
		reqLogService.saveLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName(), req, rsp);
		//校验参数
		if (StringUtils.equals(rsp.getCode(), FddUtil.SUCCESS)) {
			CreateReviseTaskRsp rspData = rsp.getData();
			//法大大员工合同记录生成
			FddContractInfo fddContractInfoNew = new FddContractInfo();
			fddContractInfoNew.setContractId(fddContractAttachInfo.getContractId());
			fddContractInfoNew.setFddPersonAccountSendId(fddCompanyPersonAccount.getId());
			fddContractInfoNew.setFddPersonAccountReceiveId(fddEmpAccount.getId());
			fddContractInfoNew.setSendUnionid(fddCompanyPersonAccount.getUnionid());
			fddContractInfoNew.setReceiveUnionid(fddEmpAccount.getUnionid());
			fddContractInfoNew.setFddTemplateId(fddContractTemplate.getId());
			this.save(fddContractInfoNew);
			fddContractInfoNew.setTaskId(rspData.getTaskId());
			fddContractInfoNew.setFileId(rspData.getTaskFiles().get(CommonConstants.ZERO_INT).getFileId());
			this.updateById(fddContractInfoNew);
			return new R<>("创建模板定稿任务成功");
		} else {
			log.error("请求数据:{}",JSON.toJSONString(req));
			log.error("返回数据:{}",JSON.toJSONString(rsp));
			return R.failed(rsp.getMsg());
		}
	}

	/**
	 * @param fddContractInfo
	 * @Author: huyc
	 * @Date: 2022/6/30
	 * @Description: 作废重签
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 * 1.去法大大撤销合同：已签署的撤销签署流程、再撤销定稿流程；未签署的撤销定稿流程
	 * 2.先复制一份合同、然后删除之前合同
	 * 3.新增一条合同
	 **/
	@Override
	public R<String> invalidAndsend(FddContractInfo fddContractInfo) throws ApiException {
		FddContractInfo entity = this.getById(fddContractInfo.getId());
		if (StringUtils.equals(entity.getDeleteFlag(), CommonConstants.ONE_STRING)) {
			return R.failed("电子合同已作废");
		}
		if(StringUtils.equals(CommonConstants.TWO_STRING,entity.getSignStatus())){
			return R.failed("合同签署任务已完成,不能作废重签");
		}
		YifuUser user = SecurityUtils.getUser();
		FddContractAttachInfo fddContractAttachInfo = fddContractAttachInfoMapper.selectOne(Wrappers.<FddContractAttachInfo>query().lambda()
				.eq(FddContractAttachInfo::getContractId,entity.getContractId()));
		if (!user.getId().equals(fddContractAttachInfo.getCreateBy())) {
			return R.failed("当前用户不是电子合同导入用户,不能操作");
		}
		if (StringUtils.isNotEmpty(entity.getSignTaskId())) {
			//发送撤销签署
			CancelSignTaskReq req = new CancelSignTaskReq();
			req.setToken(fddUtil.getToken());
			req.setTaskId(entity.getSignTaskId());
			req.setRemark("签署撤销");
			SignTaskClient client = new SignTaskClient(fddUtil.getFadadaApiClient());
			BaseRsp<GetSignUrlRsp> rsp = client.cancelSignTask(req);
			reqLogService.saveLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName(), req, rsp);
			//校验参数
			if (StringUtils.equals(rsp.getCode(), FddUtil.SUCCESS)) {
				//更新签署任务为空
				baseMapper.cancleSignTask(entity.getId());
				return cancleReviSeTask(entity);
			} else {
				return R.failed(rsp.getMsg());
			}
		} else if (StringUtils.isNotEmpty(entity.getTaskId())) {
			return cancleReviSeTask(entity);
		} else {
			return R.failed("当前电子合同未发送");
		}
	}

	/**
	 * @param fddContractInfo
	 * @Author: huyc
	 * @Date: 2022/6/30
	 * @Description: 获取在线定稿地址
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> getFillFileUrl(FddContractInfo fddContractInfo, String roleName) throws ApiException {
		//获取法大大电子合同
		FddContractInfo entity = this.getById(fddContractInfo.getId());
		if (entity == null) {
			return R.failed("未查询到相关记录");
		}
		if (StringUtils.isEmpty(entity.getTaskId())) {
			return R.failed(FILL_FILE_ID_NULL);
		}
		//发送请求
		GetFillFileUrlReq req = new GetFillFileUrlReq();
		req.setToken(fddUtil.getToken());
		req.setTaskId(entity.getTaskId());
		req.setRoleName(roleName);
		ReviseTaskClient client = new ReviseTaskClient(fddUtil.getFadadaApiClient());
		BaseRsp<GetFillFileUrlRsp> rsp = client.getFillFileUrl(req);
		reqLogService.saveLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName(), req, rsp);
		//校验参数
		if (StringUtils.equals(rsp.getCode(), FddUtil.SUCCESS)) {
			return new R<>(rsp.getData().getFillUrl());
		} else {
			return R.failed(rsp.getMsg());
		}
	}

	/**
	 * @param
	 * @Author: huyc
	 * @Date: 2022/6/30
	 * @Description: 引用模板创建签署任务
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> createTaskByDraftId(FddContractInfo entity) throws ApiException {
		if (StringUtils.isEmpty(entity.getTaskId())) {
			return R.failed(FILL_FILE_ID_NULL);
		}
		if (StringUtils.isEmpty(entity.getDraftId())) {
			return R.failed("草稿id为空");
		}
		FddPersonAccount fddCompanyPersonAccount = fddPersonAccountService.getOne(Wrappers.<FddPersonAccount>query().lambda().eq(FddPersonAccount::getId, entity.getFddPersonAccountSendId()));
		if (fddCompanyPersonAccount == null) {
			return R.failed(NOT_FOUND_FDD_USER);
		}
		//获取用户章
		List<FddSealPersonAuth> fddSealPersonAuth = fddSealPersonAuthService.list(Wrappers.<FddSealPersonAuth>query().lambda().eq(FddSealPersonAuth::getFddPersonAccountId, fddCompanyPersonAccount.getId())
				.eq(FddSealPersonAuth::getStatus, CommonConstants.ONE_STRING));
		if (fddSealPersonAuth == null) {
			return R.failed("当前用户未授权系统章");
		}
		//获取员工法大大用户id
		FddPersonAccount fddEmpAccount = fddPersonAccountService.getOne(Wrappers.<FddPersonAccount>query().lambda().eq(FddPersonAccount::getId, entity.getFddPersonAccountReceiveId()));
		if (fddEmpAccount == null) {
			return R.failed(NOT_FOUND_FDD_USER);
		}

		FddContractTemplate fddContractTemplate = fddContractTemplateService.getOne(Wrappers.<FddContractTemplate>query().lambda().eq(FddContractTemplate::getId, entity.getFddTemplateId()));
		//获取法大大组织
		FddCompanyInfo fddCompanyInfo = fddCompanyInfoService.getOne(Wrappers.<FddCompanyInfo>query().lambda().eq(FddCompanyInfo::getCompanyName, fddContractTemplate.getSignerName()));
		if (fddCompanyInfo == null) {
			return R.failed("未获取到对应法大大组织");
		}
		CreateTaskByDraftIdReq req = new CreateTaskByDraftIdReq();
		req.setDraftId(entity.getDraftId());
		req.setTaskSubject("合同签署");
		req.setStatus("sent");
		req.setSort(1);
		//发起方对象
		TaskSenderReq taskSenderReq = new TaskSenderReq();
		taskSenderReq.setUnionId(fddCompanyInfo.getCompanyUnionId());
		req.setSender(taskSenderReq);

		//templateRoleName.模板角色名称
		List<CreateTaskByDraftIdReq.CreateTaskSignerInfo> signers = new ArrayList<>();
		//组装person signers---------------start
		CreateTaskByDraftIdReq.CreateTaskSignerInfo signerInfo = new CreateTaskByDraftIdReq.CreateTaskSignerInfo();
		signerInfo.setSignOrder(1);
		signers.add(signerInfo);
		signerInfo.setTemplateRoleName(FddUtil.PERSON);
		//externalSigner
		//signer
		CreateTaskByDraftIdReq.SignatoryInfo signatory = new CreateTaskByDraftIdReq.SignatoryInfo();
		signatory.setSignerId(fddEmpAccount.getUnionid());

		CreateTaskByDraftIdReq.SignerInfo signer = new CreateTaskByDraftIdReq.SignerInfo();
		signer.setSignatory(signatory);
		com.fadada.api.bean.req.sign.NoticeReq perSionNotice = new com.fadada.api.bean.req.sign.NoticeReq();
		perSionNotice.setNotifyWay(1);
		perSionNotice.setNotifyAddress(fddEmpAccount.getMoblie());
		signer.setNotice(perSionNotice);

		signerInfo.setSigner(signer);
		//组装person signers---------------end

		//组装company signers---------------start
		CreateTaskByDraftIdReq.CreateTaskSignerInfo companySignerInfo = new CreateTaskByDraftIdReq.CreateTaskSignerInfo();
		companySignerInfo.setSignOrder(2);
		signers.add(companySignerInfo);
		companySignerInfo.setTemplateRoleName(FddUtil.COMPANY);
		//externalSigner
		//signer
		CreateTaskByDraftIdReq.SignerInfo companySigner = new CreateTaskByDraftIdReq.SignerInfo();
		CreateTaskByDraftIdReq.SignatoryInfo companySignatory = new CreateTaskByDraftIdReq.SignatoryInfo();
		companySignatory.setSignerId(fddCompanyPersonAccount.getUnionid());
		companySigner.setSignatory(companySignatory);
		CreateTaskByDraftIdReq.CorpInfo corp = new CreateTaskByDraftIdReq.CorpInfo();
		corp.setCorpId(fddCompanyInfo.getCompanyUnionId());
		companySigner.setCorp(corp);
		com.fadada.api.bean.req.sign.NoticeReq notice = new com.fadada.api.bean.req.sign.NoticeReq();
		notice.setNotifyWay(1);
		notice.setNotifyAddress(fddCompanyPersonAccount.getMoblie());
		companySigner.setNotice(notice);
		companySignerInfo.setSigner(companySigner);
		//组装company signers---------------end
		req.setSigners(signers);
		//发送请求
		//设置token
		req.setToken(fddUtil.getToken());
		SignTaskClient signTaskClient = new SignTaskClient(fddUtil.getFadadaApiClient());
		BaseRsp<CreateTaskByDraftIdRsp> rsp = signTaskClient.createTaskByDraftId(req);
		reqLogService.saveLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName(), req, rsp);
		//校验参数
		if (StringUtils.equals(rsp.getCode(), FddUtil.SUCCESS)) {
			entity.setSignTaskId(rsp.getData().getTaskId());
			this.updateById(entity);
			return new R<>("成功");
		} else {
			return R.failed(rsp.getMsg());
		}
	}

	/**
	 * @param fddContractInfo
	 * @Author: huyc
	 * @Date: 2022/6/30
	 * @Description: 获取签署链接
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<Map<String, List<SignUrlRsp>>> getSignUrl(FddContractInfo fddContractInfo) throws ApiException {
		//获取法大大电子合同
		FddContractInfo entity = this.getById(fddContractInfo.getId());
		if (entity == null) {
			return R.failed("未查询到相关记录");
		}
		if (StringUtils.isEmpty(entity.getTaskId())) {
			return R.failed(FILL_FILE_ID_NULL);
		}
		//发送请求
		GetSignUrlReq req = new GetSignUrlReq();
		req.setToken(fddUtil.getToken());
		req.setTaskId(entity.getSignTaskId());
		req.setUnionId(entity.getSendUnionid());
		SignTaskClient client = new SignTaskClient(fddUtil.getFadadaApiClient());
		BaseRsp<GetSignUrlRsp> rsp = client.getSignUrl(req);
		reqLogService.saveLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName(), req, rsp);
		HashMap<String, List<SignUrlRsp>> hashMap = Maps.newHashMap();
		//校验参数
		if (StringUtils.equals(rsp.getCode(), FddUtil.SUCCESS)) {
			hashMap.put(FddUtil.COMPANY, rsp.getData().getSignUrls());
		}
		req.setUnionId(entity.getSendUnionid());
		rsp = client.getSignUrl(req);
		reqLogService.saveLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName(), req, rsp);
		//校验参数
		if (StringUtils.equals(rsp.getCode(), FddUtil.SUCCESS)) {
			hashMap.put(FddUtil.PERSON, rsp.getData().getSignUrls());
		}
		return new R<>(hashMap);
	}

	/**
	 * @param fddContractInfo
	 * @Author: huyc
	 * @Date: 2022/6/30
	 * @Description: 获取签署文件预览地址
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> getSignPreviewUrl(FddContractInfo fddContractInfo) throws ApiException {
		FddContractInfo entity = this.getById(fddContractInfo.getId());
		if (entity == null || entity.getSignTaskId() == null) {
			throw new  CheckedException("未获取到对应签署任务");
		}
		//发送请求
		GetSignPreviewUrlReq req = new GetSignPreviewUrlReq();
		req.setToken(fddUtil.getToken());
		req.setTaskId(entity.getSignTaskId());
		SignTaskClient client = new SignTaskClient(fddUtil.getFadadaApiClient());
		BaseRsp<GetSignPreviewUrlRsp> rsp = client.getSignPreviewUrl(req);
		reqLogService.saveLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName(), req, rsp);
		//校验参数
		if (StringUtils.equals(rsp.getCode(), FddUtil.SUCCESS)) {
			return new R<>(rsp.getData().getSignPreviewUrl());
		}
		return R.failed(rsp.getMsg());
	}

	/**
	 * @param fddContractInfo
	 * @Author: huyc
	 * @Date: 2022/6/30
	 * @Description: 签署文件下载
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 **/
	@Override
	public void getBySignFileId(FddContractInfo fddContractInfo, HttpServletResponse response) throws ApiException, IOException {
		FddContractInfo entity = this.getById(fddContractInfo.getId());
		if (entity == null || entity.getSignTaskId() == null) {
			throw new CheckedException("未获取到对应签署任务");
		}
		//发送请求
		GetBySignFileIdReq req = new GetBySignFileIdReq();
		req.setToken(fddUtil.getToken());
		req.setTaskId(entity.getSignTaskId());
		DocumentClient client = new DocumentClient(fddUtil.getFadadaApiClient());
		BaseRsp<DownLoadFileRsp> rsp = client.getBySignFileId(req);
		//校验参数
		if (StringUtils.equals(rsp.getCode(), FddUtil.SUCCESS)) {
			DownLoadFileRsp rspData = rsp.getData();
			BufferedOutputStream fos = new BufferedOutputStream(response.getOutputStream());
			response.reset();
			response.setContentType("application/zip;");
			response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode("合同.zip", CommonConstants.UTF8));
			fos.write(rspData.getFileBytes());
		}
	}

	/**
	 * @param fddContractInfo
	 * @param response
	 * @Description: 签署文件转移为合同附件
	 * @Author: huyc
	 * @Date: 2022/6/30
	 * @return: R
	 **/
	@Override
	public R<String> moveFileToEmpConcat(FddContractInfo fddContractInfo, HttpServletResponse response) throws ApiException, IOException {
		FddContractInfo entity = this.getById(fddContractInfo.getId());
		if (entity == null || entity.getSignTaskId() == null) {
			throw new CheckedException("未获取到对应签署任务");
		}
		TEmployeeContractInfo employeeContractInfo = employeeContractInfoService.getById(entity.getContractId());
		if (employeeContractInfo != null) {
			//发送请求
			GetBySignFileIdReq req = new GetBySignFileIdReq();
			req.setToken(fddUtil.getToken());
			req.setTaskId(entity.getSignTaskId());
			DocumentClient client = new DocumentClient(fddUtil.getFadadaApiClient());
			BaseRsp<DownLoadFileRsp> rsp = client.getBySignFileId(req);
			//校验参数
			if (StringUtils.equals(rsp.getCode(), FddUtil.SUCCESS)) {
				DownLoadFileRsp rspData = rsp.getData();
				if (rspData != null) {
					InputStream bis = null;
					try {
						bis = new ByteArrayInputStream(rspData.getFileBytes());
						String name = System.currentTimeMillis() + "法大大电子签附件";
						String key = name + ".zip";
						ossUtil.uploadFileByStream(bis, key, null);
						// 1：保存为
//						TEmpAtta empAtta = BasicServiceUtil.initTEmpAttaForInsert(name, key, (long) rspData.getFileBytes().length);
//						empAttaService.save(empAtta);
//						MEmpContractAtta contractAtta = new MEmpContractAtta();
//						contractAtta.setAttaId(empAtta.getId());
//						contractAtta.setContractId(employeeContractInfo.getId());
//						mempContractAttaService.save(contractAtta);
						FddContractAttachInfo fddContractAttachInfo = fddContractAttachInfoMapper.selectOne(Wrappers.<FddContractAttachInfo>query().lambda()
								.eq(FddContractAttachInfo::getContractId,entity.getContractId()).last(CommonConstants.LAST_ONE_SQL));
						if (fddContractAttachInfo != null) {
							fddContractAttachInfo.setIsMove(CommonConstants.ONE_INT);
							fddContractAttachInfoMapper.updateById(fddContractAttachInfo);
						}
						return R.ok();
					} finally {
						if (bis != null) {
							bis.close();
						}
					}
				}
			}
		}
		return R.failed("转移失败");
	}

	public R<String> generalEmployeeParamNew(FddContractAttachInfo attachInfo,
											 Map<String, String> companyFieldMap) {
		JSONObject paramter = new JSONObject();
		if (Common.isNotNull(companyFieldMap)){
			R<String> res  = getValuesOfKey(paramter,attachInfo,companyFieldMap);
			if (Common.isNotNull(res) && res.getCode() == CommonConstants.FAIL.intValue()){
				return res;
			}
		}
		return new R<>(paramter.toJSONString());
	}

	private R<String> getValuesOfKey(JSONObject paramter,
									 FddContractAttachInfo attachInfo,
									 Map<String, String> companyFieldMap) {
		if (Common.isNotNull(companyFieldMap.get("name"))){
			if (StringUtils.isEmpty(attachInfo.getEmpName())) {
				return R.failed("姓名为空，请去档案补充对应信息！");
			}
			paramter.put("name", attachInfo.getEmpName());
		}
		if (Common.isNotNull(companyFieldMap.get("birth"))){
			Date date = IdcardUtil.getBirthDate(attachInfo.getEmpIdcard());
			if (LocalDateTimeUtils.convertDateToLDT(date) == null) {
				return R.failed("出生年月为空，请去档案补充对应信息！");
			}
			paramter.put("birth", DateUtil.format(LocalDateTimeUtils.convertDateToLDT(date), DatePattern.NORM_DATE_PATTERN));
		}

		//暂时档案所在地为空
		if (Common.isNotNull(companyFieldMap.get("id_card"))){
			if (StringUtils.isEmpty(attachInfo.getEmpIdcard())) {
				return R.failed("身份证号为空，请去档案补充对应信息！");
			}
			paramter.put("id_card", attachInfo.getEmpIdcard());
		}
		if (Common.isNotNull(companyFieldMap.get("sex"))){
			int sex = IdcardUtil.getGenderByIdCard(attachInfo.getEmpIdcard());
			if (sex == 0) {
				paramter.put("sex", "女");
			} else if (sex == 1) {
				paramter.put("sex", "男");
			}
		}
		if (Common.isNotNull(companyFieldMap.get("mobile"))){
			if (StringUtils.isEmpty(attachInfo.getEmpPhone())) {
				return R.failed("手机号为空，请去档案补充对应信息！");
			}
			paramter.put("mobile", attachInfo.getEmpPhone());
		}
		if (Common.isNotNull(companyFieldMap.get("contractType"))){
			//固定期限
			paramter.put("contractType", "一");
			paramter.put("fcontractStartY", DateUtil.format(attachInfo.getContractStart(), "yyyy"));
			paramter.put("fcontractStartM", DateUtil.format(attachInfo.getContractStart(), "MM"));
			paramter.put("fcontractStartD", DateUtil.format(attachInfo.getContractStart(), "dd"));
			paramter.put("fcontractEndY", DateUtil.format(attachInfo.getContractEnd(), "yyyy"));
			paramter.put("fcontractEndM", DateUtil.format(attachInfo.getContractEnd(), "MM"));
			paramter.put("fcontractEndD", DateUtil.format(attachInfo.getContractEnd(), "dd"));
			if (Common.isNotNull(companyFieldMap.get("fPeriodStartY"))){
				//合同起止时间填充,新签需要判断是否有试用期，试用期工资
				if (attachInfo.getPeriodStart() == null) {
					return R.failed("新签试用期开始时间为空");
				}
				paramter.put("fPeriodStartY", DateUtil.format(localDate2Date(attachInfo.getPeriodStart()), "yyyy"));
				paramter.put("fPeriodStartM", DateUtil.format(localDate2Date(attachInfo.getPeriodStart()), "MM"));
				paramter.put("fPeriodStartD", DateUtil.format(localDate2Date(attachInfo.getPeriodStart()), "dd"));
			}
			if (Common.isNotNull(companyFieldMap.get("fPeriodEndY"))){
				if (attachInfo.getPeriodEnd() == null) {
					return R.failed("新签试用期结束时间为空");
				}
				paramter.put("fPeriodEndY", DateUtil.format(localDate2Date(attachInfo.getPeriodEnd()), "yyyy"));
				paramter.put("fPeriodEndM", DateUtil.format(localDate2Date(attachInfo.getPeriodEnd()), "MM"));
				paramter.put("fPeriodEndD", DateUtil.format(localDate2Date(attachInfo.getPeriodEnd()), "dd"));
			}
			if (Common.isNotNull(companyFieldMap.get("periodSalaryPerMonth"))){
				if (attachInfo.getPeriodSalaryPerMonth() == null) {
					return R.failed("新签试用期工资为空");
				}
				paramter.put("pSalaryPerMon", attachInfo.getPeriodSalaryPerMonth());
			}
		}
		if (Common.isNotNull(companyFieldMap.get("post"))){
			//工作地点和岗位填充
			if (StringUtils.isEmpty(attachInfo.getPost())) {
				return R.failed("员工岗位为空，请去档案补充对应信息！");
			}
			paramter.put("post", attachInfo.getPost());
		}
		if (Common.isNotNull(companyFieldMap.get("workSpace"))){
			if (StringUtils.isEmpty(attachInfo.getWorkSpace())) {
				return R.failed("员工工作地点为空");
			}
			paramter.put("workSpace", attachInfo.getWorkSpace());
		}
		if (Common.isNotNull(companyFieldMap.get("workingHours"))){
			paramter.put("workingHours", "");
		}
		if (Common.isNotNull(companyFieldMap.get("salaryType"))){
			//工资标准
			if(StringUtils.isEmpty(attachInfo.getSalaryType())){
				return R.failed("工资标准类型不能为空");
			}
			String salaryTypeKey = "salaryType";
			if (StringUtils.equals(CommonConstants.ONE_STRING, attachInfo.getSalaryType())) {
				paramter.put(salaryTypeKey, CommonConstants.ONE_STRING);
				//计时工资
				if (attachInfo.getSalaryStandardPerHour()==null) {
					return R.failed("计时工资为空");
				}
				if (Common.isNotNull(companyFieldMap.get("salaryStrandPh"))){
					paramter.put("salaryStrandPh", String.valueOf(attachInfo.getSalaryStandardPerHour()));
				}
			} else if (StringUtils.equals(CommonConstants.TWO_STRING, attachInfo.getSalaryType())) {
				paramter.put(salaryTypeKey, CommonConstants.TWO_STRING);
				if (attachInfo.getSalaryStandardPerPiece()==null) {
					return R.failed("计件工资为空");
				}
				if (Common.isNotNull(companyFieldMap.get("salaryStrandPp"))){
					//计月工资
					paramter.put("salaryStrandPp",  String.valueOf(attachInfo.getSalaryStandardPerPiece()));
				}
			} else if (StringUtils.equals(CommonConstants.THREE_STRING, attachInfo.getSalaryType())) {
				paramter.put(salaryTypeKey, CommonConstants.THREE_STRING);
			} else {
				return R.failed("未知的工资标准类型");
			}
		}
		return new R<>(paramter.toJSONString());
	}

	private void initPersonFields(FddContractAttachInfo fddContractAttachInfo, List<FddTemplateFieldInfo> personFields) {
		if (Common.isNotNull(fddContractAttachInfo) && Common.isNotNull(personFields)){
			for (FddTemplateFieldInfo field:personFields){
				if (field.getFiledName().equals("empNameRecord")){
					field.setFieldValue(fddContractAttachInfo.getEmpName());
				}
				if (field.getFiledName().equals("empSexRecord")){
					int sex = IdcardUtil.getGenderByIdCard(fddContractAttachInfo.getEmpIdcard());
					if (sex == 0) {
						field.setFieldValue("女");
					} else if (sex == 1) {
						field.setFieldValue("男");
					}
				}
				if (field.getFiledName().equals("empBirthRecord")){
					Date date = IdcardUtil.getBirthDate(fddContractAttachInfo.getEmpIdcard());
					if (LocalDateTimeUtils.convertDateToLDT(date) != null){
						field.setFieldValue(DateUtil.format(LocalDateTimeUtils.convertDateToLDT(date), DatePattern.NORM_DATE_PATTERN));
					}
				}
				if (field.getFiledName().equals("empIdCardRecord")){
					field.setFieldValue(fddContractAttachInfo.getEmpIdcard());
				}
				if (field.getFiledName().equals("empMobileRecord")){
					field.setFieldValue(fddContractAttachInfo.getEmpPhone());
				}
			}
		}
	}

	@Override
	public R<String> generalEmployeeParam(FddContractAttachInfo attachInfo, boolean signFlag) {
		JSONObject paramter = new JSONObject();
		if (StringUtils.isEmpty(attachInfo.getEmpName())) {
			return R.failed("姓名为空，请去档案补充对应信息！");
		}
		paramter.put("name", attachInfo.getEmpName());
		Date date = IdcardUtil.getBirthDate(attachInfo.getEmpIdcard());
		if (LocalDateTimeUtils.convertDateToLDT(date) == null) {
			return R.failed("出生年月为空，请去档案补充对应信息！");
		}
		paramter.put("birth", DateUtil.format(LocalDateTimeUtils.convertDateToLDT(date), DatePattern.NORM_DATE_PATTERN));
		if (StringUtils.isEmpty(attachInfo.getEmpIdcard())) {
			return R.failed("身份证号为空，请去档案补充对应信息！");
		}
		paramter.put("id_card", attachInfo.getEmpIdcard());
		int sex = IdcardUtil.getGenderByIdCard(attachInfo.getEmpIdcard());
		if (sex == 0) {
			paramter.put("sex", "女");
		} else if (sex == 1) {
			paramter.put("sex", "男");
		}

		if (StringUtils.isEmpty(attachInfo.getEmpPhone())) {
			return R.failed("手机号为空，请去档案补充对应信息！");
		}
		paramter.put("mobile", attachInfo.getEmpPhone());

		//固定期限
		paramter.put("contractType", "一");
		paramter.put("fcontractStartY", DateUtil.format(attachInfo.getContractStart(), "yyyy"));
		paramter.put("fcontractStartM", DateUtil.format(attachInfo.getContractStart(), "MM"));
		paramter.put("fcontractStartD", DateUtil.format(attachInfo.getContractStart(), "dd"));
		paramter.put("fcontractEndY", DateUtil.format(attachInfo.getContractEnd(), "yyyy"));
		paramter.put("fcontractEndM", DateUtil.format(attachInfo.getContractEnd(), "MM"));
		paramter.put("fcontractEndD", DateUtil.format(attachInfo.getContractEnd(), "dd"));
		//合同起止时间填充,新签需要判断是否有试用期，试用期工资
		if (!signFlag) {
			if (attachInfo.getPeriodStart() == null) {
				return R.failed("新签试用期开始时间为空");
			}
			paramter.put("fPeriodStartY", DateUtil.format(localDate2Date(attachInfo.getPeriodStart()), "yyyy"));
			paramter.put("fPeriodStartM", DateUtil.format(localDate2Date(attachInfo.getPeriodStart()), "MM"));
			paramter.put("fPeriodStartD", DateUtil.format(localDate2Date(attachInfo.getPeriodStart()), "dd"));
			if (attachInfo.getPeriodEnd() == null) {
				return R.failed("新签试用期结束时间为空");
			}
			paramter.put("fPeriodEndY", DateUtil.format(localDate2Date(attachInfo.getPeriodEnd()), "yyyy"));
			paramter.put("fPeriodEndM", DateUtil.format(localDate2Date(attachInfo.getPeriodEnd()), "MM"));
			paramter.put("fPeriodEndD", DateUtil.format(localDate2Date(attachInfo.getPeriodEnd()), "dd"));
			if (attachInfo.getPeriodSalaryPerMonth() == null) {
				return R.failed("新签试用期工资为空");
			}
			paramter.put("periodSalaryPerMonth", attachInfo.getPeriodSalaryPerMonth());
		}
		//工作地点和岗位填充
		if (StringUtils.isEmpty(attachInfo.getPost())) {
			return R.failed("员工岗位为空，请去档案补充对应信息！");
		}
		paramter.put("post", attachInfo.getPost());
		if (StringUtils.isEmpty(attachInfo.getWorkSpace())) {
			return R.failed("员工工作地点为空");
		}
		paramter.put("workSpace", attachInfo.getWorkSpace());
		//工时制
		paramter.put("workingHours", "");
		//工资标准
		if(StringUtils.isEmpty(attachInfo.getSalaryType())){
			return R.failed("工资形式不能为空");
		}
		String salaryTypeKey = "salaryType";
		if (StringUtils.equals(CommonConstants.ONE_STRING, attachInfo.getSalaryType())) {
			paramter.put(salaryTypeKey, CommonConstants.ONE_STRING);
			//计时工资
			if (attachInfo.getSalaryStandardPerHour()==null) {
				return R.failed("计时工资为空");
			}
			paramter.put("salaryStrandPh", String.valueOf(attachInfo.getSalaryStandardPerHour()));
		} else if (StringUtils.equals(CommonConstants.TWO_STRING, attachInfo.getSalaryType())) {
			paramter.put(salaryTypeKey, CommonConstants.TWO_STRING);
			if (attachInfo.getSalaryStandardPerPiece()==null) {
				return R.failed("计件工资为空");
			}
			//计月工资
			paramter.put("salaryStrandPp",  String.valueOf(attachInfo.getSalaryStandardPerPiece()));
		} else if (StringUtils.equals(CommonConstants.THREE_STRING, attachInfo.getSalaryType())) {
			paramter.put(salaryTypeKey, CommonConstants.THREE_STRING);
		} else {
			return R.failed("未知的工资标准类型");
		}
		return new R<>(paramter.toJSONString());
	}

	public static Date localDate2Date(LocalDate localDate) {
		if (null == localDate) {
			return null;
		}
		ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
		return Date.from(zonedDateTime.toInstant());
	}

	/**
	 * @param entity
	 * @Author: huyc
	 * @Date: 2022/6/30
	 * @Description: 撤销定稿任务
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 **/
	private R<String> cancleReviSeTask(FddContractInfo entity) throws ApiException {
		YifuUser user = SecurityUtils.getUser();
		//定稿任务状态：0 待发起 、1定稿中、2已定稿、3已撤销、4已过期
		R<Integer> reviseTaskDetailR = reviseTaskDetail(entity);
		if (reviseTaskDetailR.getCode() != CommonConstants.SUCCESS) {
			return R.failed(reviseTaskDetailR.getMsg());
		}
		FddContractAttachInfo attachInfo = fddContractAttachInfoMapper.selectOne(Wrappers.<FddContractAttachInfo>query().lambda().eq(FddContractAttachInfo::getContractId, entity.getContractId()));
		int status = reviseTaskDetailR.getData();
		CancelReviseTaskReq req = new CancelReviseTaskReq();
		if (status == CommonConstants.ZERO_INT || status == CommonConstants.ONE_INT) {
			//发送请求
			req.setToken(fddUtil.getToken());
			req.setTaskId(entity.getTaskId());
			ReviseTaskClient client = new ReviseTaskClient(fddUtil.getFadadaApiClient());
			BaseRsp<GetFillFileUrlRsp> rsp = client.cancelReviseTask(req);
			reqLogService.saveLog(this.getClass().getName(), Thread.currentThread().getStackTrace()[1].getMethodName(), req, rsp);
		}
		//.先复制一份合同、然后删除之前合同
		entity.setDeleteFlag(CommonConstants.ONE_STRING);
		this.updateById(entity);
		R<String> saveEmpContractR = saveEmpContract(attachInfo,user);
		if (saveEmpContractR.getCode() != CommonConstants.SUCCESS) {
			throw new CheckedException(saveEmpContractR.getMsg());
		}
		return R.ok();
	}

	/**
	 * @param fddContractInfo
	 * @Author: huyc
	 * @Date: 2022/6/30
	 * @Description: 获取定稿任务详情
	 * @return: com.yifu.cloud.v1.common.core.util.R<java.lang.String>
	 **/
	public R<Integer> reviseTaskDetail(FddContractInfo fddContractInfo) throws ApiException {
		//发送撤销签署
		ReviseTaskDetailReq req = new ReviseTaskDetailReq();
		req.setToken(fddUtil.getToken());
		req.setTaskId(fddContractInfo.getTaskId());
		ReviseTaskClient client = new ReviseTaskClient(fddUtil.getFadadaApiClient());
		BaseRsp<ReviseTaskDetailRsp> rsp = client.reviseTaskDetail(req);
		//校验参数
		if (StringUtils.equals(rsp.getCode(), FddUtil.SUCCESS)) {
			log.error("请求数据:{}",JSON.toJSONString(req));
			log.error("返回数据:{}",JSON.toJSONString(rsp));
			return new R<>(rsp.getData().getTaskStatus());
		} else {
			return R.failed(rsp.getMsg());
		}
	}
}
