package com.cyksj.service.gzh.factory;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
import com.cyksj.common.util.Codec;
import com.cyksj.common.util.Jsons;
import com.cyksj.common.util.StringUtil;
import com.cyksj.config.WeChatConfig;
import com.cyksj.dto.UserSharedDto;
import com.cyksj.mapper.GoodsDonSkuMapper;
import com.cyksj.mapper.NanoUserQuotaMapper;
import com.cyksj.mapper.UserMapper;
import com.cyksj.mapper.WxAppMapper;
import com.cyksj.mapper.claudecode.ClaudeCodeUserTrialReceiveRecordMapper;
import com.cyksj.mapper.gzh.UserGzhRelationMapper;
import com.cyksj.mapper.manage.coupon.CouponDistributePopularizeMapper;
import com.cyksj.mapper.manage.coupon.CouponRecommendMapper;
import com.cyksj.mapper.manage.cps.UserDistributePopularizeMapper;
import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
import com.cyksj.mapper.nano.NanoUserTrialReceiveRecordMapper;
import com.cyksj.mapper.station.CollegeStudentStationUserRelateMapper;
import com.cyksj.model.dto.*;
import com.cyksj.model.entity.*;
import com.cyksj.redis.RedisService;
import com.cyksj.service.claude.ClaudeCodeService;
import com.cyksj.service.distribute.DistributeService;
import com.cyksj.service.distribute.equipment.EquipmentDistributeService;
import com.cyksj.service.mange.coupon.CouponCommonService;
import com.cyksj.service.market.task.BindTaskService;
import com.cyksj.service.relation.GroupRelationFrontService;
import com.cyksj.service.shop.YhShopDistributeService;
import com.cyksj.service.user.UserLoginRecordService;
import com.cyksj.service.user.UserService;
import com.cyksj.service.wechat.WeChatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.Optional;

/*
 *项目名: netflix
 *文件名: EventMsgService
 *创建者: JavaZou
 *创建时间:2023/1/13 18:16
 */
@Service("event")
@RequiredArgsConstructor
@Slf4j
public class EventMsgService implements GzhMsgService {
	private final UserMapper userMapper;

	private final UserGzhRelationMapper userGzhRelationMapper;

	private final WeChatService weChatService;

	private final WxAppMapper wxAppMapper;

	private final RedisService redisService;

	private final DistributeService distributeService;

	private final EquipmentDistributeService equipDistributeService;

	private final UserService userService;

	private final WeChatConfig weChatConfig;

	private final UserDistributePopularizeMapper distributePopularizeMapper;

	private final BindTaskService bindTaskService;

	private final UserLoginRecordService userLoginRecordService;

	private final CollegeStudentStationUserRelateMapper collegeStudentStationUserRelateMapper;

	private final GroupRelationFrontService groupRelationFrontService;

	private final YhShopDistributeService yhShopDistributeService;

	private final UserDistributeMapper userDistributeMapper;

	private final CouponDistributePopularizeMapper couponDistributePopularizeMapper;

	private final CouponRecommendMapper couponRecommendMapper;

	private final CouponCommonService couponCommonService;

	private final ClaudeCodeService claudeCodeService;

	private final ClaudeCodeUserTrialReceiveRecordMapper claudeCodeUserTrialReceiveRecordMapper;

	private final NanoUserTrialReceiveRecordMapper nanoUserTrialReceiveRecordMapper;

	private final NanoUserQuotaMapper nanoUserQuotaMapper;

	private final GoodsDonSkuMapper goodsDonSkuMapper;

	private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();

