package com.cyksj.service.user.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.EnvCommonService;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.snowflake.Sequence;
import com.cyksj.common.util.Jsons;
import com.cyksj.common.util.StringUtil;
import com.cyksj.mapper.UserCertRecordMapper;
import com.cyksj.mapper.UserMapper;
import com.cyksj.mapper.UserStudentCertRecordMapper;
import com.cyksj.model.dto.UserWxIndentDto;
import com.cyksj.model.entity.User;
import com.cyksj.model.entity.UserCertRecord;
import com.cyksj.model.entity.UserStudentCertRecord;
import com.cyksj.model.request.UserIndentCertReq;
import com.cyksj.model.response.WxCertAuthTokenResp;
import com.cyksj.redis.RedisService;
import com.cyksj.service.user.UserBindRelationService;
import com.cyksj.service.user.UserIdentCertService;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.faceid.v20180301.FaceidClient;
import com.tencentcloudapi.faceid.v20180301.models.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 项目名: yhlxj2
 * 文件名: UserIdentCertServiceImpl
 * 创建者: JavaZou
 * 创建时间:2024/2/21 10:21
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserIdentCertServiceImpl implements UserIdentCertService {
	private final UserBindRelationService userBindRelationService;

	private final UserCertRecordMapper userCertRecordMapper;

	private final UserStudentCertRecordMapper userStudentCertRecordMapper;

	private final UserMapper userMapper;

	private final RedisService redisService;

	private final EnvCommonService envCommonService;

	private final static Sequence SEQUENCE = new Sequence(0);

	private static final String TENCENT_SECRET_ID = "AKIDBB3jEqR0Y95zpfTix1vd6fMqAIahc4Ka";

	private static final String TENCENT_SECRET_KEY = "c6YtNm63rcQ1QdiGmEbmEPSTPF3e4KQK";

	private static final String ruleId = "1";

	private static final String REDIRECT_URL = "applets/user/cert/auth/result/";

	@Override
	public Boolean checkCertRecord(long userId) {
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		Integer count = userCertRecordMapper.selectCount(Wrappers.lambdaQuery(UserCertRecord.class)
				.in(UserCertRecord::getUserId, userIdList));
		return count > 0 ? true : false;
	}

	@Override
	public UserCertRecord getUserCertRecord(long userId, String mappingId) throws Exception {
		if (StrUtil.isNotEmpty(mappingId)) {
			//实名认证结果查询
			String redirectParams = redisService.getStr(mappingId);
			if (StrUtil.isNotBlank(redirectParams)) {
				UserWxIndentDto userWxIndentDto = Jsons.parseObject(redirectParams, UserWxIndentDto.class);
				try {
					wxH5IndentCertResult(userWxIndentDto);
				} catch (Exception e) {

				}
			}
		}
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		UserCertRecord record = userCertRecordMapper.selectOne(Wrappers.lambdaQuery(UserCertRecord.class)
				.in(UserCertRecord::getUserId, userIdList)
				.select(UserCertRecord::getName, UserCertRecord::getIdent, UserCertRecord::getCreatedTime)
				.last("limit 1"));
		if (record == null) {
			return null;
		}
		record.setIdent(StringUtil.enIndent(record.getIdent()));
		return record;
	}

	@Override
	public UserStudentCertRecord getUserStudentCertRecord(long userId) {
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		UserStudentCertRecord record = userStudentCertRecordMapper.selectOne(Wrappers.lambdaQuery(UserStudentCertRecord.class)
				.in(UserStudentCertRecord::getUserId, userIdList)
				.select(UserStudentCertRecord::getSchool, UserStudentCertRecord::getCreatedTime)
				.last("limit 1"));
		if (record == null) {
			return null;
		}
		return record;
	}

	@Override
	public String bindWxUser(long userId) {
		User user = userMapper.selectById(userId);
		if (StrUtil.isNotBlank(user.getOpenId())) {
			return null;
		}
		String state = StringUtil.randomString(6);
		redisService.set(RedisService.key.WX_INDENT_BIND_KEY.getName() + state, userId, RedisService.key.WX_INDENT_BIND_KEY.getTimeout());
		return state;
	}

	@Override
	public WxCertAuthTokenResp wxH5IndentCert(UserIndentCertReq indentCertReq) throws Exception {
		Long userId = indentCertReq.getUserId();
		String redirectUrl = indentCertReq.getRedirectUrl();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
//		String bindState = indentCertReq.getBindState();
//		if (userIdList.size() == 1 && StrUtil.isNotEmpty(bindState)) {
//			User user = userMapper.selectById(userId);
//			if (StrUtil.isEmpty(user.getOpenId())) {
//				String key = RedisService.key.WX_INDENT_BIND_KEY.getName() + bindState;
//				Object bindInfo = redisService.get(key);
//				if (bindInfo == null) {
//					throw BusinessRuntimeException.getInstance("认证信息已失效，请重新操作..");
//				}
//				Long bindUserId = Long.parseLong(bindInfo.toString());
//				User bindUser = userMapper.selectById(bindUserId);
//				//绑定微信端用户
//				UserBindInfoReq request = new UserBindInfoReq();
//				request.setType(StrUtil.isNotBlank(bindUser.getLoginPhone()) ? 1 : 2);
//				request.setUserId(userId);
//				request.setAccount(request.getType() == 1 ? bindUser.getLoginPhone() : bindUser.getEmail());
//				bindTaskService.bindOtherAccount(request);
//				userIdList = userBindRelationService.getRelationUserIdList(userId, null);
//				redisService.del(key);
//			}
//		}

		Integer count = userCertRecordMapper.selectCount(Wrappers.lambdaQuery(UserCertRecord.class)
				.in(UserCertRecord::getUserId, userIdList));
		if (count > 0) throw BusinessRuntimeException.getInstance("您已完成认证了..");

		Credential cred = new Credential(TENCENT_SECRET_ID, TENCENT_SECRET_KEY);
		// 实例化一个http选项，可选的，没有特殊需求可以跳过
		HttpProfile httpProfile = new HttpProfile();
		httpProfile.setEndpoint("faceid.tencentcloudapi.com");
		// 实例化一个client选项，可选的，没有特殊需求可以跳过
		ClientProfile clientProfile = new ClientProfile();
		clientProfile.setHttpProfile(httpProfile);
		// 实例化要请求产品的client对象,clientProfile是可选的
		FaceidClient client = new FaceidClient(cred, "", clientProfile);
		// 实例化一个请求对象,每个接口都会对应一个request对象
		DetectAuthRequest req = new DetectAuthRequest();
		req.setRuleId(ruleId);
		Long mappingId = SEQUENCE.nextId();
		req.setRedirectUrl(envCommonService.getNotifyHost() + REDIRECT_URL + mappingId);
		// 返回的resp是一个DetectAuthResponse的实例，与请求对象对应
		DetectAuthResponse resp = client.DetectAuth(req);

		log.info("微信h5核身认证,返回:{}", Jsons.toJson(resp));

		WxCertAuthTokenResp tokenResp = new WxCertAuthTokenResp();
		BeanUtil.copyProperties(resp, tokenResp);

		UserWxIndentDto userWxIndentDto = new UserWxIndentDto();
		userWxIndentDto.setUserId(userId);
		userWxIndentDto.setRedirectUrl(redirectUrl);
		userWxIndentDto.setBizToken(tokenResp.getBizToken());
		redisService.set(mappingId.toString(), Jsons.toJson(userWxIndentDto), 60 * 60 * 24L);
		tokenResp.setMappingId(mappingId.toString());
		return tokenResp;
	}

	@Override
	public void wxH5IndentCertResult(UserWxIndentDto userWxIndentDto) throws Exception {
		Long userId = userWxIndentDto.getUserId();
		Credential cred = new Credential(TENCENT_SECRET_ID, TENCENT_SECRET_KEY);
		// 实例化一个http选项，可选的，没有特殊需求可以跳过
		HttpProfile httpProfile = new HttpProfile();
		httpProfile.setEndpoint("faceid.tencentcloudapi.com");
		// 实例化一个client选项，可选的，没有特殊需求可以跳过
		ClientProfile clientProfile = new ClientProfile();
		clientProfile.setHttpProfile(httpProfile);
		// 实例化要请求产品的client对象,clientProfile是可选的
		FaceidClient client = new FaceidClient(cred, "", clientProfile);
		// 实例化一个请求对象,每个接口都会对应一个request对象
		GetDetectInfoEnhancedRequest req = new GetDetectInfoEnhancedRequest();
		req.setBizToken(userWxIndentDto.getBizToken());
		req.setRuleId(ruleId);
		// 返回的resp是一个GetDetectInfoEnhancedResponse的实例，与请求对象对应
		GetDetectInfoEnhancedResponse resp = client.GetDetectInfoEnhanced(req);
		DetectInfoText text = resp.getText();
		if (text.getErrCode() == 0) {
			UserCertRecord certRecord = new UserCertRecord();
			String ocrIdCard = text.getOcrIdCard();
			Integer count = userCertRecordMapper.selectCount(Wrappers.lambdaQuery(UserCertRecord.class)
					.eq(UserCertRecord::getIdent, ocrIdCard));
			if (count > 0) {
				throw BusinessRuntimeException.getInstance("该身份证号已被其他账号绑定");
			}
			if (count == 0) {
				certRecord.setIdent(text.getOcrIdCard());
				certRecord.setName(text.getOcrName());
				certRecord.setSex(text.getOcrGender());
				certRecord.setUserId(userId);
				certRecord.setAddr(text.getOcrAddress());
				userCertRecordMapper.insert(certRecord);
			}
		}
	}
}
