package shop.alien.job.store;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import shop.alien.entity.store.LifeCoupon;
import shop.alien.entity.store.LifeGroupBuyMain;
import shop.alien.entity.store.LifeUserOrder;
import shop.alien.entity.store.OrderCouponMiddle;
import shop.alien.mapper.LifeCouponMapper;
import shop.alien.mapper.LifeGroupBuyMainMapper;
import shop.alien.mapper.LifeUserOrderMapper;
import shop.alien.mapper.OrderCouponMiddleMapper;
import shop.alien.util.common.constant.OrderStatusEnum;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户订单任务
 * 待支付订单超时处理
 *
 * @author lyx
 * @date 2023/12/20 14:20
 * @see shop.alien.entity.store.LifeUserOrder
 */

@Slf4j
@Component
@RequiredArgsConstructor
public class LifeUserOrderJob {

    private final LifeUserOrderMapper lifeUserOrderMapper;
    private final OrderCouponMiddleMapper orderCouponMiddleMapper;
    private final LifeCouponMapper lifeCouponMapper;
    private final LifeGroupBuyMainMapper lifeGroupBuyMainMapper;
    /**
     * 待支付订单超时处理
     */
    @XxlJob("autoCancelUnpaidOrders")
    @Transactional(rollbackFor = Exception.class)
    public String autoCancelUnpaidOrders(){
        //1.查询待支付超时订单
        List<LifeUserOrder> lifeUserOrders = lifeUserOrderMapper.selectList(new LambdaQueryWrapper<LifeUserOrder>()
                .eq(LifeUserOrder::getStatus, OrderStatusEnum.WAIT_PAY.getStatus())
                .le(LifeUserOrder::getBuyTime, LocalDateTime.now().minusMinutes(15)));
        if( CollectionUtils.isEmpty(lifeUserOrders) ){
            return "无待支付超时订单";
        }
        //2.超时则取消订单id
        List<String> orderIds = lifeUserOrders.stream().map(LifeUserOrder::getId).collect(Collectors.toList());
        lifeUserOrderMapper.update(null,new LambdaUpdateWrapper<LifeUserOrder>()
                .set(LifeUserOrder::getStatus,OrderStatusEnum.CANCEL.getStatus())
                .set(LifeUserOrder::getCancelTime,LocalDateTime.now())
                .set(LifeUserOrder::getCancelReason,"订单超时未支付")
                .set(LifeUserOrder::getFinishTime,LocalDateTime.now())
                .in(LifeUserOrder::getId,orderIds));
        // 根据类型分组
        Map<Integer, List<String>> collect = lifeUserOrders.stream().filter(order -> order.getCouponType() != null)
                .collect(Collectors.groupingBy(
                        LifeUserOrder::getCouponType,  // 按订单类型分组
                        Collectors.mapping(  // 对每个分组中的元素提取ID
                                LifeUserOrder::getId,
                                Collectors.toList()
                        )
                ));
        int updateNum = 0;
        if(collect.containsKey(0)){
            //3.1代金券订单
            List<String> couponOrderIds = collect.get(0);
            QueryWrapper<OrderCouponMiddle> queryWrapper = new QueryWrapper<OrderCouponMiddle>().in("order_id", couponOrderIds)
                    .eq("status", OrderStatusEnum.WAIT_PAY.getStatus())
                    .groupBy("coupon_id")  // 按coupon_id分组
                    .select("coupon_id, COUNT(*) as count");  // 选择分组字段和统计数量
            List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(queryWrapper);
            for (OrderCouponMiddle orderCouponMiddle : orderCouponMiddles) {
                // 恢复库存
                lifeCouponMapper.update(null, new LambdaUpdateWrapper<LifeCoupon>()
                        .setSql("stock_qty=stock_qty+" + orderCouponMiddle.getCount())
                        .eq(LifeCoupon::getId, orderCouponMiddle.getCouponId()));
            }
        }
        if(collect.containsKey(1)){
            //3.2团购订单
            List<String> groupOrderIds = collect.get(1);
            QueryWrapper<OrderCouponMiddle> queryWrapper = new QueryWrapper<OrderCouponMiddle>().in("order_id", groupOrderIds)
                    .eq("status", OrderStatusEnum.WAIT_PAY.getStatus())
                    .groupBy("coupon_id")  // 按coupon_id分组
                    .select("coupon_id, COUNT(*) as count");
            List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(queryWrapper);
            for (OrderCouponMiddle orderCouponMiddle : orderCouponMiddles) {
                // 恢复库存
                lifeGroupBuyMainMapper.update(null,new LambdaUpdateWrapper<LifeGroupBuyMain>()
                        .setSql("inventory_num=inventory_num+" + orderCouponMiddle.getCount())
                        .eq(LifeGroupBuyMain::getId, orderCouponMiddle.getCouponId()));
            }
        }
        // 更新券状态
        orderCouponMiddleMapper.update(null,new LambdaUpdateWrapper<OrderCouponMiddle>()
                .set(OrderCouponMiddle::getStatus,OrderStatusEnum.CANCEL.getStatus())
                .in(OrderCouponMiddle::getOrderId,orderIds));
        return "success";
    }

    /**
     * 自动更新总订单状态
     */
    @XxlJob("autoUpdateOrderStatus")
    @Transactional(rollbackFor = Exception.class)
    public String autoUpdateOrderStatus(){
        // 查询所以已完成的订单id
        List<OrderCouponMiddle> orderCouponMiddles = orderCouponMiddleMapper.selectList(new LambdaQueryWrapper<OrderCouponMiddle>()
                .select(OrderCouponMiddle::getOrderId)
                .eq(OrderCouponMiddle::getDeleteFlag, 0)
                .in(OrderCouponMiddle::getStatus, OrderStatusEnum.CANCEL.getStatus(), OrderStatusEnum.WAIT_PAY.getStatus(), OrderStatusEnum.WAIT_USE.getStatus(), OrderStatusEnum.REFUND_FAILED.getStatus())
                .groupBy(OrderCouponMiddle::getOrderId));
        // 批量更新为已完成
        lifeUserOrderMapper.update(null,new UpdateWrapper<LifeUserOrder>()
                .set("status",OrderStatusEnum.COMPLETE.getStatus())
                .notIn("id",orderCouponMiddles.stream().map(OrderCouponMiddle::getOrderId).collect(Collectors.toList())));
        return "success";
    }
}