	@Override
	public String handleNotify(MsgEvent msgEvent) {
		try {
			if (msgEvent.getEvent() == MsgEvent.Event.subscribe) {
				String eventKey = msgEvent.getEventKey();
				if (StrUtil.isNotEmpty(eventKey) && eventKey.contains("qrscene")) {
					msgEvent.setEventKey(eventKey.substring(eventKey.indexOf("qrscene_") + 8));
				}
				if (!saveOrGetUser(msgEvent)) {
					return "";
				}
			} else if (msgEvent.getEvent() == MsgEvent.Event.unsubscribe) {
				UserGzhRelation userGzhRelation = userGzhRelationMapper.selectOne(Wrappers.lambdaQuery(UserGzhRelation.class)
						.eq(UserGzhRelation::getOpenId, msgEvent.getFromUserName()).last("limit 1"));
				if (userGzhRelation == null) {
					return "";
				}
				userGzhRelation.setIsSubscribe(false);
				userGzhRelationMapper.updateById(userGzhRelation);
			} else if (msgEvent.getEvent() == MsgEvent.Event.SCAN) {
				if (!saveOrGetUser(msgEvent)) {
					return "";
				}
			}
			return "";
		} catch (Exception e) {
			log.error("接收微信公众:{},报错:{}", msgEvent.getToUserName(), e == null ? "" : e.getMessage());
			return "";
		}
	}

