package com.yifu.cloud.plus.v1.yifu.salary.service.impl.process;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ResultConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
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.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.EkpDaprUtils;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpDivisionInfoVo;
import com.yifu.cloud.plus.v1.yifu.salary.config.WxConfig;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TAuditNodeProcess;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TAuditRecord;
import com.yifu.cloud.plus.v1.yifu.salary.service.TInsuranceUnpurchaseApplyService;
import com.yifu.cloud.plus.v1.yifu.salary.service.impl.AbastractAuditProcess;
import com.yifu.cloud.plus.v1.yifu.process.constant.ProcessConstants;
import com.yifu.cloud.plus.v1.yifu.process.entity.TNodePrimission;
import com.yifu.cloud.plus.v1.yifu.process.entity.TNodeRoute;
import com.yifu.cloud.plus.v1.yifu.process.entity.TNodeRouteCondition;
import com.yifu.cloud.plus.v1.yifu.process.entity.TProcessNode;
import com.yifu.cloud.plus.v1.yifu.process.util.ProcessAuditUtil;
import com.yifu.cloud.plus.v1.yifu.process.vo.ProcessVo;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TInsuranceUnpurchaseApply;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TInsuranceUnpurchasePerson;
import com.yifu.cloud.plus.v1.yifu.salary.service.TInsuranceUnpurchasePersonService;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TInsuranceUnpurchaseApplySearchVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @auther wangan
 * @date 2021/4/26
 * 商机审核
 */
@Component
public class TInsuranceUnpurchaseApplyAuditProcess extends AbastractAuditProcess<TInsuranceUnpurchaseApply, TInsuranceUnpurchaseApplySearchVo> {

	@Resource
	private TInsuranceUnpurchaseApplyService tInsuranceUnpurchaseApplyService;

	@Resource
	private TInsuranceUnpurchasePersonService personService;

	@Autowired
	private WxConfig wxConfig;

	@Autowired
	private EkpDaprUtils ekpDaprUtils;

    @Override
    public R<String> auditSuccess(TInsuranceUnpurchaseApply entity, TAuditRecord auditRecord, YifuUser loginUser) {
    	// 改实体审核状态为审核通过
        entity.setStatus(CommonConstants.THREE_STRING);
        entity.setAuditUser("");
		entity.setAuditUserId("");
        boolean res = tInsuranceUnpurchaseApplyService.updateById(entity);
        if (res) {
            // 删除当前实体所有的流程节点，数据量太大影响审批效率
            // 防止死锁，先查询再删除
            TAuditNodeProcess auditNodeProcessInfo = auditNodeProcessService.getOne(Wrappers.<TAuditNodeProcess>query().lambda()
                    .eq(TAuditNodeProcess::getDomainId, entity.getId())
                    .in(TAuditNodeProcess::getType, auditRecord.getAuditType())
                    .last(CommonConstants.SQL_LIMIT_ONE));
            if(Common.isNotKong(auditNodeProcessInfo)) {
                auditNodeProcessService.remove(Wrappers.<TAuditNodeProcess>query().lambda().eq(TAuditNodeProcess::getDomainId, entity.getId())
                        .in(TAuditNodeProcess::getType, auditRecord.getAuditType()));
            }

			//huych--更新明细审核状态
			LambdaUpdateWrapper<TInsuranceUnpurchasePerson> updateWrapper = new LambdaUpdateWrapper<>();
			updateWrapper.eq(TInsuranceUnpurchasePerson::getParnetId,entity.getId())
					.set(TInsuranceUnpurchasePerson::getStatus, entity.getStatus());
			personService.update(updateWrapper);
        }

        return R.ok("审核通过");
    }

    @Override
    public R<String> auditSuccessAndNex(TInsuranceUnpurchaseApply entity, List<SysUser> remoteSysUserList, TAuditRecord auditRecord) {
		if (Common.isEmpty(remoteSysUserList)) {
			throw new CheckedException(NEXT_NODE_USER_NULL);
		}
		// 存即将审批人的信息
		String auditUserNameStrs = "";
		String auditUserIdStrs = "";
		for(SysUser userInfo : remoteSysUserList){
			auditUserIdStrs = auditUserIdStrs.concat(";").concat(userInfo.getUserId());
			auditUserNameStrs = auditUserNameStrs.concat(";").concat(userInfo.getNickname());
		}
		if(Common.isNotNull(auditUserNameStrs)){
			auditUserNameStrs = auditUserNameStrs.substring(1);
		}
		if(Common.isNotNull(auditUserIdStrs)){
			auditUserIdStrs = auditUserIdStrs.substring(1);
		}
		entity.setAuditUser(auditUserNameStrs);
		entity.setAuditUserId(auditUserIdStrs);
		tInsuranceUnpurchaseApplyService.updateById(entity);

        return R.ok("审核通过");
    }

