package com.qunzhixinxi.hnqz.admin.service.gig.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qunzhixinxi.hnqz.admin.api.constant.CacheConstants;
import com.qunzhixinxi.hnqz.admin.api.constant.MqConstants;
import com.qunzhixinxi.hnqz.admin.api.entity.SysDept;
import com.qunzhixinxi.hnqz.admin.api.entity.SysUser;
import com.qunzhixinxi.hnqz.admin.config.TaxNotifyConfig;
import com.qunzhixinxi.hnqz.admin.config.UpmsConfig;
import com.qunzhixinxi.hnqz.admin.entity.SysDeptSub;
import com.qunzhixinxi.hnqz.admin.entity.SysUserExtRecord;
import com.qunzhixinxi.hnqz.admin.entity.SysUserSub;
import com.qunzhixinxi.hnqz.admin.entity.dto.UserSignCertDTO;
import com.qunzhixinxi.hnqz.admin.entity.model.GigBaseInfoModel;
import com.qunzhixinxi.hnqz.admin.entity.model.GigInfoModel;
import com.qunzhixinxi.hnqz.admin.entity.model.GigUserInfoModel;
import com.qunzhixinxi.hnqz.admin.entity.vo.SysUserSubVO;
import com.qunzhixinxi.hnqz.admin.enums.DelEnum;
import com.qunzhixinxi.hnqz.admin.enums.GigCallBackStatus;
import com.qunzhixinxi.hnqz.admin.enums.GigChannelEnum;
import com.qunzhixinxi.hnqz.admin.enums.GigTypeEnum;
import com.qunzhixinxi.hnqz.admin.enums.LockEnum;
import com.qunzhixinxi.hnqz.admin.enums.MemberIDCardType;
import com.qunzhixinxi.hnqz.admin.enums.MemberType;
import com.qunzhixinxi.hnqz.admin.enums.OladingCertStatus;
import com.qunzhixinxi.hnqz.admin.enums.PayChannel;
import com.qunzhixinxi.hnqz.admin.enums.RenlijiaCertStatus;
import com.qunzhixinxi.hnqz.admin.enums.SubjectLocation;
import com.qunzhixinxi.hnqz.admin.enums.SubjectTypeEnum;
import com.qunzhixinxi.hnqz.admin.enums.YeeCertStatus;
import com.qunzhixinxi.hnqz.admin.service.SysDeptService;
import com.qunzhixinxi.hnqz.admin.service.SysDeptSubService;
import com.qunzhixinxi.hnqz.admin.service.SysUserExtRecordService;
import com.qunzhixinxi.hnqz.admin.service.SysUserService;
import com.qunzhixinxi.hnqz.admin.service.SysUserSubService;
import com.qunzhixinxi.hnqz.admin.service.gig.SysUserSignCertService;
import com.qunzhixinxi.hnqz.common.core.constant.CommonConstants;
import com.qunzhixinxi.hnqz.common.core.entity.BaseMap;
import com.qunzhixinxi.hnqz.common.core.util.R;
import com.qunzhixinxi.hnqz.common.rabbitmq.client.RabbitMqClient;
import com.qunzhixinxi.hnqz.common.security.service.HnqzUser;
import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
import com.qunzhixinxi.hnqz.common.taxhelper.enums.TaxHelperCertStatus;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用户签约认证服务
 *
 * @author lixuesong
 * @date 2022年03月03日 14:38
 */
@Slf4j
@Service
@AllArgsConstructor
public class SysUserSignCertServiceImpl implements SysUserSignCertService {

	private final SysUserService sysUserService;

	private final SysUserSubService sysUserSubService;

	private final SysDeptSubService sysDeptSubService;

	private final SysDeptService sysDeptService;

	private final SysUserExtRecordService sysUserExtRecordService;

	private final RabbitMqClient rabbitMqClient;

	private final UpmsConfig upmsConfig;

	private final TaxNotifyConfig taxNotifyConfig;

	private final RedisTemplate redisTemplate;

	/**
	 * 查询会员认证结果接口url
	 */
	private static final String GIG_CERT_STATE = "/gig/v2/operation/cert/state";

	/**
	 * 签约接口url
	 */
	private static final String GIG_CERT_ACTION_SIGN_UP = "/gig/v2/operation/cert/action/sign-up";

	/**
	 * 税邦云绑卡url
	 */
	private static final String GIG_CERT_ACTION_BANK_CARD = "/gig/v2/operation/cert/action/bank-card";

	/**
	 * 查询用户签约认证信息
	 *
	 * @param userId
	 * @return
	 */
	@Override
	public List<SysUserSub> listUserSignCert(Integer userId) {
		List<SysUserSub> userSubList = sysUserSubService.list(Wrappers.<SysUserSub>lambdaQuery()
				.eq(SysUserSub::getUserId, userId));
		return userSubList;
	}

	/**
	 * 查询用户签约认证信息
	 *
	 * @param userId
	 * @param gigTypeList
	 * @return
	 */
	@Deprecated
	@Override
	public List<SysUserSub> listUserSignCert(Integer userId, List<GigTypeEnum> gigTypeList) {
		List<SysUserSub> userSubList = sysUserSubService.list(Wrappers.<SysUserSub>lambdaQuery()
				.eq(SysUserSub::getUserId, userId)
				.in(SysUserSub::getGigType, gigTypeList));
		return userSubList;
	}

