package com.bonus.canteen.core.pay.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.bonus.canteen.core.account.v3.service.AccTradeService;
import com.bonus.canteen.core.common.utils.TenantContextHolder;
import com.bonus.canteen.core.order.common.model.OrderInfo;
import com.bonus.canteen.core.order.common.service.OrderInfoService;
import com.bonus.canteen.core.pay.api.vo.TradeRecordParamVO;
import com.bonus.canteen.core.pay.common.constants.PayStateEnum;
import com.bonus.canteen.core.pay.common.constants.TradeTypeEnum;
import com.bonus.canteen.core.pay.common.model.TradeChannel;
import com.bonus.canteen.core.pay.common.model.TradeOrderRecharge;
import com.bonus.canteen.core.pay.common.model.TradeRecord;
import com.bonus.canteen.core.pay.common.service.TradeChannelService;
import com.bonus.canteen.core.pay.common.service.TradeRecordService;
import com.bonus.canteen.core.pay.common.service.impl.PayTradeServiceImpl;
import com.bonus.canteen.core.pay.common.vo.MobileNotifyVO;
import com.bonus.canteen.core.pay.common.vo.TradeChannelVO;
import com.bonus.common.houqin.i18n.I18n;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class TradeRecordApi {
   private static final Logger log = LoggerFactory.getLogger(TradeRecordApi.class);
   @Lazy
   @Resource
   protected TradeRecordService tradeRecordService;
   @Lazy
   @Resource
   protected OrderInfoService orderInfoService;
   @Lazy
   @Autowired
   protected TradeChannelService tradeChannelService;

   public TradeRecord getTradeRecordById(Long tradeId) {
      return this.tradeRecordService.getTradeRecordById(tradeId);
   }

   public TradeRecordParamVO getParamVOByTradeId(Long tradeId) {
      TradeRecord tradeRecord = this.tradeRecordService.getTradeRecordById(tradeId);
      if (tradeRecord == null) {
         return null;
      } else {
         TradeRecordParamVO paramVO = TradeRecordParamVO.of(tradeRecord);
         if (TradeTypeEnum.isConsumeType(tradeRecord.getTradeType())) {
            List<OrderInfo> orderInfoList = this.orderInfoService.getOrderInfoListByTradeId(tradeRecord.getId());
            paramVO.fillOrderInfoList(orderInfoList);
         }

         return paramVO;
      }
   }
   public List<TradeOrderRecharge> listOrderRechargeByTradeId(Long tradeId) {
      return this.tradeRecordService.queryOrderRechargeTrade(tradeId);
   }

   public List<TradeOrderRecharge> listSuccessByOrderIds(List<Long> orderIds) {
      return this.tradeRecordService.listSuccessByOrderIds(orderIds);
   }

   public List<TradeChannelVO> listChannelDetailByTradeId(Long tradeId) {
      return this.tradeChannelService.listChannelDetailByTradeId(tradeId);
   }

   @Transactional(
           rollbackFor = {Exception.class}
   )
   public void updateOrderRechargeId(Long tradeId, String newMacOrderId, List<Long> newOrderRechargeIds) {
      if (!CollUtil.isEmpty(newOrderRechargeIds)) {
         this.tradeRecordService.deleteOrderRechargeTrade(tradeId);
         this.tradeRecordService.insertOrderRechargeTrade(newOrderRechargeIds.stream().map((s) -> {
            return new TradeOrderRecharge(tradeId, s, newMacOrderId, (LocalDateTime)null, (LocalDateTime)null);
         }).collect(Collectors.toList()));
      }
   }

   public TradeRecord getLastTradeRecordByOrderId(Long orderId) {
      return (TradeRecord)this.tradeRecordService.queryTradeRecordInfoList((String)null, orderId, (Integer)null, (Integer)null).stream().sorted(Comparator.comparing(TradeRecord::getId).reversed()).findFirst().orElse((TradeRecord) null);
   }

   public List<TradeRecord> listTradeRecordByOrderRechargeId(Long orderRechargeId, Integer... tradeState) {
      return this.tradeRecordService.listTradeRecordByOrderRechargeId(orderRechargeId, tradeState);
   }
}