    @Override
    public R<String> auditFail(TInsuranceUnpurchaseApply entity, TAuditRecord approvalRecord) {
		// 以后有抄送再加逻辑：参照crm-更改之前抄送记录状态为0
		// 改实体审核状态为审核不通过
		entity.setStatus(CommonConstants.FOUR_STRING);
		entity.setAuditUser("");
		entity.setAuditUserId("");
		tInsuranceUnpurchaseApplyService.updateById(entity);

		// 删除当前实体所有的流程节点，数据量太大影响审批效率
		// 防止死锁，先查询再删除
		TAuditNodeProcess auditNodeProocessInfo = auditNodeProcessService.getOne(Wrappers.<TAuditNodeProcess>query().lambda()
				.eq(TAuditNodeProcess::getDomainId, entity.getId())
				.in(TAuditNodeProcess::getType, approvalRecord.getAuditType())
				.last(CommonConstants.SQL_LIMIT_ONE));
		if(Common.isNotKong(auditNodeProocessInfo)) {
			auditNodeProcessService.remove(Wrappers.<TAuditNodeProcess>query().lambda()
					.eq(TAuditNodeProcess::getDomainId, entity.getId())
					.in(TAuditNodeProcess::getType, approvalRecord.getAuditType()));
		}

		return R.ok("审核成功");
    }

    @Override
    public TProcessNode choiceGetNode(ProcessVo processVo, List<TNodeRoute> nodeRouteList, List<TNodeRouteCondition> nodeRouteConditionList,
									  TProcessNode currentNode, TInsuranceUnpurchaseApply entity, String auditType, YifuUser loginUser) {
        // 根据不购买原因判断 1 已购买社保 2 人员已离职选择
        if (StringUtils.equals(ProcessConstants.PROCESS_NODE_INSURANCEUNPURCHASE_REASON_TYPE,currentNode.getName())){
        	// 通过条件表达式判断路由的下一个节点
            TNodeRoute nodeRoute = ProcessAuditUtil.getTNodeRoteByExpress(nodeRouteList, nodeRouteConditionList, entity.getReasonType(), null);
            // 存下一个节点的信息
            saveNodeProcess(processVo, nodeRoute.getNextNode(), entity.getId(), auditType);
            // 校验即将进入的节点信息，是审批节点返回节点信息，不是继续找下一个节点信息
            return validateNextNode(processVo, nodeRoute.getNextNode(), entity.getId(), nodeRoute.getRouteType(), auditType, entity, loginUser);
        }else if (StringUtils.equals(ProcessConstants.PROCESS_NODE_INSURANCEUNPURCHASE_DEPT_PROPERTY,currentNode.getName())){
            // 根据申请部门 是否属于子分公司
			// 通过条件表达式判断路由的下一个节点
            TNodeRoute nodeRoute = ProcessAuditUtil.getTNodeRoteByExpress(nodeRouteList, nodeRouteConditionList, entity.getCompanyFlag(), null);
			// 存下一个节点的信息
            saveNodeProcess(processVo, nodeRoute.getNextNode(), entity.getId(), auditType);
			// 校验即将进入的节点信息，是审批节点返回节点信息，不是继续找下一个节点信息
            return validateNextNode(processVo, nodeRoute.getNextNode(), entity.getId(), nodeRoute.getRouteType(), auditType, entity, loginUser);
        } else{
            throw new CheckedException("未知的条件节点类型,请联系管理员");
        }
    }

    @Override
    public R<String> sendMessage(List<SysUser> users, TInsuranceUnpurchaseApply entity, String type, TAuditRecord approvalRecord) {
		sendMessageToWx(users,entity,type);
        return R.ok(null, ResultConstants.SUCCESS_INFO);
    }