	/**
	 * 查询用户签约认证信息
	 *
	 * @param userId
	 * @param deptId
	 * @return
	 */
	@Override
	public List<SysUserSubVO> listUserSignCertForApi(Integer userId, Integer deptId) {
		List<SysUserSub> userSubList = sysUserSubService.list(Wrappers.<SysUserSub>lambdaQuery()
				.eq(SysUserSub::getDeptId, deptId)
				.eq(SysUserSub::getUserId, userId));
		if (CollUtil.isNotEmpty(userSubList)) {
			List<SysUserSubVO> resultList = new ArrayList<>();
			userSubList.forEach(sysUserSub -> {
				SysUserSubVO userSubVO = BeanUtil.copyProperties(sysUserSub, SysUserSubVO.class, "certStatus");
				switch (sysUserSub.getGigType()) {
					case REN_LI_JIA:
						userSubVO.setCertStatus(RenlijiaCertStatus.resolve(sysUserSub.getCertStatus()).name());
						break;
					case TAX_HELPOR:
						userSubVO.setCertStatus(TaxHelperCertStatus.resolve(sysUserSub.getCertStatus()).name());
						break;
					case YEE:
						userSubVO.setCertStatus(YeeCertStatus.resolve(String.valueOf(sysUserSub.getCertStatus())).name());
						break;
					case OLADING:
						userSubVO.setCertStatus(OladingCertStatus.resolve(String.valueOf(sysUserSub.getCertStatus())).name());
						break;
					default:
				}

				resultList.add(userSubVO);
			});
			return resultList;
		}
		return new ArrayList<>();
	}

	/**
	 * 查询用户认证状态
	 *
	 * @param idCard 身份证号
	 * @param enterprisCode 税号
	 * @param subjectChannel 渠道类型
	 * @return
	 */
	@Override
	public Map<String, Object> listCertInfo(String idCard, String enterprisCode, List<SubjectLocation> subjectChannel) {
		Map<String, Object> params = new HashMap<>(3);
		params.put("idCard", idCard);
		params.put("enterprisCode", enterprisCode);
		params.put("subjectChannel", subjectChannel);
		String postResult = HttpUtil.post(upmsConfig.getGigServiceUrl() + GIG_CERT_STATE, JSONUtil.toJsonStr(params));
		log.info("查询用户认证状态返回：{}", postResult);
		if (JSONUtil.isJsonObj(postResult)) {
			JSONObject jsonResult = JSONUtil.parseObj(postResult);
			if (CommonConstants.SUCCESS.equals(jsonResult.getInt("code"))) {
				return jsonResult.getJSONObject("data");
			}
		}

		return null;
	}

