package com.bonus.core.order.common.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.core.order.common.constants.OrderAmountDetailTypeEnum;
import com.bonus.core.order.common.mapper.OrderAmountDetailMapper;
import com.bonus.core.order.common.model.OrderAmountDetail;
import com.bonus.core.order.common.service.OrderAmountDetailService;
import com.bonus.core.order.utils.LeNumUtil;
import com.bonus.core.order.utils.LeOrderUtil;
import com.bonus.core.pay.common.constants.PayStateEnum;
import com.bonus.core.pay.common.vo.TradeChannelVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.invoke.SerializedLambda;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrderAmountDetailServiceImpl extends ServiceImpl<OrderAmountDetailMapper, OrderAmountDetail> implements OrderAmountDetailService {
   @Transactional(
      rollbackFor = {Exception.class}
   )
   public void insertList(List<OrderAmountDetail> orderAmountDetailList) {
      if (!CollUtil.isEmpty(orderAmountDetailList)) {
         Iterator var2 = orderAmountDetailList.iterator();

         while(var2.hasNext()) {
            OrderAmountDetail orderAmountDetail = (OrderAmountDetail)var2.next();
            ((OrderAmountDetailMapper)this.baseMapper).insert(orderAmountDetail);
         }

      }
   }

   @Transactional(
      rollbackFor = {Exception.class}
   )
   public List<OrderAmountDetail> insertByRefund(List<TradeChannelVO> tradeChannelVOList, Long orderId, LocalDate orderDate, Long orderRefundId) {
      if (CollUtil.isEmpty(tradeChannelVOList)) {
         return CollUtil.newArrayList(new OrderAmountDetail[0]);
      } else {
         List<OrderAmountDetail> orderAmountDetailList = tradeChannelVOList.stream().filter((s) -> {
            return PayStateEnum.isPaidState(s.getTradeState());
         }).map((s) -> {
            return s.convertToOrderAmountDetail(orderId, orderDate, orderRefundId, s.getAmount(), OrderAmountDetailTypeEnum.REFUND);
         }).collect(Collectors.toList());
         tradeChannelVOList.stream().filter((s) -> {
            return PayStateEnum.isPaidState(s.getTradeState());
         }).forEach((s) -> {
            s.shareAccPayResult(orderAmountDetailList);
         });
         this.saveBatch(orderAmountDetailList);
         return orderAmountDetailList;
      }
   }

   public void deleteByOrderIds(List<Long> orderIds, Collection<LocalDate> orderDates) {
      if (!CollUtil.isEmpty(orderIds)) {
         List<LocalDate> dateRange = LeOrderUtil.queryDateRange(orderIds, orderDates);
         this.baseMapper.delete(Wrappers
                 .lambdaQuery(OrderAmountDetail.class).in(OrderAmountDetail::getOrderId, orderIds)
                 .between(OrderAmountDetail::getOrderDate, dateRange.get(0), dateRange.get(1)));
      }
   }

   public List<OrderAmountDetail> listByOrderIds(List<Long> orderIds, Collection<LocalDate> orderDates, Integer amountDetailType) {
      if (CollUtil.isEmpty(orderIds)) {
         return CollUtil.newArrayList(new OrderAmountDetail[0]);
      } else {
         List<LocalDate> dateRange = LeOrderUtil.queryDateRange(orderIds, orderDates);
         return this.baseMapper.selectList(Wrappers
                 .lambdaQuery(OrderAmountDetail.class).in(OrderAmountDetail::getOrderId, orderIds)
                 .between(OrderAmountDetail::getOrderDate, dateRange.get(0), dateRange.get(1))
                 .eq(LeNumUtil.isValidId(amountDetailType), OrderAmountDetail::getAmountDetailType, amountDetailType));
      }
   }
}
