package com.cyksj.service.cps.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.Jsons;
import com.cyksj.common.util.SmsUtil;
import com.cyksj.common.util.StringUtil;
import com.cyksj.mapper.manage.coupon.CouponDistributePopularizeMapper;
import com.cyksj.mapper.manage.coupon.CouponMapper;
import com.cyksj.mapper.manage.distribute.DistributeWaitingSendPointsMapper;
import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
import com.cyksj.mapper.sys.SysConfigMapper;
import com.cyksj.model.entity.*;
import com.cyksj.model.views.BrokenLineCpsUserWMoneyView;
import com.cyksj.model.views.CpsUserWMoneyStatisticsDataView;
import com.cyksj.redis.RedisService;
import com.cyksj.service.cps.CpsManageService;
import com.cyksj.service.mail.MailService;
import com.cyksj.service.user.BadIntentionOpService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/*
 *项目名: netflix
 *文件名: CpsManageServiceImpl
 *创建者: JavaZou
 *创建时间:2023/5/12 11:18
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CpsManageServiceImpl implements CpsManageService {

	private final MailService mailService;

	private final RedisService redisService;

	private final DistributeWaitingSendPointsMapper waitingSendPointsMapper;

	private final UserDistributeMapper userDistributeMapper;

	private final SysConfigMapper sysConfigMapper;

	private final CouponMapper couponMapper;

	private final CouponDistributePopularizeMapper couponDistributePopularizeMapper;

	private final HttpServletRequest request;

	private final BadIntentionOpService badIntentionOpService;

	@Override
	public void getLoginCode(Integer type, String login, Integer cid, String verifyCode, String ticket, String randStr) {
		if (type > 2) {
			throw BusinessRuntimeException.getInstance("");
		}
		if (cid == null) {
			cid = 86;
		}
		//是否是渠道分销用户
		String phone = null;
		String email = null;
		if (type == 1) phone = login;
		else if (type == 2) email = login;
		User user = userDistributeMapper.getUserDistributeDetail(phone, email);
		if (user == null) throw BusinessRuntimeException.getInstance("只支持渠道分销用户登录");
		String CACHE_LOGIN_KEY = RedisService.key.CPS_BACK_LOGIN_KEY.getName() + login;
		Object o = redisService.get(CACHE_LOGIN_KEY);
		Long expire = redisService.getExpire(CACHE_LOGIN_KEY);
		if (o != null && expire >= 3 * 60 - 10) {
			throw BusinessRuntimeException.getInstance("获取验证码过于频繁");
		}
		String code = StringUtil.getRandomCodeStr(6);
		if (type == 1) {
			if (StrUtil.isEmpty(login) || (86 == cid && !Validator.isMobile(phone))) {
				throw BusinessRuntimeException.getInstance("请输入正确的手机号");
			}
			//是否是恶意用户
			badIntentionOpService.checkHandleBadUserOp(phone, verifyCode, ticket, randStr, request);
			SmsUtil.sendTencent(cid, login, code);
		} else if (type == 2) {
			if (!Validator.isEmail(login)) {
				throw BusinessRuntimeException.getInstance("请输入正确的邮箱");
			}
			mailService.sendLoginCodeEmailToPeople(code, login);
		}
		redisService.set(CACHE_LOGIN_KEY, code, RedisService.key.CPS_BACK_LOGIN_KEY.getTimeout());
	}

	@Override
	public User login(Integer type, String login, String code) {
		String phone = null;
		String email = null;
		if (type == null) {
			type = 1;
		}
		if (type > 2) {
			throw BusinessRuntimeException.getInstance("");
		}
		if (type == 1) phone = login;
		if (type == 2) email = login;
		if (StrUtil.isEmpty(code)) {
			throw BusinessRuntimeException.getInstance("请输入验证码");
		}
		String CACHE_LOGIN_KEY = RedisService.key.CPS_BACK_LOGIN_KEY.getName();
		if (type == 1) {
			if (StrUtil.isEmpty(phone)) {
				throw BusinessRuntimeException.getInstance("请输入正确的手机号");
			}
			CACHE_LOGIN_KEY += phone;
		} else if (type == 2) {
			if (!Validator.isEmail(email)) {
				throw BusinessRuntimeException.getInstance("请输入正确的邮箱");
			}
			CACHE_LOGIN_KEY += email;
		}
		String cache_code = (String) redisService.get(CACHE_LOGIN_KEY);
		if (StrUtil.isBlank(cache_code) || !cache_code.equals(code)) {
			throw BusinessRuntimeException.getInstance("验证码错误");
		}
		User user = userDistributeMapper.getUserDistributeDetail(phone, email);
		if (user == null) throw BusinessRuntimeException.getInstance("用户不存在");
		redisService.del(CACHE_LOGIN_KEY);
		return user;
	}

	@Override
	public List<CpsUserWMoneyStatisticsDataView> getWMoneyStatisticsDataView(Long cpsUserId, DateTime first, DateTime end) {
		boolean today = isToday(first, end);
		return waitingSendPointsMapper.getWMoneyStatisticsDataView(cpsUserId, first, end, today);
	}

	@Override
	public BrokenLineCpsUserWMoneyView getWMoneyStatisticsDate(Long cpsUserId, DateTime first, DateTime end) {
		boolean today = isToday(first, end);
		return waitingSendPointsMapper.getWMoneyStatisticsDate(cpsUserId, first, end, today);
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void setCouponCode(long cpsUserId, List<CouponDistributePopularize> couponRelates) throws Exception {
		SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.COUPON_DISTRIBUTE_RELATE_COUPON_KEY)
				.last("limit 1"));
		List<Long> show_coupon_ids = null;
		if (sysConfig != null && StrUtil.isNotBlank(sysConfig.getSysValue())) {
			show_coupon_ids = Jsons.parseList(sysConfig.getSysValue(), Long.class);
		}
		if (CollUtil.isEmpty(show_coupon_ids)) {
			throw BusinessRuntimeException.getInstance("设置优惠码异常");
		}
		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
				.eq(UserDistribute::getUserId, cpsUserId)
				.eq(UserDistribute::getDeleted, true)
				.last("limit 1"));
		//处理优惠券关联
		handlerDistributeCouponRelate(userDistribute.getId(), userDistribute.getUserId(), couponRelates,show_coupon_ids);
	}

	private void handlerDistributeCouponRelate(Long distributeId, Long userId, List<CouponDistributePopularize> couponRelates, List<Long> show_coupon_ids) {
		couponRelates.forEach(data -> {
			data.setDistributeId(distributeId);
			if (data.getCouponId() == null) {
				throw BusinessRuntimeException.getInstance("存在错误的优惠券，请刷新页面重试");
			}
			if (!show_coupon_ids.contains(data.getCouponId())) {
				throw BusinessRuntimeException.getInstance("存在错误的优惠券，请刷新页面重试");
			}
			Integer exists = couponMapper.selectCount(Wrappers.lambdaQuery(Coupon.class).eq(Coupon::getId, data.getCouponId()).eq(Coupon::getDeleted, 1));
			if (exists == 0) {
				throw BusinessRuntimeException.getInstance("存在错误的优惠券，请刷新页面重试");
			}
			String exCode = data.getExCode();
			if (StrUtil.isEmpty(exCode)) {
				throw BusinessRuntimeException.getInstance("优惠码为空");
			}
			List<CouponDistributePopularize> popularizeList = couponDistributePopularizeMapper.selectList(Wrappers.lambdaQuery(CouponDistributePopularize.class)
					.eq(CouponDistributePopularize::getDeleted, 1)
					.eq(CouponDistributePopularize::getExCode, exCode));
			//个人渠道
			for (CouponDistributePopularize couponDistributePopularize : popularizeList) {
				Long disId = couponDistributePopularize.getDistributeId();
				if (disId != null && !ObjectUtil.equal(disId, distributeId)) {
					throw BusinessRuntimeException.getInstance("优惠码:{0}已存在", exCode);
				}
				Long uid = couponDistributePopularize.getUserId();
				if (uid != null && !ObjectUtil.equal(uid, userId)) {
					throw BusinessRuntimeException.getInstance("优惠码:{0}已存在", exCode);
				}
			}
			Integer count = couponMapper.selectCount(Wrappers.lambdaQuery(Coupon.class).eq(Coupon::getExCode, exCode).eq(Coupon::getDeleted, true));
			if (count > 0) {
				throw BusinessRuntimeException.getInstance("优惠码:{0}已存在", exCode);
			}
			if (data.getId() != null) {
//				couponDistributePopularizeMapper.updateById(data);
			} else {
				Long couponId = data.getCouponId();
				Integer selectCount = couponDistributePopularizeMapper.selectCount(Wrappers.lambdaQuery(CouponDistributePopularize.class)
						.eq(CouponDistributePopularize::getDistributeId, distributeId)
						.eq(CouponDistributePopularize::getCouponId, couponId)
						.eq(CouponDistributePopularize::getDeleted, true));
				if (selectCount == 0) {
					couponDistributePopularizeMapper.insert(data);
				}
			}
		});
	}

	public boolean isToday(DateTime first, DateTime end) {
		boolean today = false;
		if (first != null && end != null) {
			if (DateUtil.beginOfDay(DateTime.now()).equals(first) && (DateUtil.beginOfDay(DateUtil.offsetDay(DateTime.now(), 1)).equals(end) || DateUtil.endOfDay(DateTime.now()).equals(end))) {
				today = true;
			}
		}
		return today;
	}
}
