package com.cyksj.service.order.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.dto.RedisKey;
import com.cyksj.mapper.*;
import com.cyksj.model.entity.*;
import com.cyksj.redis.RedisService;
import com.cyksj.service.order.OrderCommonService;
import com.cyksj.service.relation.GroupRelationClearService;
import com.cyksj.service.user.UserBindRelationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/*
 *项目名: netflix
 *文件名: OrderCommonServiceImpl
 *创建者: JavaZou
 *创建时间:2023/5/22 14:48
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class OrderCommonServiceImpl implements OrderCommonService {

	private final GroupsRelationMapper groupsRelationMapper;

	private final UserRenewChangeTicketRecordMapper userRenewChangeTicketRecordMapper;

	private final OrderDonMapper orderDonMapper;

	private final GoodsDonSkuMapper goodsDonSkuMapper;

	private final GroupsMapper groupsMapper;

	private final RedisService redisService;

	private final GroupRelationClearService clearService;

	private final UserBindRelationService userBindRelationService;
	@Override
	public void clearUnrealGoodsDetail(OrderDon orderDon, Integer goodsType, GoodsDonSku sku) {
		if (goodsType == 1 && sku != null) {
			//清出车队,车位变为已过期
			Long relationId = orderDon.getRelationId();
			//更换车票前后的座位id集合
			List<Long> relationIds = new ArrayList<>();
			relationIds.add(relationId);
			Integer num = orderDon.getNum();
			DateTime now = DateTime.now();
			List<Long> userIdList = userBindRelationService.getRelationUserIdList(orderDon.getUserId(), null);
			GroupsRelation relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
					.in(GroupsRelation::getUserId, userIdList)
					.eq(GroupsRelation::getId, relationId)
					.in(GroupsRelation::getStatus, List.of(GroupsRelation.Status.validity, GroupsRelation.Status.outside)));
			Date oriExpiryTime = relation.getExpiryTime();
			//车票变更之后
			if (relation == null || orderDon.getIsChangeTicket()) {
				UserRenewChangeTicketRecord record = userRenewChangeTicketRecordMapper.selectOne(Wrappers.lambdaQuery(UserRenewChangeTicketRecord.class)
						.in(UserRenewChangeTicketRecord::getUserId, userIdList)
						.eq(UserRenewChangeTicketRecord::getPreRelationId, relationId)
						.orderByDesc(UserRenewChangeTicketRecord::getId).last("limit 1"));
				if (record != null && relationId.equals(record.getPreRelationId())) {
					relation = groupsRelationMapper.selectById(record.getAfterRelationId());
					Optional.ofNullable(relation).ifPresent((re) -> relationIds.add(re.getId()));
				}
			}
			if (relation != null) {
				Boolean isFlag = true;
				Date expiryTime = relation.getExpiryTime();
				OrderDon otherOrder = null;
				if (orderDon.getOrderType() == 2 || relationIds.size() > 1) {
					//是否有其他付款订单是否过期
					otherOrder = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
							.in(OrderDon::getRelationId, relationIds)
							.in(OrderDon::getUserId, userIdList)
							.ne(OrderDon::getId, orderDon.getId())
							.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
							.orderByDesc(OrderDon::getId)
							.last("limit 1"));
				}
				if (otherOrder != null) {
					Long otherSkuId = otherOrder.getSkuId();
					GoodsDonSku otherGoodsSku = goodsDonSkuMapper.selectById(otherSkuId);
					DateTime endTime;
					Date otherOrderCreatedTime = otherOrder.getCreatedTime();
					if (otherGoodsSku.getDays() != null && otherGoodsSku.getDays() > 0) {
						endTime = DateUtil.offsetDay(otherOrderCreatedTime, otherGoodsSku.getDays() * num);
					} else {
						if (otherGoodsSku.getGoodsId() == 1 && otherGoodsSku.getMonths() == 1) {
							endTime = DateUtil.offsetDay(otherOrderCreatedTime, 30);
						} else{
							endTime = DateUtil.offsetMonth(otherOrderCreatedTime, otherGoodsSku.getMonths() * num);
						}
					}
					if (now.isBefore(endTime)) {
						isFlag = false;
					}
				} else {
					//座位 过期时间
					if (expiryTime != null) {
						DateTime refundExpiryTime;
						if (sku.getDays() != null && sku.getDays() > 0) {
							refundExpiryTime = DateUtil.offsetDay(expiryTime, -sku.getDays() * num);
						} else {
							if (sku.getGoodsId() == 1 && sku.getMonths() == 1) {
								refundExpiryTime = DateUtil.offsetDay(expiryTime, -30);
							} else {
								refundExpiryTime = DateUtil.offsetMonth(expiryTime, -sku.getMonths() * num);
							}
						}
						if (now.isBefore(refundExpiryTime)) {
							isFlag = false;
						}
					}
				}
				if (isFlag) {
					clearService.clearTicket(relation, UserTicketClearedRecord.Source.refund);
				} else {
					if (expiryTime != null) {
						if (sku.getDays() != null && sku.getDays() > 0) {
							expiryTime = DateUtil.offsetDay(expiryTime, -sku.getDays() * num);
						} else {
							if (sku.getGoodsId() == 1 && sku.getMonths() == 1) {
								expiryTime = DateUtil.offsetDay(expiryTime, -30);
							} else{
								expiryTime = DateUtil.offsetMonth(expiryTime, -sku.getMonths() * num);
							}
						}
						relation.setExpiryTime(expiryTime);
						groupsRelationMapper.updateById(relation);
						if (expiryTime.compareTo(now) <= 0) {
							clearService.clearTicket(relation, UserTicketClearedRecord.Source.refund);
						} else {
							if (sku.getGoodsId() == Constant.CLAUDE_CODE_GOODS_ID) {

							}
						}
					}
				}
				if (relation != null && relation.getIsFrozen()) {
					Date thisExpiryTime = relation.getExpiryTime();
					if (thisExpiryTime != null) {
						Long day = DateUtil.betweenDay(thisExpiryTime, oriExpiryTime, false);
						if (day > 0) {
							relation.setReservedDays(relation.getReservedDays() - day.intValue());
							if (relation.getReservedDays() > 0) {
								groupsRelationMapper.updateById(relation);
							}
						}
					}
				}
				orderDon.setIsKickOut(true);
				return;
			}
			throw BusinessRuntimeException.getInstance("车票已不存在");
		}
	}

	@Override
	public void delRelation(GroupsRelation relation) {
		Long relationId = relation.getId();
		redisService.del(RedisKey.GROUPS_RELATION_NUM_KEY + relationId);
		if (relation.getStatus() == GroupsRelation.Status.outside) {
			return;
		}
		int count = groupsMapper.incrAvailableNum(relation.getGroupsId());
		if (count == 0) {
			log.error("车位异常 groupId:{}", relation.getGroupsId());
			groupsMapper.updateAvailableNum(relation.getGroupsId());
			throw new BusinessRuntimeException("车位异常");
		}
	}

	@Override
	public void clearUserTicketTime(Long relationId) {
		GroupsRelation relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
				.eq(GroupsRelation::getId, relationId)
				.in(GroupsRelation::getStatus, List.of(GroupsRelation.Status.validity, GroupsRelation.Status.outside)));
		GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
		GoodsDonSku sku = goodsDonSkuMapper.selectById(groupsTrips.getSkuId());
		Date expiryTime = relation.getExpiryTime();
		DateTime now = DateTime.now();
		Boolean isFlag = true;
		if (expiryTime != null) {
			DateTime refundExpiryTime;
			if (sku.getDays() != null && sku.getDays() > 0) {
				refundExpiryTime = DateUtil.offsetDay(expiryTime, -sku.getDays());
			} else {
				if (sku.getGoodsId() == 1 && sku.getMonths() == 1) {
					refundExpiryTime = DateUtil.offsetDay(expiryTime, -30);
				} else {
					refundExpiryTime = DateUtil.offsetMonth(expiryTime, -sku.getMonths());
				}
			}
			if (now.isBefore(refundExpiryTime)) {
				isFlag = false;
			}
		}

		if (isFlag) {
			relation.setUserId(0l);
			if (relation.getStatus() != GroupsRelation.Status.outside) {
				relation.setStatus(GroupsRelation.Status.none);
			}
			relation.setStartTime(null);
			relation.setExpiryTime(null);
			relation.setIsHandle(false);
			relation.setRenewStatus(false);
			relation.setAccount(null);
			groupsRelationMapper.updateExpiryTime(relation, expiryTime);
			if (relation.getStatus() != GroupsRelation.Status.outside) {
				delRelation(relation);
			}
		} else {
			if (expiryTime != null) {
				if (sku.getDays() != null && sku.getDays() > 0) {
					expiryTime = DateUtil.offsetDay(expiryTime, -sku.getDays());
				} else {
					if (sku.getGoodsId() == 1 && sku.getMonths() == 1) {
						expiryTime = DateUtil.offsetDay(expiryTime, -30);
					} else {
						expiryTime = DateUtil.offsetMonth(expiryTime, -sku.getMonths());
					}
				}
				relation.setExpiryTime(expiryTime);
				groupsRelationMapper.updateById(relation);
			}
		}
	}
}