	/**
	 * 保存用户基础信息
	 *
	 * @param userSignCertDTO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveBaseInfo(UserSignCertDTO userSignCertDTO) {
		HnqzUser user = SecurityUtils.getUser();
		Integer operateUserId = user.getId();
		// 查询user
		SysUser queryUser = sysUserService.getById(userSignCertDTO.getUserId());

		if (StrUtil.isNotBlank(userSignCertDTO.getIdCardNumber()) || StrUtil.isNotBlank(userSignCertDTO.getBankPhone())
				|| StrUtil.isNotBlank(userSignCertDTO.getBankCardNumber())) {
			// 更新用户信息
			SysUser updateUser = new SysUser();
			updateUser.setUserId(userSignCertDTO.getUserId());
			updateUser.setIdCardNumber(userSignCertDTO.getIdCardNumber());
			updateUser.setBankPhone(userSignCertDTO.getBankPhone());
			updateUser.setBankCardNumber(userSignCertDTO.getBankCardNumber());
			updateUser.setUpdateTime(LocalDateTime.now());
			sysUserService.updateById(updateUser);
		}
		// 更新用户签约认证主体信息
		// 税邦云单独设置渠道类型
		SubjectLocation subjectLocation = userSignCertDTO.getSubjectLocation();
		GigChannelEnum gigChannel;
		if (GigTypeEnum.TAX_HELPOR.equals(subjectLocation.getGigType())) {
			// 读取用户所认证的企业的结算渠道
			SysDeptSub deptSub = sysDeptSubService.getOne(Wrappers.<SysDeptSub>lambdaQuery()
					.eq(SysDeptSub::getDeptId, queryUser.getDeptId())
					.eq(SysDeptSub::getSubjectType, subjectLocation.getGigType().getCode())
					.eq(SysDeptSub::getSubjectLocation, subjectLocation)
					.eq(SysDeptSub::getEnableFlag, SubjectTypeEnum.ENABLE_FLAG_TRUE.getCode()));
			if (deptSub != null) {
				gigChannel = GigChannelEnum.resolve(Integer.parseInt(deptSub.getSubjectType()));
			} else {
				gigChannel = GigChannelEnum.DEFAULT;
			}
		} else {
			gigChannel = GigChannelEnum.DEFAULT;
		}
		SysUserSub queryUserSub = sysUserSubService.getOne(Wrappers.<SysUserSub>lambdaQuery()
				.eq(SysUserSub::getUserId, userSignCertDTO.getUserId())
				.eq(SysUserSub::getDeptId, queryUser.getDeptId())
				.eq(SysUserSub::getGigType, subjectLocation.getGigType())
				.eq(SysUserSub::getSubjectLocation, subjectLocation));
		if (queryUserSub != null) {
			SysUserSub updateUserSub = new SysUserSub();
			updateUserSub.setId(queryUserSub.getId());
			updateUserSub.setCallbackStatus(GigCallBackStatus.NOT_SUBMIT);
			updateUserSub.setGigChannel(gigChannel);
			updateUserSub.setBankCardNumber(userSignCertDTO.getBankCardNumber());
			updateUserSub.setUpdateTime(LocalDateTime.now());
			updateUserSub.setUpdateUser(operateUserId);
			sysUserSubService.updateById(updateUserSub);
		} else {
			SysUserSub userSub = new SysUserSub();
			userSub.setUserId(userSignCertDTO.getUserId());
			userSub.setDeptId(queryUser.getDeptId());
			userSub.setGigType(subjectLocation.getGigType());
			userSub.setGigChannel(gigChannel);
			userSub.setSubjectLocation(userSignCertDTO.getSubjectLocation());
			userSub.setCallbackStatus(GigCallBackStatus.NOT_SUBMIT);
			userSub.setBankCardNumber(userSignCertDTO.getBankCardNumber());
			userSub.setBankPhone(userSignCertDTO.getBankPhone());
			userSub.setCreateUser(operateUserId);
			userSub.setCreateTime(LocalDateTime.now());
			sysUserSubService.save(userSub);
		}
	}

	/**
	 * 签约/增员
	 *
	 * @param userSignCertDTO
	 * @return
	 */
	@Override
	public R<?> toSign(UserSignCertDTO userSignCertDTO) {
		Integer userId = userSignCertDTO.getUserId();

		// 根据用户id查询用户信息
		SysUser sysUser = sysUserService.getById(userId);
		if (sysUser == null) {
			return R.failed("用户不存在");
		}

		// 查询userSub
		SysUserSub userSub = sysUserSubService.getOne(Wrappers.<SysUserSub>lambdaQuery()
				.eq(SysUserSub::getDeptId, sysUser.getDeptId())
				.eq(SysUserSub::getUserId, userId)
				.eq(SysUserSub::getSubjectLocation, userSignCertDTO.getSubjectLocation()));
		if (userSub == null) {
			return R.failed("用户sub数据不存在");
		}
		// 判断是否已签约/增员
		if (userSignCertDTO.getSubjectLocation().getGigType().equals(GigTypeEnum.TAX_HELPOR)) {
			if (userSub.getCertStatus() > TaxHelperCertStatus.UN_CERT.getCode()) {
				return R.ok();
			}
		} else if (userSignCertDTO.getSubjectLocation().getGigType().equals(GigTypeEnum.OLADING)) {
			if (OladingCertStatus.SIGNED.getCode().equals(String.valueOf(userSub.getCertStatus()))
					|| OladingCertStatus.SIGNING.getCode().equals(String.valueOf(userSub.getCertStatus()))
					|| OladingCertStatus.CERT.getCode().equals(String.valueOf(userSub.getCertStatus()))) {
				return R.ok(MapUtil.builder("certStatus", OladingCertStatus.resolve(String.valueOf(userSub.getCertStatus()))).build());
			}
		}

		// 查询dept
		SysDept dept = sysDeptService.getById(sysUser.getDeptId());

		// 发起签约/增员
		Map<String, Object> params = new HashMap<>();
		params.put("enterpriseCode", dept.getTaxCode());
		params.put("subjectLocation", userSub.getSubjectLocation().name());
		params.put("subjectChannel", userSub.getGigChannel().name());
		params.put("realName", sysUser.getRealname());
		params.put("phone", sysUser.getUsername());
		params.put("bankPhone", userSub.getBankPhone());
		params.put("bankCard", userSub.getBankCardNumber());
		params.put("idCard", sysUser.getIdCardNumber());
		params.put("endType", "CSO");
		params.put("email", "service@yaoyi.net");
		params.put("address", "北京市房山区");

		String postResult = HttpUtil.post(upmsConfig.getGigServiceUrl() + GIG_CERT_ACTION_SIGN_UP, JSONUtil.toJsonStr(params));
		log.info("签约/增员，req={}, resp={}", JSONUtil.toJsonStr(params), postResult);

		String message = "增员/签约失败";
		int certStatus = 0;
		boolean successFlag = false;
		String requestId = null;
		if (JSONUtil.isJsonObj(postResult)) {
			JSONObject jsonResult = JSONUtil.parseObj(postResult);
			if (jsonResult.getInt("code") == 0) {
				JSONObject data = jsonResult.getJSONObject("data");
				if (userSignCertDTO.getSubjectLocation().getGigType().equals(GigTypeEnum.TAX_HELPOR)) {
					if ("2000".equals(data.getStr("code"))) {
						successFlag = true;
						certStatus = TaxHelperCertStatus.ADD_MEMBER.getCode();
					}
					message = data.getStr("message");
				} else if (userSignCertDTO.getSubjectLocation().getGigType().equals(GigTypeEnum.OLADING)) {
					if ("0".equals(data.getStr("code"))) {
						successFlag = true;
						certStatus = Integer.parseInt(OladingCertStatus.SIGNING.getCode());
						requestId = data.getStr("requestId");
					} else if ("1004".equals(data.getStr("code"))) {
						successFlag = true;
						certStatus = Integer.parseInt(OladingCertStatus.SIGNING.getCode());
					}
					message = data.getStr("message");
				}
			}
		}

		// 修改userSub状态
		SysUserSub updateUserSub = new SysUserSub();
		updateUserSub.setId(userSub.getId());
		updateUserSub.setCertStatus(certStatus);
		updateUserSub.setCertRemark("签约/增员:" + message);
		updateUserSub.setRequestId(requestId);
		updateUserSub.setUpdateUser(SecurityUtils.getUser().getId());
		updateUserSub.setUpdateTime(LocalDateTime.now());
		sysUserSubService.updateById(updateUserSub);

		if (successFlag) {
			if (userSignCertDTO.getSubjectLocation().getGigType().equals(GigTypeEnum.OLADING)) {
				return R.ok(MapUtil.builder("certStatus", OladingCertStatus.resolve(String.valueOf(certStatus))).build());
			}
			return R.ok();
		}
		return R.failed(message);
	}

