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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.core.order.utils.LeNumUtil;
import com.bonus.core.order.utils.LeOrderUtil;
import com.bonus.core.pay.api.vo.UnifyPayVO;
import com.bonus.core.pay.api.vo.UnifyRefundVO;
import com.bonus.core.pay.common.mapper.TradeOrderRechargeMapper;
import com.bonus.core.pay.common.mapper.TradeRecordMapper;
import com.bonus.core.pay.common.model.TradeOrderRecharge;
import com.bonus.core.pay.common.model.TradeRecord;
import com.bonus.core.pay.common.service.TradeRecordService;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class TradeRecordServiceImpl extends ServiceImpl<TradeRecordMapper, TradeRecord> implements TradeRecordService {
   private static final Logger log = LoggerFactory.getLogger(TradeRecordServiceImpl.class);
   @Resource
   private TradeOrderRechargeMapper tradeOrderRechargeMapper;
   public void  insertTradeRecord(TradeRecord tradeRecord) {
      log.info("[交易记录] insertTradeRecord 开始");
      this.save(tradeRecord);
      log.info("[交易记录] insertTradeRecord 结束");
   }

   public void insertOrderRechargeTrade(List<TradeOrderRecharge> tradeOrderRechargeList) {
      log.info("[交易记录] insertOrderRechargeTrade 开始");
      if (!CollUtil.isEmpty(tradeOrderRechargeList)) {
         this.tradeOrderRechargeMapper.batchInsert(tradeOrderRechargeList);
         log.info("[交易记录] insertOrderRechargeTrade 结束");
      }
   }

   @Override
   @Transactional(
      rollbackFor = {Exception.class}
   )
   public void insertTrade(TradeRecord tradeRecord, List<TradeOrderRecharge> tradeOrderRechargeList) {
      this.insertTradeRecord(tradeRecord);
      this.insertOrderRechargeTrade(tradeOrderRechargeList);
   }


   @Override
   public void updateTradeRecordState(Long tradeId, UnifyPayVO payVO) {
      this.updateTradeRecordState(tradeId, payVO.getCode(), payVO.getMsg(), payVO.getOutTradeNo(), payVO.getPayChannel(), payVO.getPayType(), payVO.getPayTime(), payVO.getCustId());
   }

   protected void updateTradeRecordState(Long tradeId, Integer tradeState, String tradeResult, String outTradeNo, Integer payChannel, Integer payType, LocalDateTime tradeTime, Long custId) {
      log.info("[交易记录] updateTradeRecordState 开始");
      List<LocalDateTime> timeRange = LeOrderUtil.queryCreateTimeRange(tradeId);
      this.update(Wrappers.<TradeRecord>lambdaUpdate().set(TradeRecord::getTradeState, tradeState).set(TradeRecord::getTradeResult, tradeResult)
              .set(CharSequenceUtil.isNotBlank(outTradeNo), TradeRecord::getOutTradeNo, outTradeNo).set(ObjectUtil.isNotNull(payChannel), TradeRecord::getPayChannel, payChannel)
              .set(ObjectUtil.isNotNull(payType), TradeRecord::getPayType, payType).set(ObjectUtil.isNotNull(tradeTime), TradeRecord::getTradeTime, tradeTime)
              .set(LeNumUtil.isValidId(custId), TradeRecord::getCustId, custId).eq(TradeRecord::getId, tradeId).between(TradeRecord::getCreateTime, timeRange.get(0), timeRange.get(1)));
      log.info("[交易记录] updateTradeRecordState 结束");
   }

   @Override
   public TradeRecord getTradeRecordById(Long tradeId) {
      if (tradeId == null) {
         return null;
      } else {
         log.info("[交易记录] getTradeRecordById 开始");
         List<LocalDateTime> timeRange = LeOrderUtil.queryCreateTimeRange(tradeId);
         TradeRecord tradeRecord = (TradeRecord)((TradeRecordMapper)this.baseMapper)
                 .selectOne(Wrappers.lambdaQuery(TradeRecord.class).eq(TradeRecord::getId, tradeId)
                         .between(TradeRecord::getCreateTime, timeRange.get(0), timeRange.get(1)));
         log.info("[交易记录] getTradeRecordById 结束");
         return tradeRecord;
      }
   }

   @Override
   public List<TradeOrderRecharge> queryOrderRechargeTrade(Long tradeId) {
      log.info("[交易记录] queryOrderRechargeTrade 开始");
      List<LocalDateTime> timeRange = LeOrderUtil.queryCreateTimeRange(tradeId);
      List<TradeOrderRecharge> tradeOrderRechargeList = this.tradeOrderRechargeMapper.selectList(Wrappers.lambdaQuery(TradeOrderRecharge.class)
              .eq(TradeOrderRecharge::getTradeId, tradeId)
              .between(TradeOrderRecharge::getCreateTime, timeRange.get(0), timeRange.get(1)));
      log.info("[交易记录] queryOrderRechargeTrade 结束");
      return tradeOrderRechargeList;
   }

   @Override
   public TradeRecord getTradeRecordByOrderRechargeId(Long orderRechargeId, Integer... tradeState) {
      log.info("[交易记录] getTradeRecordByOrderRechargeId 开始");
      List<LocalDateTime> timeRange = LeOrderUtil.queryCreateTimeRange();
      List<TradeRecord> tradeRecords = ((TradeRecordMapper)this.baseMapper).listTradeRecordByOrderRechargeId(orderRechargeId, (LocalDateTime)timeRange.get(0), (LocalDateTime)timeRange.get(1), tradeState);
      log.info("[交易记录] getTradeRecordByOrderRechargeId 结束");
      return (TradeRecord)CollUtil.getFirst(tradeRecords);
   }

   public void updateTradeRecordState(Long tradeId, UnifyRefundVO refundVO) {
      this.updateTradeRecordState(tradeId, refundVO.getCode(), refundVO.getMsg(), refundVO.getOutTradeNo()
              , null, null, null, null);
   }
}
