package com.cyksj.service.distribute.equipment.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.util.Jsons;
import com.cyksj.mapper.GroupsRelationMapper;
import com.cyksj.mapper.OrderDonMapper;
import com.cyksj.mapper.UserMapper;
import com.cyksj.mapper.manage.distribute.equipment.*;
import com.cyksj.model.dto.EquipmentConfigDto;
import com.cyksj.model.entity.*;
import com.cyksj.model.manage.views.RealGoodsOrderDonView;
import com.cyksj.redis.RedisService;
import com.cyksj.service.distribute.equipment.EquipmentDistributeService;
import com.cyksj.service.mange.coupon.CouponCommonService;
import com.cyksj.service.relation.GroupRelationClearService;
import com.cyksj.service.sys.SysConfigService;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Optional;

/*
 *项目名: netflix
 *文件名: EquipmentDistributeServiceImpl
 *创建者: JavaZou
 *创建时间:2023/2/23 13:42
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class EquipmentDistributeServiceImpl implements EquipmentDistributeService {

	private final EquipmentUserDistributeInviteRecordMapper inviteRecordMapper;

	private final EquipmentUserChanceMapper equipmentUserChanceMapper;

	private final EquipmentUserChanceRecordMapper equipmentUserChanceRecordMapper;

	private final EquipmentUserReceiveBenefitsRecordMapper equipmentUserReceiveBenefitsRecordMapper;

	private final GroupsRelationMapper groupsRelationMapper;

	private final GroupRelationClearService groupRelationClearService;

	private final SysConfigService sysConfigService;

	private final CouponCommonService couponCommonService;

	private final RedisService redisService;

	private final OrderDonMapper orderDonMapper;

	private final BeanSearcher beanSearcher;

	private final EquipmentUserDistributeTransportBenefitsMapper transportBenefitsMapper;

	private final EquipmentUserPayRecordMapper equipmentUserPayRecordMapper;

	private final UserMapper userMapper;

	@Override
	public void saveDistributionInvitation(Long sharedId, Boolean isNewUser, Long userId) {
		if (sharedId == 0l || sharedId.equals(userId)) {
			return;
		}
		User user = userMapper.selectById(sharedId);
		if (user == null) {
			return;
		}
		//邀请人是否购买了实物
		RealGoodsOrderDonView realGoodsOrderDonView = beanSearcher.searchFirst(RealGoodsOrderDonView.class, MapUtils.builder()
				.field(RealGoodsOrderDonView::getStatus, Constant.noOrderAllStatus).op(Operator.NotIn)
				.field(RealGoodsOrderDonView::getType, 2)
				.field(RealGoodsOrderDonView::getUserId, sharedId)
				.build());
		if (realGoodsOrderDonView == null) {
			log.info("userid:{},购买硬件设备之后才可拥有分享权益", sharedId);
			return;
		}
		EquipmentUserDistributeInviteRecord exists = inviteRecordMapper.selectOne(Wrappers.lambdaQuery(EquipmentUserDistributeInviteRecord.class)
				.eq(EquipmentUserDistributeInviteRecord::getUserId, userId).last("limit 1"));
		if (exists == null) {
			EquipmentUserDistributeInviteRecord record = new EquipmentUserDistributeInviteRecord();
			record.setShareId(sharedId);
			//存在分销
			record.setUserId(userId);
			try {
				//发放新用户福利优惠券
//				if (isNewUser) {
//				sendInvitedUserEquipmentCoupon(userId);
//				}
				record.setIsNewUser(isNewUser);
				inviteRecordMapper.insert(record);

			} catch (DuplicateKeyException e) {
				log.info("实物分销被邀请人id:{}重复插入", userId);
			} catch (Exception e) {
			}
		}
	}

	@Override
	public void addDistributeBenefitsChance(Long userId, Long orderId) {
		EquipmentUserDistributeInviteRecord record = getDistributeRecord(userId);
		if (record != null) {
			Long sharId = record.getShareId();
			saveInviteRecord(sharId, userId, orderId, 1);
		}
	}

	@Override
	public void subDistributeBenefitsChance(Long userId, Long orderId) {
		EquipmentUserDistributeInviteRecord record = getDistributeRecord(userId);
		if (record != null) {
			Long sharId = record.getShareId();
			saveInviteRecord(sharId, userId, orderId, 2);
		}
	}

	public EquipmentUserDistributeInviteRecord getDistributeRecord(Long userId) {
		//是否有实物分销邀请记录
		EquipmentUserDistributeInviteRecord record = inviteRecordMapper.selectOne(Wrappers.lambdaQuery(EquipmentUserDistributeInviteRecord.class)
				.eq(EquipmentUserDistributeInviteRecord::getUserId, userId)
				.last("limit 1"));
		if (record == null) {
			return null;
		}
		return record;
	}

	public void saveInviteRecord(Long sharId, Long userId, Long orderId, Integer type) {
//		EquipmentConfigDto equipmentConfigDto = checkEquipmentConfigDto();
		Integer benefitsType = 0;
		if (type == 1) {
//			//配置车票权益
//			if (CollUtil.isNotEmpty(equipmentConfigDto.getSkuList())) {
//				addTicketBenefitsChance(sharId, userId, orderId, EquipmentUserChanceRecord.Status.hasPayment);
//			}
//
//			//已配置余额  实物发货 发送余额
//			if (equipmentConfigDto.getBalance() != null && equipmentConfigDto.getBalance().compareTo(BigDecimal.ZERO) > 0) {
//				addBalanceBenefits(sharId, orderId, equipmentConfigDto.getBalance(), EquipmentUserDistributeTransportBenefits.Status.hasPayment);
//				benefitsType = 2;
//			}
			EquipmentUserPayRecord record = new EquipmentUserPayRecord();
			record.setShareId(sharId);
			record.setUserId(userId);
			record.setStatus(EquipmentUserPayRecord.Status.hasPayment);
			record.setOrderId(orderId);
			//0无类型  1、车票权益，2、余额
			record.setType(benefitsType);
			equipmentUserPayRecordMapper.insert(record);
		} else if (type == 2) {
//			//是否有余额权益
//			EquipmentUserDistributeTransportBenefits transportBenefits = transportBenefitsMapper.selectOne(Wrappers.lambdaQuery(EquipmentUserDistributeTransportBenefits.class)
//					.eq(EquipmentUserDistributeTransportBenefits::getOrderId, orderId).last("limit 1"));
//			if (transportBenefits != null && transportBenefits.getStatus() != EquipmentUserDistributeTransportBenefits.Status.complete) {
//				transportBenefits.setStatus(EquipmentUserDistributeTransportBenefits.Status.refund);
//				transportBenefitsMapper.updateById(transportBenefits);
//			}
//			//是否有车票权益
//			int update = equipmentUserChanceRecordMapper.update(null, Wrappers.lambdaUpdate(EquipmentUserChanceRecord.class)
//					.set(EquipmentUserChanceRecord::getStatus, EquipmentUserChanceRecord.Status.refund)
//					.eq(EquipmentUserChanceRecord::getOrderId, orderId)
//					.eq(EquipmentUserChanceRecord::getStatus, EquipmentUserChanceRecord.Status.hasPayment));
//			if (update > 0) {
//				update = equipmentUserChanceMapper.subUserChance(sharId);
//				if (update == 0) {
//					//扣除权益
//					deductUserBenefits(sharId, orderId);
//				}
//			}
			equipmentUserPayRecordMapper.update(null, Wrappers.lambdaUpdate(EquipmentUserPayRecord.class)
					.set(EquipmentUserPayRecord::getStatus, EquipmentUserPayRecord.Status.refund)
					.eq(EquipmentUserPayRecord::getOrderId, orderId)
					.ne(EquipmentUserPayRecord::getStatus, EquipmentUserChanceRecord.Status.refund));
		}
	}

	public void deductUserBenefits(Long userId, Long orderId) {
		EquipmentUserReceiveBenefitsRecord receiveBenefitsRecord = equipmentUserReceiveBenefitsRecordMapper.selectOne(Wrappers.lambdaQuery(EquipmentUserReceiveBenefitsRecord.class)
				.eq(EquipmentUserReceiveBenefitsRecord::getStatusCode, 1)
				.eq(EquipmentUserReceiveBenefitsRecord::getUserId, userId)
				.orderByDesc(EquipmentUserReceiveBenefitsRecord::getId).last("limit 1"));
		if (receiveBenefitsRecord == null) {
			return;
		}
		Integer days = receiveBenefitsRecord.getDays();
		Integer months = receiveBenefitsRecord.getNum();
		Long relationId = receiveBenefitsRecord.getRelationId();
		GroupsRelation relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
				.eq(GroupsRelation::getUserId, userId)
				.eq(GroupsRelation::getId, relationId).eq(GroupsRelation::getStatus, GroupsRelation.Status.validity).last("limit 1"));
		Date expiryTime = relation.getExpiryTime();
		if (relation == null) {
			return;
		}
		if (expiryTime == null) {
			//未发车直接清除车票
			groupRelationClearService.clearTicket(relation, UserTicketClearedRecord.Source.distribute);
		} else {
			DateTime now = DateTime.now();
			Date finalDate = null;
			if (days != null && days > 0) {
				finalDate = DateUtil.offsetDay(expiryTime, -days);
			} else {
				finalDate = DateUtil.offset(expiryTime, DateField.MONTH, -months);
			}
			if (now.isAfter(finalDate)) {
				//过期 直接清除车票
				groupRelationClearService.clearTicket(relation, UserTicketClearedRecord.Source.distribute);
			} else {
				relation.setExpiryTime(finalDate);
				groupsRelationMapper.updateById(relation);
			}
		}
		Optional.ofNullable(receiveBenefitsRecord.getOrderId()).ifPresent(selfOrderId->{
			orderDonMapper.update(null, Wrappers.lambdaUpdate(OrderDon.class).eq(OrderDon::getId, selfOrderId)
					.set(OrderDon::getRefundMoney, BigDecimal.ZERO)
					.set(OrderDon::getStatus, OrderDon.Status.refund));
		});
		receiveBenefitsRecord.setRefundOrderId(orderId);
		receiveBenefitsRecord.setStatusCode(0);
		equipmentUserReceiveBenefitsRecordMapper.updateById(receiveBenefitsRecord);
	}

	public void sendInvitedUserEquipmentCoupon(Long userId) throws Exception {
		SysConfig config = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
				.eq(SysConfig::getSysKey, Constant.EQUIPMENT_DISTRIBUTE_KEY).last("limit 1"));
		Optional.ofNullable(config).ifPresent(cf->{
			EquipmentConfigDto equipmentConfigDto = null;
			try {
				equipmentConfigDto = Jsons.parseObject(config.getSysValue(), EquipmentConfigDto.class);
				if (equipmentConfigDto != null && CollUtil.isNotEmpty(equipmentConfigDto.getCouponIds())) {
					equipmentConfigDto.getCouponIds().forEach(couponId -> {
						couponCommonService.sendCouponToUser(userId, couponId, null, null, null, CouponUser.Channel.equipment);
					});
					redisService.set(RedisService.key.EQUIPMENT_DISTRIBUTE_COUPON_KEY.getNameFormat(userId), userId, RedisService.key.EQUIPMENT_DISTRIBUTE_COUPON_KEY.getTimeout());
				}
			} catch (Exception e) {
			}
		});
	}

	public EquipmentConfigDto checkEquipmentConfigDto() {
		//是否有配置车票权益
		SysConfig config = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
				.eq(SysConfig::getSysKey, Constant.EQUIPMENT_DISTRIBUTE_KEY).last("limit 1"));
		if (config == null) {
			return null;
		}
		String sysValue = config.getSysValue();
		//未配置权益
		if (StrUtil.isEmpty(sysValue)) {
			return null;
		}
		EquipmentConfigDto equipmentConfigDto = null;
		try {
			equipmentConfigDto = Jsons.parseObject(sysValue, EquipmentConfigDto.class);
		} catch (Exception e) {
			return null;
		}
		return equipmentConfigDto;
	}

	public void addBalanceBenefits(Long sharId, Long orderId, BigDecimal balance, EquipmentUserDistributeTransportBenefits.Status status) {
		log.info("分销人:{}记录分享有礼实物订单:{}余额权益,待发货后发送", sharId, orderId);
		EquipmentUserDistributeTransportBenefits transportBenefits = new EquipmentUserDistributeTransportBenefits();
		transportBenefits.setShareId(sharId);
		transportBenefits.setOrderId(orderId);
		transportBenefits.setStatus(status);
		transportBenefits.setBalance(balance);
		transportBenefitsMapper.insert(transportBenefits);
	}

	public void addTicketBenefitsChance(Long sharId, Long userId, Long orderId, EquipmentUserChanceRecord.Status status) {
		try {
			EquipmentUserChanceRecord record = new EquipmentUserChanceRecord();
			record.setShareId(sharId);
			record.setUserId(userId);
			record.setStatus(status);
			record.setOrderId(orderId);
			equipmentUserChanceRecordMapper.insert(record);

			EquipmentUserChance chance = equipmentUserChanceMapper.selectOne(Wrappers.lambdaQuery(EquipmentUserChance.class)
					.eq(EquipmentUserChance::getUserId, sharId)
					.last("limit 1"));
			if (chance == null) {
				try {
					chance = new EquipmentUserChance();
					chance.setUserId(sharId);
					chance.setNum(1);
					equipmentUserChanceMapper.insert(chance);
				} catch (DuplicateKeyException e) {
					equipmentUserChanceMapper.addUserChance(sharId);
				}
			} else {
				equipmentUserChanceMapper.addUserChance(sharId);
			}
		} catch (DuplicateKeyException e) {
		}
	}
}