	/**
	 * 签协议
	 *
	 * @param userSignCertDTO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void signAgreement(UserSignCertDTO userSignCertDTO) {
		SysUser sysUser = sysUserService.getById(userSignCertDTO.getUserId());

		LambdaUpdateWrapper<SysUserSub> updateWrapper = Wrappers.lambdaUpdate();
		updateWrapper.eq(SysUserSub::getUserId, userSignCertDTO.getUserId());
		updateWrapper.eq(SysUserSub::getDeptId, sysUser.getDeptId());
		if (userSignCertDTO.getSubjectLocation() != null) {
			updateWrapper.eq(SysUserSub::getSubjectLocation, userSignCertDTO.getSubjectLocation());
		}
		updateWrapper.set(SysUserSub::getAgreementUrl, userSignCertDTO.getAgreementUrl());
		updateWrapper.set(SysUserSub::getUpdateUser, SecurityUtils.getUser().getId());
		updateWrapper.set(SysUserSub::getUpdateTime, LocalDateTime.now());

		sysUserSubService.update(updateWrapper);
	}

	/**
	 * 人身验证
	 *
	 * @param userSignCertDTO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void personalIdentityVerification(UserSignCertDTO userSignCertDTO) {

		LambdaUpdateWrapper<SysUserSub> updateWrapper = Wrappers.lambdaUpdate();
		updateWrapper.eq(SysUserSub::getUserId, userSignCertDTO.getUserId());
		if (userSignCertDTO.getSubjectLocation() != null) {
			updateWrapper.eq(SysUserSub::getSubjectLocation, userSignCertDTO.getSubjectLocation());
		}
		if (StrUtil.isNotBlank(userSignCertDTO.getAgreementUrl())) {
			updateWrapper.set(SysUserSub::getAgreementUrl, userSignCertDTO.getAgreementUrl());
		}
		updateWrapper.set(SysUserSub::getIdCardFrontUrl, userSignCertDTO.getIdCardFrontUrl());
		updateWrapper.set(SysUserSub::getIdCardBackUrl, userSignCertDTO.getIdCardBackUrl());
		updateWrapper.set(SysUserSub::getCertVideo1Url, userSignCertDTO.getCertVideo1Url());
		updateWrapper.set(SysUserSub::getCertVideo2Url, userSignCertDTO.getCertVideo2Url());
		updateWrapper.set(SysUserSub::getUpdateUser, SecurityUtils.getUser().getId());
		updateWrapper.set(SysUserSub::getUpdateTime, LocalDateTime.now());

		sysUserSubService.update(updateWrapper);
	}

	/**
	 * 批量发起用户签约认证
	 *
	 * @param userSignCertDTO
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean batchChannelCert(UserSignCertDTO userSignCertDTO) {
		Integer userId = userSignCertDTO.getUserId();
		// 根据用户id查询用户信息、认证信息
		SysUser sysUser = sysUserService.getById(userId);
		if (sysUser == null) {
			return false;
		}
		// 查询认证数据
		SysUserExtRecord userExtRecord = sysUserExtRecordService.getOne(Wrappers.<SysUserExtRecord>lambdaQuery()
				.eq(SysUserExtRecord::getUserId, userId)
				.eq(SysUserExtRecord::getDelFlag, DelEnum.NOT_DEL.val()));
		if (userExtRecord == null && !SubjectLocation.REN_LI_JIA.equals(userSignCertDTO.getSubjectLocation())) {
			return false;
		}
		// 查询dept
		SysDept dept = sysDeptService.getById(sysUser.getDeptId());
		// 查询当前用户关联的userSub
		LambdaQueryWrapper<SysUserSub> userSubWrapper = Wrappers.lambdaQuery();
		userSubWrapper.eq(SysUserSub::getUserId, userId);
		userSubWrapper.eq(SysUserSub::getDeptId, sysUser.getDeptId());
		userSubWrapper.eq(SysUserSub::getSubjectLocation, userSignCertDTO.getSubjectLocation());
		List<SysUserSub> userSubList = sysUserSubService.list(userSubWrapper);

		if (CollUtil.isNotEmpty(userSubList)) {
			// 过滤出阿拉钉的渠道
			Collection<SubjectLocation> oladingList =
					CollUtil.intersection(CollUtil.toList(userSignCertDTO.getSubjectLocation()),
							SubjectLocation.getByGigType(GigTypeEnum.OLADING)).stream()
							.sorted(Comparator.comparing(SubjectLocation::getSort))
							.collect(Collectors.toList());

			// 封装请求数据
			userSubList.stream()
					.sorted(Comparator.comparing(sysUserSub -> sysUserSub.getSubjectLocation().getSort()))
					.filter(sysUserSub -> {
				// 过滤掉认证成功的数据
				if (GigTypeEnum.TAX_HELPOR.equals(sysUserSub.getGigType())
						&& TaxHelperCertStatus.CHECKED_UNBIND.getCode() != sysUserSub.getCertStatus()
						&& TaxHelperCertStatus.CERT.getCode() != sysUserSub.getCertStatus()) {
					return true;
				} else if (GigTypeEnum.YEE.equals(sysUserSub.getGigType())
						&& !YeeCertStatus.SIGNED.getCode().equals(String.valueOf(sysUserSub.getCertStatus()))) {
					return true;
				} else if (GigTypeEnum.OLADING.equals(sysUserSub.getGigType())) {
					return true;
				} else if (GigTypeEnum.REN_LI_JIA.equals(sysUserSub.getGigType())
						&& RenlijiaCertStatus.CER_STATUS_1.getCode() != sysUserSub.getCertStatus()) {
					return true;
				}
				return false;
			}).forEach(userSub -> {

				// 发起前置判断
				if (!this.preSignCert(sysUser, userSub, userSignCertDTO, oladingList)) {
					// false直接返回，不发送mq
					log.info("本次不发起认证，userSubId={}", userSub.getId());
					return;

				}
				// 请求流水号
				String requestId = RandomStringUtils.randomAlphabetic(16);

				// 是否需要传核身视频，阿拉丁、易联默认都要传
				boolean uploadFaceID = userSignCertDTO.getUploadFaceID() != null && userSignCertDTO.getUploadFaceID();
				// 封装请求参数
				GigInfoModel infoModel = this.buildChannelCertModel(sysUser, userSub, userExtRecord, dept.getTaxCode(), requestId, uploadFaceID);
				// 更新为进行中状态
				SysUserSub updateUserSub = new SysUserSub();
				updateUserSub.setId(userSub.getId());
				updateUserSub.setRequestId(requestId);
				updateUserSub.setCallbackStatus(GigCallBackStatus.IN_PROGRESS);
				updateUserSub.setUpdateTime(LocalDateTime.now());
				HnqzUser hnqzUser = SecurityUtils.getUser();
				updateUserSub.setUpdateUser(hnqzUser != null ? hnqzUser.getId() : 0);
				sysUserSubService.updateById(updateUserSub);
				// 发送mq
				BaseMap gigInfo = new BaseMap();
				gigInfo.put(userSub.getGigType().name(), infoModel);
				rabbitMqClient.sendMessage(MqConstants.DIRECT_MODE_GIG_SIGN_CERT_QUEUE, JSONUtil.toJsonStr(gigInfo));

			});
			return true;
		}
		return false;
	}

	/**
	 * 签约认证前的前置判断
	 *
	 * @param sysUser 用户信息
	 * @param userSub userSub信息
	 * @param userSignCertDTO 发起参数
	 * @param locationList 阿拉钉税源地list
	 */
	private boolean preSignCert(SysUser sysUser, SysUserSub userSub, UserSignCertDTO userSignCertDTO, Collection<SubjectLocation> locationList) {
		// 校验是否有进行中的
		if (GigCallBackStatus.IN_PROGRESS.equals(userSub.getCallbackStatus())) {
			return false;
		}

		switch (userSub.getGigType()) {
			case OLADING:
				// 阿拉钉-海南飞亿
				// 如果需要传核身视频，则返回true
				if (userSignCertDTO.getUploadFaceID() != null && userSignCertDTO.getUploadFaceID()) {
					return true;
				}

				// 已认证不发起
				if (OladingCertStatus.CERT.getCode().equals(String.valueOf(userSub.getCertStatus()))) {
					return false;
				}

				// 如果同时包含阿拉钉多个渠道，则只选第一个发起，其余不发起
				if (locationList.size() > 1 && !locationList.stream().findFirst().get().equals(userSub.getSubjectLocation())) {
					// 同时选择了阿拉钉金园数科、海南飞亿、河南薪泰梓渠道的两个及以上，则先发起第一个，完成之后再依次发起其他的
					return false;
				}

				return true;
			case REN_LI_JIA:
				// 人力家直接调用原有发短信接口
				SysDept dept = new SysDept();
				dept.setDeptId(sysUser.getDeptId());
				Map<String, String> renLiJiaResult = sysUserService.certByRenLiJia(sysUser, dept);
				// 更新状态
				SysUserSub updateUserSub = new SysUserSub();
				updateUserSub.setId(userSub.getId());
				Integer renLijiaCertStatus =
						Optional.ofNullable(sysUser.getRljCertStatus()).orElseGet(RenlijiaCertStatus.CER_STATUS_4::getCode);
				// 结果状态
				RenlijiaCertStatus certStatus = RenlijiaCertStatus.resolve(renLijiaCertStatus);
				updateUserSub.setCertStatus(sysUser.getRljCertStatus());
				// 发起成功或认证成功，才修改CallbackStatus状态
				if (RenlijiaCertStatus.CER_STATUS_1.equals(certStatus) || RenlijiaCertStatus.CER_STATUS_3.equals(certStatus)) {
					updateUserSub.setCallbackStatus(GigCallBackStatus.IN_PROGRESS);
				} else {
					updateUserSub.setCallbackStatus(GigCallBackStatus.RETURNED);
				}
				updateUserSub.setCertRemark(renLiJiaResult.get("msg"));
				updateUserSub.setUpdateTime(LocalDateTime.now());
				updateUserSub.setUpdateUser(0);
				sysUserSubService.updateById(updateUserSub);
				// 结果放到redis
				String key = CacheConstants.USER_SIGN_CERT_RESPONSE_KEY + userSub.getUserId();
				Map<String, String> subMap = new HashMap<>();
				subMap.put("certStatus", certStatus.name());
				Map<String, Object> result = MapUtil.newHashMap(1);
				result.put("REN_LI_JIA", subMap);
				redisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(result), 1, TimeUnit.MINUTES);
				// 默认返回false，不触发发送mq
				return false;
			default:
		}