	public Boolean saveOrGetUser(MsgEvent msgEvent) throws Exception {
		//扫描带参数二维码 场景值
		String sceneKey = msgEvent.getEventKey();

		String openId = msgEvent.getFromUserName();
		if (StrUtil.isEmpty(openId)) {
			return false;
		}
		//迁移公众号之后同步授权后信息
		//是否是迁移用户
//		WxSyncLog wxSyncLog = wxSyncLogMapper.selectOne(Wrappers.lambdaQuery(WxSyncLog.class)
//				.eq(WxSyncLog::getToAppid, weChatConfig.getAppid())
//				.eq(WxSyncLog::getNewOpenid, openId).last("limit 1"));

		WxApp wxApp = wxAppMapper.selectOne(Wrappers.lambdaQuery(WxApp.class)
				.eq(WxApp::getGzhOriginalId, msgEvent.getToUserName()).last("limit 1"));
		if (wxApp == null) {
			return false;
		}
		GzhUnionidUserinfo info = weChatService.getUserInfo2(weChatService.getAccessToken(wxApp.getAppId()), openId);
		User user = userService.getSyncUser(info.getOpenid(), info.getUnionid(), null);

		String state = redisService.getStr(RedisService.key.WX_GZH_QRCODE_SHARED_LOGIN.getNameFormat(sceneKey));
		GzhBodyDto gzhDto = null;
		if (StrUtil.isNotEmpty(state)) {
			// 转跳参数
			String json = Codec.DoBase64.custom().setData(state).decodeAsText();
			if (StrUtil.isNotEmpty(json)) {
				try {
					gzhDto = Jsons.parseObject(json, GzhBodyDto.class);
				} catch (Exception e) {
				}
			}
		}
		Boolean isNewUser = false;
		if (user == null) {
			isNewUser = true;
			user = new User();
			user.setNickname(String.format("%s%s", Constant.DEFAULT_NAME, Codec.DoDigest.custom().setAlgorithm(Codec.DoDigest.Algorithm.MD5).setStringData(RandomUtil.randomString(10)).toHexString().substring(0, 6)))
					.setSex(info.getSex())
					.setCountry(info.getCountry())
					.setProvince(info.getProvince())
					.setCity(info.getCity())
					.setHeadimgurl(Constant.DEFAULT_HEAD_IMG);
			user.setOpenId(openId);
			user.setUnionid(info.getUnionid());
			//重复插入
			if (!redisService.setNx(RedisService.key.REPEAT_USER_KEY.getNameFormat(user.getUnionid()), user.getUnionid(), RedisService.key.REPEAT_USER_KEY.getTimeout())) {
				return false;
			}
			//pc网页扫码
			user.setRegisterEnv(User.RegisterEnv.pc.name());
			userMapper.insert(user);
			Long userId = user.getId();
			Long dsPopularizeId = null;
			Boolean cgTj = null;
			if (gzhDto != null) {
				Long sharedId = gzhDto.getSharedId();
				String dsCode = gzhDto.getDsCode();
				//是否是cc普通推广
				cgTj = gzhDto.getCgTj();
				if (StrUtil.isNotBlank(dsCode)) {
					dsCode = dsCode.trim();
					User sharedUser = userService.getOne(Wrappers.lambdaQuery(User.class)
							.eq(User::getShowId, dsCode).last("limit 1"));
					if (sharedUser != null) {
						sharedId = sharedUser.getId();
					} else {
						UserDistributePopularize distributePopularize = distributePopularizeMapper.selectOne(Wrappers.lambdaQuery(UserDistributePopularize.class)
								.eq(UserDistributePopularize::getCode, dsCode)
								.select(UserDistributePopularize::getUserId, UserDistributePopularize::getId).last("limit 1"));
						if (distributePopularize != null) {
							log.info("渠道sharedId:{}设置固定推广链接PC扫码用户分销", distributePopularize.getUserId());
							sharedId = distributePopularize.getUserId();
							dsPopularizeId = distributePopularize.getId();
						}
					}
				}
				if (sharedId != null) {
					distributeService.saveDistributionInvitation(sharedId, user.getId(), dsPopularizeId, cgTj);
				}
				Long popularizeId = gzhDto.getPid();
				if (popularizeId != null) {
					userMapper.update(null, Wrappers.lambdaUpdate(User.class)
							.eq(User::getId, user.getId())
							.set(User::getPopularizeId, popularizeId));
					TASK_POOL.execute(() -> {
						userService.sendFixedCustomerCoupon(popularizeId, userId, info.getUnionid());
					});
				}
				userBind(user, sceneKey, gzhDto.getLoginPhone(), gzhDto.getLoginEmail());

				String callback = gzhDto.getCk();
				String callbackType = gzhDto.getCt();
				//缓存用户注册 回传信息
				if (StrUtil.isNotBlank(callback)) {
					OrderDonPostDataDto orderDonPostDataDto = new OrderDonPostDataDto().setCallback(callback)
							.setCallbackType(callbackType);
					redisService.set(RedisService.key.ORDER_DON_POST_DATA_USER_KEY.getName() + user.getId(), Jsons.toJson(orderDonPostDataDto));
				}

				String customId = gzhDto.getCd();
				//店铺注册用户 关联
				if (isNewUser && StrUtil.isNotBlank(customId)) {
					yhShopDistributeService.saveDistributionInvitation(customId, user.getId(), gzhDto.getCmt());
				}
			}

			saveGzhUserRelation(msgEvent, user.getId(), openId, info.getUnionid(), sceneKey, wxApp.getId());
		} else {
			//之前关注过
			if (user.getUnionid() == null || !user.getUnionid().equals(info.getUnionid())) {
				user.setUnionid(info.getUnionid());
				userMapper.updateById(user);
			}
			saveGzhUserRelation(msgEvent, user.getId(), openId, info.getUnionid(), sceneKey, wxApp.getId());
			if (gzhDto != null) {
				userBind(user, sceneKey, gzhDto.getLoginPhone(), gzhDto.getLoginEmail());
			}
		}
		//场景值扫描公众号二维码 登录
		if (StrUtil.isNotEmpty(sceneKey)) {
			WxUserSceneDto wxUserSceneDto = new WxUserSceneDto(user.getId(), openId);
			redisService.set(RedisService.key.WX_GZH_QRCODE_LOGIN.getNameFormat(sceneKey), Jsons.toJson(wxUserSceneDto), RedisService.key.WX_GZH_QRCODE_LOGIN.getTimeout());
		}
		if (gzhDto != null) {
			Long sharedId = gzhDto.getSharedId();
			Integer dsType = gzhDto.getDsType();
			String dsCode = gzhDto.getDsCode();
			Long dsPopularizeId = null;
			Boolean cgTj = gzhDto.getCgTj();
			if (StrUtil.isNotBlank(dsCode)) {
				UserSharedDto userSharedDto = getUserShredDtoByDsCode(dsCode);
				sharedId = userSharedDto.getSharedId();
				dsPopularizeId = userSharedDto.getDsPopularizeId();
			}
			//新旧用户都可实物分销
			if (dsType != null && dsType == 2) {
				equipDistributeService.saveDistributionInvitation(sharedId, isNewUser, user.getId());
			}
			//新用户推广
			if (sharedId != null && isNewUser) {
				if (dsType == null || dsType == 1) {
					distributeService.saveDistributionInvitation(sharedId, user.getId(), dsPopularizeId, cgTj);
				}
			}
			//查找渠道是否有设置了对应的claude code优惠码
			handlerSpecialPopularize(sharedId, dsPopularizeId, user, isNewUser, gzhDto.getIsNano());
			//每日活跃记录
			userLoginRecordService.saveUserLoginDayRecord(user.getId());
			//是否是大学生快递站进来的用户
			Integer cst = gzhDto.getCst();
			Long userId = user.getId();
			if (cst != null) {
				TASK_POOL.execute(() -> {
					handlerCollegeStudentUser(userId, cst);
				});
			}
		}
		return true;
	}

