package com.cyksj.service.relation.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.constant.Constant;
import com.cyksj.dto.RedisKey;
import com.cyksj.mapper.GoodsDonSkuMapper;
import com.cyksj.mapper.GroupsMapper;
import com.cyksj.mapper.GroupsRelationMapper;
import com.cyksj.mapper.OrderDonMapper;
import com.cyksj.model.entity.*;
import com.cyksj.redis.RedisService;
import com.cyksj.service.groups.GroupsFuncService;
import com.cyksj.service.relation.GroupRelationClearService;
import com.cyksj.service.relation.GroupsRelationChangeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 项目名: yhlxj2
 * 文件名: GroupsRelationChangeServiceImpl
 * 创建者: JavaZou
 * 创建时间:2024/10/28 14:15
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class GroupsRelationChangeServiceImpl implements GroupsRelationChangeService {
	private final GroupsRelationMapper relationMapper;

	private final RedisService redisService;

	private final GroupsMapper groupsMapper;

	private final GroupsFuncService groupsFuncService;

	private final GoodsDonSkuMapper skuMapper;

	private final OrderDonMapper orderDonMapper;

	private final GroupRelationClearService relationClearService;

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public GroupsRelation changeTicket(Long userId, Long oriRelationId, Long itemGroupsId, Long skuId) {
		GroupsRelation relation = getRelationThisTrips(userId, itemGroupsId, 1);
		if (relation == null) {
			return relation;
		}
		syncGroupsRelation(oriRelationId, relation);
		return relation;
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public GroupsRelation getEmptyGroupsRelation(Long userId, Long oriRelationId, Long skuId) {
		return getEmptyGroupsRelationIfRetry(userId, oriRelationId, skuId, 1);
	}

	public GroupsRelation getEmptyGroupsRelationIfRetry(Long userId, Long oriRelationId, Long skuId, Integer retryNum) {
		GroupsTrips groupsTrips = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
				.eq(GroupsTrips::getStatus, GroupsTrips.Status.waiting)
				.eq(GroupsTrips::getSkuId, skuId)
				.gt(GroupsTrips::getAvailableNum, 0)
				.orderByAsc(GroupsTrips::getAvailableNum)
				.last("limit 1"));
		GroupsRelation relation = null;
		if (groupsTrips != null) {
			relation = relationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
					.eq(GroupsRelation::getGroupsId, groupsTrips.getId())
					.eq(GroupsRelation::getStatus, GroupsRelation.Status.none)
					.last("limit 1"));
		}
		if (relation == null) {
			//新增空车队
			GoodsDonSku sku = skuMapper.selectById(skuId);
			relation = groupsFuncService.createNewGroupsTrips(sku);
		}
		if (!redisService.setNx(RedisKey.GROUPS_RELATION_NUM_KEY + relation.getId(), userId, 60 * 2L)) {
			retryNum++;
			if (retryNum >= 7) {
				return null;
			}
			return getEmptyGroupsRelationIfRetry(userId, oriRelationId, skuId, retryNum);
		}
		Long groupsId = relation.getGroupsId();
		int count = groupsMapper.decrAvailableNum(groupsId);
		if (count == 0) {
			log.error("车位异常 groupId:{}", groupsId);
			groupsMapper.updateAvailableNum(groupsId);
			log.error("车位异常");
		}
		syncGroupsRelation(oriRelationId, relation);
		return relation;
	}


	/**
	 * 寻找该车队空余车位
	 */
	public GroupsRelation getRelationThisTrips(Long userId, Long groupsId, Integer retryNum) {
		//寻找快满编车队进行占座
		GroupsRelation relation = relationMapper.selectRandomOneRelationByGroupsId(groupsId);
		if (relation == null) {
			log.error("该车队人员已满,请选择另一车队");
			return null;
		}
		Long relationId = relation.getId();
		if (!redisService.setNx(RedisKey.GROUPS_RELATION_NUM_KEY + relationId, userId, 60 * 2L)) {
			if (retryNum == 7){
				log.error("该车队人员已满,请选择另一车队");
				return null;
			}
			retryNum++;
			return getRelationThisTrips(userId, groupsId, retryNum);
		}
		int count = groupsMapper.decrAvailableNum(relation.getGroupsId());
		if (count == 0) {
			log.error("车位异常 groupId:{}", groupsId);
			groupsMapper.updateAvailableNum(groupsId);
			log.error("车位异常");
			return null;
		}
		return relation;
	}

	public void syncGroupsRelation(Long oriRelationId, GroupsRelation newRelation) {
		GroupsRelation oriRelation = relationMapper.selectById(oriRelationId);
		newRelation.setStartTime(oriRelation.getStartTime());
		newRelation.setExpiryTime(oriRelation.getExpiryTime());
		newRelation.setStatus(oriRelation.getStatus());
		newRelation.setUserId(oriRelation.getUserId());
		newRelation.setYhsId(oriRelation.getYhsId());
		relationMapper.updateById(newRelation);
		relationClearService.clearTicket(oriRelation, UserTicketClearedRecord.Source.change_ticket);
		OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
				.eq(OrderDon::getRelationId, oriRelationId)
				.eq(OrderDon::getUserId, newRelation.getUserId())
				.notIn(OrderDon::getStatus, Constant.noOrderStatus)
				.orderByDesc(OrderDon::getId)
				.last("limit 1"));
		if (orderDon != null) {
			orderDon.setRelationId(newRelation.getId());
			orderDonMapper.updateById(orderDon);
		}
	}
}