	/**
	 * 根据事业部条线获取审批用户
	 * @param nodePrimission
	 * @param entity
	 * @return List<SysUser>
	 **/
	@Override
	public List<SysUser> getDivisionAuditUser(TNodePrimission nodePrimission, TInsuranceUnpurchaseApply entity) {
		SysUser remoteSysUser;
		List<SysUser> remoteSysUserList = new ArrayList<>();
		if (CommonConstants.SIX_INT == nodePrimission.getType().intValue()) {
			 // 6.指定事业部审批
			 if (Common.isEmpty(nodePrimission.getDivisionIdentification())) {
				 throw new CheckedException("未查询当前节点配置的事业部审批人标识");
			 }
			 // 根据配置条件查找用户账号
			EkpDivisionInfoVo divisionInfoVo = new EkpDivisionInfoVo();
			divisionInfoVo.setDivisionIdentification(nodePrimission.getDivisionIdentification());
			divisionInfoVo.setDivision(entity.getDivision());
			divisionInfoVo.setNewLine(entity.getNewLine());

			R<EkpDivisionInfoVo> divisionInfoVoRes = ekpDaprUtils.getDivisionUsernameList(divisionInfoVo);
			if(null != divisionInfoVoRes && null != divisionInfoVoRes.getData()) {
				List<String> divisionUsernameList = divisionInfoVoRes.getData().getDivisionUsernameList();
				if(Common.isNotNull(divisionUsernameList)){
					// 根据用户账号查用户信息
					for(String username : divisionUsernameList){
						R<SysUser> remoteSysUserR = upmsDaprUtils.getSimpleUserByLoginName(username);
						if (Common.isNotNull(remoteSysUserR) && Common.isNotNull(remoteSysUserR.getData())){
							remoteSysUser = remoteSysUserR.getData();
							remoteSysUserList.add(remoteSysUser);
						}
					}
				}
			}
		}
		return remoteSysUserList;
	}


	private void sendMessageToWx(List<SysUser> users, TInsuranceUnpurchaseApply insuranceUnpurchaseApply, String type) {

			StringBuilder sendUser = null;
			for (SysUser user : users) {
				if (Common.isNotKong(user.getWxMessage())) {
					if (sendUser == null) {
						sendUser = new StringBuilder(user.getWxMessage());
					} else {
						sendUser = sendUser.append("|").append(user.getWxMessage());
					}
				}
			}
			if (sendUser != null) {
				RestTemplate restTemplate = new RestTemplate();
				Map<String, Object> requestMap = new HashMap<>();
				String authUrl = null;
				Map<String, Object> textcard = new HashMap<>();

				authUrl = String.format(SecurityConstants.WX_GET_MESSAGE_AUTH_URL, wxConfig.getCorpid(), wxConfig.getDomainName()+"/auth/oauth/wxLogin", "01"+insuranceUnpurchaseApply.getId());
				textcard.put("title", "含风险项目不购买商险申请");

				textcard.put("url", authUrl);
				StringBuilder description = new StringBuilder();
				description.append("申请人：").append(insuranceUnpurchaseApply.getCreateName()).append("<br>");
				description.append("项目编码：").append(insuranceUnpurchaseApply.getDeptNo()).append("<br>");

				String departName =  insuranceUnpurchaseApply.getDeptName();
				if(departName.length()>CommonConstants.THIRTY_INT){
					departName = insuranceUnpurchaseApply.getDeptName().substring(CommonConstants.ZERO_INT,CommonConstants.TWENTY_SEVEN_INT)+"...";
				}
				description.append("项目名称：").append(departName).append("<br>");
				// 不购买原因 1 已购买社保 2 人员已离职
				Map<String,String> reasonTypeMap = new HashMap<>();
				reasonTypeMap.put("1", "已购买社保");
				reasonTypeMap.put("2", "人员已离职");
				description.append("不购买原因：").append(reasonTypeMap.get(insuranceUnpurchaseApply.getReasonType())).append("<br>");

				String unbuyNum =  CommonConstants.ZERO_STRING;
				if(Common.isNotNull(insuranceUnpurchaseApply.getUnbuyNum())){
					unbuyNum = insuranceUnpurchaseApply.getUnbuyNum();
				}
				description.append("不购买人数：").append(unbuyNum).append("<br>");

				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);
				}
			}


	}
}