	private void saveGzhUserRelation(MsgEvent msgEvent, Long userId, String openId, String unionid, String sceneKey, Long wxAppId) {
		UserGzhRelation userGzhRelation = userGzhRelationMapper.selectOne(Wrappers.lambdaQuery(UserGzhRelation.class)
				.eq(UserGzhRelation::getWxAppId, wxAppId)
				.eq(UserGzhRelation::getOpenId, msgEvent.getFromUserName()).last("limit 1"));
		userGzhRelation = Optional.ofNullable(userGzhRelation).orElseGet(() -> new UserGzhRelation());

		userGzhRelation.setUserId(userId);
		userGzhRelation.setWxAppId(wxAppId);
		userGzhRelation.setIsSubscribe(true);
		userGzhRelation.setEvent(msgEvent.getEvent());
		userGzhRelation.setOpenId(openId);
		userGzhRelation.setUnionid(unionid);
		if (StrUtil.isNotEmpty(msgEvent.getEventKey())) {
			userGzhRelation.setIsQrScene(true);
		}
		try {
			if (userGzhRelation.getId() == null) {
				//记录首次关注公众号的场景值
				userGzhRelation.setSceneKey(sceneKey);
				userGzhRelationMapper.insert(userGzhRelation);
				return;
			}
			userGzhRelationMapper.updateById(userGzhRelation);
		} catch (DuplicateKeyException e) {

		}
	}

	public void userBind(User user, String sceneKey, String loginPhone, String loginEmail) {
		if (StrUtil.isNotBlank(loginPhone)) {
			log.info("手机号phone:{}登录用户,微信扫描公众号二维码进行用户信息绑定", loginPhone);
			try {
				bindTaskService.bindPhone(user, loginPhone, null);
				redisService.set(RedisService.key.WX_GZH_QRCODE_BIND.getNameFormat(sceneKey), user.getId(), RedisService.key.WX_GZH_QRCODE_BIND.getTimeout());
			} catch (Exception e) {
				log.info(StringUtil.getErrorText(e));
			}
		}

		if (StrUtil.isNotBlank(loginEmail)) {
			log.info("邮箱email:{}登录用户,微信扫描公众号二维码进行用户信息绑定", loginEmail);
			try {
				bindTaskService.bindEmail(user, loginEmail, null);
				redisService.set(RedisService.key.WX_GZH_QRCODE_BIND.getNameFormat(sceneKey), user.getId(), RedisService.key.WX_GZH_QRCODE_BIND.getTimeout());
			} catch (Exception e) {
				log.info(StringUtil.getErrorText(e));
			}
		}
	}

	public UserSharedDto getUserShredDtoByDsCode(String dsCode) {
		Long sharedId = 0l;
		Long dsPopularizeId = 0l;
		dsCode = dsCode.trim();
		User sharedUser = userMapper.selectOne(Wrappers.lambdaQuery(User.class)
				.eq(User::getShowId, dsCode).last("limit 1"));
		if (sharedUser != null) {
			sharedId = sharedUser.getId();
		} else {
			UserDistributePopularize distributePopularize = distributePopularizeMapper.selectOne(Wrappers.lambdaQuery(UserDistributePopularize.class)
					.eq(UserDistributePopularize::getCode, dsCode)
					.select(UserDistributePopularize::getUserId, UserDistributePopularize::getId).last("limit 1"));
			if (distributePopularize != null) {
				log.info("渠道sharedId:{}设置固定推广链接用户分销", distributePopularize.getUserId());
				sharedId = distributePopularize.getUserId();
				dsPopularizeId = distributePopularize.getId();
			}
		}
		UserSharedDto sharedDto = new UserSharedDto();
		sharedDto.setSharedId(sharedId);
		sharedDto.setDsPopularizeId(dsPopularizeId);
		return sharedDto;
	}