		// 默认发起认证
		return true;
	}

	/**
	 * 是否存在已认证的，存在则同步更新状态
	 *
	 * @param sysUser
	 * @param userSub
	 * @return
	 */
	private boolean checkExistCerted(SysUser sysUser, SysUserSub userSub) {
		List<SysUser> existUserList = sysUserService.list(Wrappers.<SysUser>lambdaQuery()
				.eq(SysUser::getUsername, sysUser.getUsername())
				.eq(SysUser::getRealname, sysUser.getRealname())
				.eq(SysUser::getIdCardNumber, sysUser.getIdCardNumber())
				.eq(SysUser::getLockFlag, LockEnum.UN_LOCK.val())
				.ne(SysUser::getUserId, sysUser.getUserId()));
		if (CollUtil.isNotEmpty(existUserList)) {
			List<Integer> existUserIdList = existUserList.stream()
					.map(SysUser::getUserId)
					.collect(Collectors.toList());
			List<SysUserSub> existUserSubList = sysUserSubService.list(Wrappers.<SysUserSub>lambdaQuery()
					.in(SysUserSub::getUserId, existUserIdList)
					.eq(SysUserSub::getCertStatus, Integer.valueOf(OladingCertStatus.CERT.getCode()))
					.eq(SysUserSub::getCallbackStatus, GigCallBackStatus.RETURNED)
					.eq(SysUserSub::getGigType, userSub.getGigType()));
			if (CollUtil.isNotEmpty(existUserSubList)) {
				SysUserSub existUserSub = existUserSubList.get(0);
				// 更新状态
				SysUserSub updateUserSub = new SysUserSub();
				updateUserSub.setId(userSub.getId());
				updateUserSub.setCertStatus(existUserSub.getCertStatus());
				updateUserSub.setCallbackStatus(GigCallBackStatus.RETURNED);
				updateUserSub.setUpdateTime(LocalDateTime.now());
				updateUserSub.setUpdateUser(0);
				sysUserSubService.updateById(updateUserSub);
				// 结果放到redis
				String key = CacheConstants.USER_SIGN_CERT_RESPONSE_KEY + userSub.getUserId();
				Map<String, String> subMap = new HashMap<>();
				subMap.put("certStatus", OladingCertStatus.resolve(String.valueOf(existUserSub.getCertStatus())).name());
				Map<String, Object> result = MapUtil.newHashMap(1);
				result.put(userSub.getGigType().name(), subMap);
				redisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(result), 1, TimeUnit.MINUTES);

				return true;
			}
		}
		return false;
	}

	/**
	 * 封装签约认证的请求参数
	 *
	 * @param sysUser
	 * @param userSub
	 * @param userExtRecord
	 * @param entCode
	 * @param requestId
	 * @param uploadFaceID
	 * @return
	 */
	private GigInfoModel buildChannelCertModel(SysUser sysUser, SysUserSub userSub, SysUserExtRecord userExtRecord,
											   String entCode, String requestId, boolean uploadFaceID) {
		// 基础信息
		GigBaseInfoModel baseInfoModel = new GigBaseInfoModel();
		baseInfoModel.setRequestId(requestId);
		baseInfoModel.setGigType(userSub.getGigType());
		baseInfoModel.setGigChannel(userSub.getGigChannel());
		baseInfoModel.setGigLocation(userSub.getSubjectLocation());
		// 用户信息
		GigUserInfoModel userInfoModel = new GigUserInfoModel();
		userInfoModel.setUserId(sysUser.getUserId());
		userInfoModel.setName(sysUser.getRealname());
		userInfoModel.setUsername(sysUser.getUsername());
		userInfoModel.setEntCode(entCode);
		userInfoModel.setDeptId(sysUser.getDeptId());
		userInfoModel.setIdCard(sysUser.getIdCardNumber());
		userInfoModel.setIdCardType(MemberIDCardType.ID_CARD);
		userInfoModel.setMemberType(MemberType.YAOYI_EXCLUSIVE_PERSONNEL);
		userInfoModel.setEmail("gig_service@yaoyi.net");
		userInfoModel.setAddress("北京市-房山区-长阳镇");
		userInfoModel.setPayChannel(PayChannel.BANK_CARD);
		userInfoModel.setBankPhone(userSub.getBankPhone());
		userInfoModel.setBankCard(userSub.getBankCardNumber());
		userInfoModel.setUploadFaceID(uploadFaceID);
		userInfoModel.setIdCardFront(StrUtil.isBlank(userSub.getIdCardFrontUrl())
				? null : userSub.getIdCardFrontUrl().startsWith("https")
				? userSub.getIdCardFrontUrl() : upmsConfig.getClientUrl() + userSub.getIdCardFrontUrl());
		userInfoModel.setIdCardBack(StrUtil.isBlank(userSub.getIdCardBackUrl())
				? null : userSub.getIdCardBackUrl().startsWith("https")
				? userSub.getIdCardBackUrl() : upmsConfig.getClientUrl() + userSub.getIdCardBackUrl());
		userInfoModel.setCertVideo1(StrUtil.isBlank(userSub.getCertVideo1Url())
				? null : userSub.getCertVideo1Url().startsWith("https")
				? userSub.getCertVideo1Url() : upmsConfig.getClientUrl() + userSub.getCertVideo1Url());
		userInfoModel.setCertVideo2(StrUtil.isBlank(userSub.getCertVideo2Url())
				? null : userSub.getCertVideo2Url().startsWith("https")
				? userSub.getCertVideo2Url() : upmsConfig.getClientUrl() + userSub.getCertVideo2Url());
		userInfoModel.setSignImageUrl(StrUtil.isBlank(userSub.getAgreementUrl())
				? null : userSub.getAgreementUrl().startsWith("https")
				? userSub.getAgreementUrl() : upmsConfig.getClientUrl() + userSub.getAgreementUrl());
		userInfoModel.setIdCardBackBase64(userExtRecord.getIdCardBackBase64());
		userInfoModel.setIdCardFrontBase64(userExtRecord.getIdCardFrontBase64());
		userInfoModel.setBestFrameBase64(userExtRecord.getBestFrameBase64());

		GigInfoModel infoModel = new GigInfoModel();
		infoModel.setBaseInfo(baseInfoModel);
		infoModel.setUserInfo(userInfoModel);

		return infoModel;
	}

	/**
	 * 税邦云发送绑卡验证码
	 *
	 * @param userSignCertDTO
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public R<?> bindCardVerification(UserSignCertDTO userSignCertDTO) {
		// 查询user
		SysUser sysUser = sysUserService.getById(userSignCertDTO.getUserId());
		// 查询userSub
		SysUserSub userSub = sysUserSubService.getOne(Wrappers.<SysUserSub>lambdaQuery()
				.eq(SysUserSub::getUserId, userSignCertDTO.getUserId())
				.eq(SysUserSub::getDeptId, sysUser.getDeptId())
				.eq(SysUserSub::getSubjectLocation, SubjectLocation.LUO_SHU_YUN));
		if (userSub == null) {
			return R.failed("用户sub数据不存在");
		}

		// 查询dept
		SysDept dept = sysDeptService.getById(sysUser.getDeptId());

		// 发送绑卡验证码
		Map<String, Object> params = new HashMap<>();
		params.put("enterpriseCode", dept.getTaxCode());
		params.put("subjectLocation", userSub.getSubjectLocation().name());
		params.put("realName", sysUser.getRealname());
		params.put("bankCard", userSignCertDTO.getBankCardNumber());
		params.put("idCard", sysUser.getIdCardNumber());
		params.put("bankPhone", userSignCertDTO.getBankPhone());
		params.put("endType", "CSO");
		params.put("bankCardStep", "CAPTCHA");

		String postResult = HttpUtil.post(upmsConfig.getGigServiceUrl() + GIG_CERT_ACTION_BANK_CARD, JSONUtil.toJsonStr(params));
		log.info("税邦云发送绑卡验证码: req={}, resp={}", JSONUtil.toJsonStr(params), postResult);

		if (JSONUtil.isJsonObj(postResult)) {
			JSONObject jsonResult = JSONUtil.parseObj(postResult);
			if (jsonResult.getInt("code") == 0) {
				JSONObject data = jsonResult.getJSONObject("data");
				if ("2000".equals(data.getStr("code"))) {
					return R.ok();
				}
				return R.failed(data.getStr("message"));
			}
		}

		return R.failed("发送绑卡验证码失败");

//		// 基础信息
//		GigBaseInfoModel baseInfoModel = new GigBaseInfoModel();
//		baseInfoModel.setGigType(userSub.getGigType());
//		baseInfoModel.setGigChannel(userSub.getGigChannel());
//		baseInfoModel.setBankCardOpt("captcha");
//		baseInfoModel.setNotifyUrl(taxNotifyConfig.getNotifyUrl());
//		// 用户信息
//		GigUserInfoModel userInfoModel = new GigUserInfoModel();
//		userInfoModel.setName(sysUser.getRealname());
//		userInfoModel.setUsername(sysUser.getUsername());
//		userInfoModel.setEntCode(dept.getTaxCode());
//		userInfoModel.setIdCard(sysUser.getIdCardNumber());
//		userInfoModel.setBankPhone(userSignCertDTO.getBankPhone());
//		userInfoModel.setBankCard(userSignCertDTO.getBankCardNumber());
//
//		GigInfoModel infoModel = new GigInfoModel();
//		infoModel.setBaseInfo(baseInfoModel);
//		infoModel.setUserInfo(userInfoModel);
//		BaseMap gigInfo = new BaseMap();
//		gigInfo.put(userSub.getGigType().name(), infoModel);
//		// 发送mq
//		rabbitMqClient.sendMessage(MqConstants.DIRECT_MODE_GIG_BANK_CARD_QUEUE, JSONUtil.toJsonStr(gigInfo));

	}

	/**
	 * 绑卡确认
	 *
	 * @param userSignCertDTO
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public R<Object> bindCardConfirm(UserSignCertDTO userSignCertDTO) {

		// 查询user
		SysUser sysUser = sysUserService.getById(userSignCertDTO.getUserId());
		// 查询userSub
		SysUserSub userSub = sysUserSubService.getOne(Wrappers.<SysUserSub>lambdaQuery()
				.eq(SysUserSub::getUserId, userSignCertDTO.getUserId())
				.eq(SysUserSub::getDeptId, sysUser.getDeptId())
				.eq(SysUserSub::getSubjectLocation, SubjectLocation.LUO_SHU_YUN));
		if (userSub == null) {
			return R.failed("用户sub数据不存在");
		}

		// 查询dept
		SysDept dept = sysDeptService.getById(sysUser.getDeptId());

		// 税邦云中金绑卡操作
		Map<String, Object> params = new HashMap<>();
		params.put("enterpriseCode", dept.getTaxCode());
		params.put("subjectLocation", userSub.getSubjectLocation().name());
		params.put("realName", sysUser.getRealname());
		params.put("bankCard", userSignCertDTO.getBankCardNumber());
		params.put("idCard", sysUser.getIdCardNumber());
		params.put("endType", "CSO");
		params.put("bankCardStep", "BOUND");
		params.put("captcha", userSignCertDTO.getVerifyCode());

		String postResult = HttpUtil.post(upmsConfig.getGigServiceUrl() + GIG_CERT_ACTION_BANK_CARD, JSONUtil.toJsonStr(params));
		log.info("税邦云中金绑卡操作: req={}, resp={}", JSONUtil.toJsonStr(params), postResult);

		if (JSONUtil.isJsonObj(postResult)) {
			JSONObject jsonResult = JSONUtil.parseObj(postResult);
			if (jsonResult.getInt("code") == 0) {
				JSONObject data = jsonResult.getJSONObject("data");
				if ("2000".equals(data.getStr("code"))) {
					// 保存手机号和银行卡号
					SysUser updateUser = new SysUser();
					updateUser.setUserId(sysUser.getUserId());
					updateUser.setBankPhone(userSignCertDTO.getBankPhone());
					updateUser.setBankCardNumber(userSignCertDTO.getBankCardNumber());
					updateUser.setUpdateTime(LocalDateTime.now());
					sysUserService.updateById(updateUser);

					return R.ok();
				}
				return R.failed(data.getStr("message"));
			}
		}

		return R.failed("发送绑卡验证码失败");

//		List<SysUserSub> userSubList = sysUserSubService.list(Wrappers.<SysUserSub>lambdaQuery()
//				.eq(SysUserSub::getUserId, userSignCertDTO.getUserId())
//				.in(SysUserSub::getGigType, userSignCertDTO.getGigTypeList()));
//		if (CollUtil.isEmpty(userSubList)) {
//			throw new RuntimeException("数据异常");
//		}
//		BaseMap gigInfo = new BaseMap();
//		userSubList.stream()
//				// 人力家暂过滤掉
//				.filter(sysUserSub -> !GigTypeEnum.REN_LI_JIA.equals(sysUserSub.getGigType()))
//				.forEach(userSub -> {
//					// 新银行卡号缓存到redis
//					String cacheKey = String.format("%s_%s_%s", CacheConstants.BIND_CARD_CONFIRM_NEW_BANK_CARD, userSub.getUserId(), userSub.getGigType().name());
//					redisTemplate.opsForValue().set(cacheKey, userSignCertDTO);
//
//					// 查询user
//					SysUser sysUser = sysUserService.getById(userSignCertDTO.getUserId());
//					// 查询dept
//					SysDept dept = sysDeptService.getById(sysUser.getDeptId());
//					// 封装请求数据
//					if (GigTypeEnum.TAX_HELPOR.equals(userSub.getGigType())) {
//						userSub.setBankPhone(userSignCertDTO.getBankPhone());
//						userSub.setBankCardNumber(userSignCertDTO.getBankCardNumber());
//						gigInfo.put(userSub.getGigType().name(),
//								this.buildTaxHelperBindCardConfirmModel(sysUser, userSub, dept.getTaxCode(), userSignCertDTO.getBankCardNumber(), userSignCertDTO.getVerifyCode()));
//					} else if (GigTypeEnum.YEE.equals(userSub.getGigType())) {
//						gigInfo.put(userSub.getGigType().name(),
//								this.buildYeeBindCardConfirmModel(sysUser, userSub, dept.getTaxCode(), userSignCertDTO.getBankCardNumber()));
//					} else if (GigTypeEnum.OLADING.equals(userSub.getGigType())) {
//						gigInfo.put(userSub.getGigType().name(),
//								this.buildOladingBindCardConfirmModel(sysUser, userSub, dept.getTaxCode(), userSignCertDTO.getBankCardNumber()));
//					}
//					// 更新为进行中状态
//					SysUserSub updateUserSub = new SysUserSub();
//					updateUserSub.setId(userSub.getId());
//					updateUserSub.setCallbackStatus(GigCallBackStatus.IN_PROGRESS);
//					updateUserSub.setUpdateTime(LocalDateTime.now());
//					updateUserSub.setUpdateUser(0);
//					sysUserSubService.updateById(updateUserSub);
//				});
//
//		if (CollUtil.isNotEmpty(gigInfo)) {
//			// 发送mq
//			rabbitMqClient.sendMessage(MqConstants.DIRECT_MODE_GIG_BANK_CARD_QUEUE, JSONUtil.toJsonStr(gigInfo));
//		}
	}

	/**
	 * 封装税邦云绑卡model
	 *
	 * @param sysUser
	 * @param userSub
	 * @param taxCode
	 * @param newBankCard
	 * @param verifyCode
	 * @return
	 */
	private GigInfoModel buildTaxHelperBindCardConfirmModel(SysUser sysUser, SysUserSub userSub, String taxCode, String newBankCard, String verifyCode) {
		// 基础信息
		GigBaseInfoModel baseInfoModel = new GigBaseInfoModel();
		baseInfoModel.setGigType(userSub.getGigType());
		baseInfoModel.setGigChannel(userSub.getGigChannel());
		baseInfoModel.setCaptcha(verifyCode);
		baseInfoModel.setNotifyUrl(taxNotifyConfig.getNotifyUrl());
		// 用户信息
		GigUserInfoModel userInfoModel = new GigUserInfoModel();
		userInfoModel.setName(sysUser.getRealname());
		userInfoModel.setUsername(sysUser.getUsername());
		userInfoModel.setEntCode(taxCode);
		userInfoModel.setIdCard(sysUser.getIdCardNumber());
		userInfoModel.setBankPhone(userSub.getBankPhone());
		userInfoModel.setBankCard(userSub.getBankCardNumber());
		userInfoModel.setNewBankCard(newBankCard);
		userInfoModel.setAddress("北京市-房山区-长阳镇");

		GigInfoModel infoModel = new GigInfoModel();
		infoModel.setBaseInfo(baseInfoModel);
		infoModel.setUserInfo(userInfoModel);

		return infoModel;
	}

	/**
	 * 封装易联换绑model
	 *
	 * @param sysUser
	 * @param userSub
	 * @param taxCode
	 * @param newBankCard
	 * @return
	 */
	private GigInfoModel buildYeeBindCardConfirmModel(SysUser sysUser, SysUserSub userSub, String taxCode, String newBankCard) {
		// 基础信息
		GigBaseInfoModel baseInfoModel = new GigBaseInfoModel();
		baseInfoModel.setGigChannel(userSub.getGigChannel());
		baseInfoModel.setGigType(userSub.getGigType());
		// 用户信息
		GigUserInfoModel userInfoModel = new GigUserInfoModel();
		userInfoModel.setName(sysUser.getRealname());
		userInfoModel.setUsername(sysUser.getUsername());
		userInfoModel.setEntCode(taxCode);
		userInfoModel.setIdCard(sysUser.getIdCardNumber());
		userInfoModel.setBankPhone(userSub.getBankPhone());
		userInfoModel.setBankCard(userSub.getBankCardNumber());
		userInfoModel.setNewBankCard(newBankCard);
		userInfoModel.setAddress("北京市-房山区-长阳镇");

		GigInfoModel infoModel = new GigInfoModel();
		infoModel.setBaseInfo(baseInfoModel);
		infoModel.setUserInfo(userInfoModel);

		return infoModel;
	}

	/**
	 * 封装自由职家换绑model
	 *
	 * @param sysUser
	 * @param userSub
	 * @param taxCode
	 * @param newBankCard
	 * @return
	 */
	private GigInfoModel buildOladingBindCardConfirmModel(SysUser sysUser, SysUserSub userSub, String taxCode, String newBankCard) {
		// 基础信息
		GigBaseInfoModel baseInfoModel = new GigBaseInfoModel();
		baseInfoModel.setGigChannel(userSub.getGigChannel());
		baseInfoModel.setGigType(userSub.getGigType());
		// 用户信息
		GigUserInfoModel userInfoModel = new GigUserInfoModel();
		userInfoModel.setName(sysUser.getRealname());
		userInfoModel.setUsername(sysUser.getUsername());
		userInfoModel.setEntCode(taxCode);
		userInfoModel.setIdCard(sysUser.getIdCardNumber());
		userInfoModel.setBankPhone(userSub.getBankPhone());
		userInfoModel.setBankCard(userSub.getBankCardNumber());
		userInfoModel.setNewBankCard(newBankCard);
		userInfoModel.setAddress("北京市-房山区-长阳镇"); // TODO

		GigInfoModel infoModel = new GigInfoModel();
		infoModel.setBaseInfo(baseInfoModel);
		infoModel.setUserInfo(userInfoModel);

		return infoModel;
	}
}