	/**
	 * 处理大学生快递站用户
	 */
	public void handlerCollegeStudentUser(Long userId, Integer cst) {
		try {
			CollegeStudentStationUserRelate cstRelate = new CollegeStudentStationUserRelate();
			cstRelate.setType(cst);
			cstRelate.setUserId(userId);
			collegeStudentStationUserRelateMapper.insert(cstRelate);

			//赠送1天的GPT镜像车票
			groupRelationFrontService.getCollegeStudentUserGptTicket(userId);
		} catch (DuplicateKeyException e) {
		}
	}

	/**
	 * 查找渠道是否有设置了对应的claude code优惠码
	 */
	public void handlerSpecialPopularize(Long sharedId, Long dsPopularizeId, User user, Boolean isNewUser, Boolean isNano) {
		if (!isNewUser) {
			return;
		}
		String email = user.getEmail();
		if (StrUtil.isNotBlank(email)) {
			//包含+号
			if (email.contains("+")) {
				return;
			}
			Long count = email.chars().filter(c -> c == '.').count();
			//邮箱超过3个'.'字符用户过滤
			if (count > 3) {
				return;
			}
		}
		//查找渠道是否有设置了对应的claude code优惠码
		if (sharedId != null) {
			UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, sharedId).eq(UserDistribute::getDeleted, Boolean.TRUE).last("limit 1"));
			if (userDistribute != null) {
				if (dsPopularizeId == null) {
					return;
				}
				UserDistributePopularize userDistributePopularize = distributePopularizeMapper.selectById(dsPopularizeId);
				if (userDistributePopularize == null) {
					return;
				}
				//是否是cc推广
				if (Constant.CC_DISTRIBUTE_MARK.equals(userDistributePopularize.getOtherUrl())) {
					Integer selectCount = couponDistributePopularizeMapper.selectCount(Wrappers.lambdaQuery(CouponDistributePopularize.class).eq(CouponDistributePopularize::getDistributeId, userDistribute.getId()).eq(CouponDistributePopularize::getDeleted, Boolean.TRUE).eq(CouponDistributePopularize::getCouponId, Constant.DISTRIBUTE_CLAUDE_CODE_COUPON_ID));
					//是否设置claude cod优惠券
					if (selectCount > 0) {
						//设置了 直接发送优惠券
						Boolean b = couponCommonService.sendCouponToUser(user.getId(), Constant.DISTRIBUTE_CLAUDE_CODE_COUPON_ID, 0l, 0l, dsPopularizeId, CouponUser.Channel.manual);
						if (!b) {
							return;
						}
						if (redisService.setNx(RedisService.key.CLAUDE_CODE_TY_DAY_CARD_KEY.getName() + user.getId(), user.getId(), RedisService.key.CLAUDE_CODE_TY_DAY_CARD_KEY.getTimeout())) {
							//存在Claude code车票不发送体验卡
							if (!claudeCodeService.checkClaudeCodeUser(user.getId())) {
								Integer receiveRecord = claudeCodeUserTrialReceiveRecordMapper.selectCount(Wrappers.lambdaQuery(ClaudeCodeUserTrialReceiveRecord.class).eq(ClaudeCodeUserTrialReceiveRecord::getUserId, user.getId()));
								if (receiveRecord > 0) {
									return;
								}
								//发送claude code 体验卡
								Long relationId = groupRelationFrontService.getTrialTicketByUserIdAndGoodsId(user.getId(), Constant.DISTRIBUTE_CLAUDE_CODE_TRIAL_SKU_ID, 1);
								recordReceiveClaudeCodeRecord(user.getId(), relationId);
							}
						}
					} else {
						//该优惠券是否处于推荐中
						int isTj = couponRecommendMapper.checkPresentRecommendByCouponId(Constant.DISTRIBUTE_CLAUDE_CODE_NO_CODE_COUPON_ID);
						if (isTj != 0) {
							//发送无优惠码的 优惠券
							couponCommonService.sendCouponToUser(user.getId(), Constant.DISTRIBUTE_CLAUDE_CODE_NO_CODE_COUPON_ID, 0l, 0l, dsPopularizeId, CouponUser.Channel.manual);
						}
					}
				}

				//是否是nano 推广
				if (Constant.NANO_DISTRIBUTE_MARK.equals(userDistributePopularize.getOtherUrl())) {
					Integer selectCount = couponDistributePopularizeMapper.selectCount(Wrappers.lambdaQuery(CouponDistributePopularize.class).eq(CouponDistributePopularize::getDistributeId, userDistribute.getId()).eq(CouponDistributePopularize::getDeleted, Boolean.TRUE).eq(CouponDistributePopularize::getCouponId, Constant.DISTRIBUTE_NANO_COUPON_ID));
					if (selectCount > 0) {
						//设置了 直接发送优惠券
						couponCommonService.sendCouponToUser(user.getId(), Constant.DISTRIBUTE_NANO_COUPON_ID, 0l, 0l, dsPopularizeId, CouponUser.Channel.manual);
					}
				}
			}
		}
		//新用户都送体验卡
		if (isNano != null && isNano) {
			if (redisService.setNx(RedisService.key.NANO_TY_DAY_CARD_KEY.getName() + user.getId(), user.getId(), RedisService.key.NANO_TY_DAY_CARD_KEY.getTimeout())) {
				Integer receiveRecord = nanoUserTrialReceiveRecordMapper.selectCount(Wrappers.lambdaQuery(NanoUserTrialReceiveRecord.class).eq(NanoUserTrialReceiveRecord::getUserId, user.getId()));
				if (receiveRecord > 0) {
					return;
				}
				//发送nano 体验卡
				Long relationId = groupRelationFrontService.getTrialTicketByUserIdAndGoodsId(user.getId(), Constant.DISTRIBUTE_NANO_TRIAL_SKU_ID, 2);
				recordReceiveNanoRecord(user.getId(), relationId);
				//创建nano user
				createNanoUser(user.getId(), relationId, goodsDonSkuMapper.selectById(Constant.DISTRIBUTE_NANO_TRIAL_SKU_ID));
			}
		}
	}

	public void recordReceiveClaudeCodeRecord(Long userId,Long relationId) {
		if (relationId != null) {
			ClaudeCodeUserTrialReceiveRecord record = new ClaudeCodeUserTrialReceiveRecord();
			record.setUserId(userId);
			record.setRelationId(relationId);
			claudeCodeUserTrialReceiveRecordMapper.insert(record);
		}
	}

	private void recordReceiveNanoRecord(Long userId, Long relationId) {
		if (relationId != null) {
			NanoUserTrialReceiveRecord record = new NanoUserTrialReceiveRecord();
			record.setUserId(userId);
			record.setRelationId(relationId);
			nanoUserTrialReceiveRecordMapper.insert(record);
		}
	}

	private void createNanoUser(Long userId, Long relationId, GoodsDonSku sku) {
		try {
			if (relationId == null) {
				return;
			}
			User user = userMapper.selectById(userId);
			NanoUserQuota nanoUserQuota = new NanoUserQuota();
			nanoUserQuota.setUid(userId);
			nanoUserQuota.setRelationId(relationId);
			nanoUserQuota.setUserToken(UUID.randomUUID().toString());
			nanoUserQuota.setNickname(user.getNickname());
			nanoUserQuota.setAvatar(user.getHeadimgurl());
			nanoUserQuota.setPurchaseDate(DateTime.now());
			nanoUserQuota.setTotalQuota(sku.getNanoQuota());
			nanoUserQuota.setRemainingQuota(nanoUserQuota.getTotalQuota());
			nanoUserQuotaMapper.insert(nanoUserQuota);
		} catch (DuplicateKeyException e) {

		}
	}
}
