package com.bonus.canteen.core.account.v3.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
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.common.core.exception.ServiceException;
import com.bonus.canteen.core.account.v3.mapper.AccTradeWalletDetailMapper;
import com.bonus.canteen.core.account.v3.metadata.enums.AccWalletIdEnum;
import com.bonus.canteen.core.account.v3.model.AccTradeWalletDetail;
import com.bonus.canteen.core.account.v3.mq.send.model.RepAccMqDetailModel;
import com.bonus.canteen.core.account.v3.po.AccOrdTradeDetailPO;
import com.bonus.canteen.core.account.v3.po.AccTradeWalletPO;
import com.bonus.canteen.core.account.v3.service.AccTradeWalletDetailService;
import com.bonus.canteen.core.account.v3.web.vo.AccOrdTradeVO;
import com.bonus.canteen.core.account.v3.po.AccWalletPayPO;
import com.bonus.common.houqin.i18n.I18n;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class AccTradeWalletDetailServiceImpl extends ServiceImpl<AccTradeWalletDetailMapper, AccTradeWalletDetail> implements AccTradeWalletDetailService {
   private static final Logger log = LoggerFactory.getLogger(AccTradeWalletDetailServiceImpl.class);


   @Override
   public List<AccTradeWalletDetail> listCustMonthAccSubsidyExpirationTrade(Long custId) {
      return ((AccTradeWalletDetailMapper)this.baseMapper).listCustMonthAccSubsidyExpirationTrade(custId, LocalDateTime.now(), LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).atTime(23, 59, 59));
   }

   @Override
   public int insertAccTradeWalletDetail(AccTradeWalletPO accTradeWalletPo) {
      AccTradeWalletDetail accTradeWalletDetail = new AccTradeWalletDetail();
      BeanUtil.copyProperties(accTradeWalletPo, accTradeWalletDetail, new String[0]);
      log.info("[账户交易明细]新增开始:{}", JSONUtil.toJsonStr(accTradeWalletDetail));
      int insert = ((AccTradeWalletDetailMapper)this.baseMapper).insert(accTradeWalletDetail);
      log.info("[账户交易明细]新增结束");
      return insert;
   }

   @Override
   public List<RepAccMqDetailModel> listAccTradeWalletDetailForSend(List<Long> tradeIdList) {
      return ((AccTradeWalletDetailMapper)this.baseMapper).listAccTradeWalletDetailForSend(tradeIdList);
   }

   @Override
   public List<Long> selectCustIdForSubsidyExpireTime(LocalDateTime now) {
      return ((AccTradeWalletDetailMapper)this.baseMapper).selectCustIdForSubsidyExpireTime(now);
   }
   @Override
   public void updateExpiredClearTradeUseAmount(Long id, BigDecimal useAmount) {
      ((AccTradeWalletDetailMapper)this.baseMapper).update(null,Wrappers.<AccTradeWalletDetail>lambdaUpdate()
              .setSql(true, "use_amount = use_amount + " + useAmount)
              .eq(AccTradeWalletDetail::getId, id));
   }


   @Override
   public AccTradeWalletDetail selectOneSubsidyExpirationTrade(Long custId) {
      LocalDateTime localDateTime = LocalDate.now().atTime(0, 0, 0);
      return ((AccTradeWalletDetailMapper)this.baseMapper).selectOneSubsidyExpirationTrade(custId, localDateTime);
   }

   @Override
   public List<AccTradeWalletDetail> queryAccTradeWalletDetailByLeOrdNo(Long orderId, List<Integer> tradeTypeList) {
      return ((AccTradeWalletDetailMapper)this.baseMapper).queryAccTradeWalletDetailByLeOrdNo(orderId, tradeTypeList);
   }

   @Override
   public List<AccTradeWalletDetail> queryAccTradeWalletDetailByOriginTradeId(Long originTradeId, Integer tradeType) {
      return ((AccTradeWalletDetailMapper)this.baseMapper).queryAccTradeWalletDetailByOriginTradeId(originTradeId, tradeType);
   }

   public AccOrdTradeVO queryAccTradeOrderDetailByLeOrderNo(Long leOrderNo) {
      log.info("根据订单id查询交易明细,orderId_{}", leOrderNo);
      List<AccOrdTradeDetailPO> list = ((AccTradeWalletDetailMapper)this.baseMapper).queryAccTradeOrderDetailByLeOrderNo(leOrderNo, (List)null);
      if (ObjectUtil.isEmpty(list)) {
         throw new ServiceException(I18n.getMessage("acc_ord_not_releat_record", new Object[0]));
      } else {
         return this.getAccOrdTradeVOByTradeDetailList(list);
      }
   }

   protected AccOrdTradeVO getAccOrdTradeVOByTradeDetailList(List<AccOrdTradeDetailPO> list) {
      if (ObjectUtil.isEmpty(list)) {
         throw new ServiceException(I18n.getMessage("acc_ord_not_releat_record", new Object[0]));
      } else {
         AccOrdTradeVO accOrdTradeVO = new AccOrdTradeVO();
         Map<Integer, AccOrdTradeDetailPO> tradeDetailMap = list.stream().collect(Collectors.toMap(AccWalletPayPO::getWalletId, Function.identity()));
         accOrdTradeVO.setOrderId(((AccOrdTradeDetailPO)list.get(0)).getLeOrdNo());
         accOrdTradeVO.setWalletPay(ObjectUtil.isNotNull(tradeDetailMap.get(AccWalletIdEnum.WALLET.getKey())) ? ((AccOrdTradeDetailPO)tradeDetailMap.get(AccWalletIdEnum.WALLET.getKey())).getAmount() : BigDecimal.ZERO);
         accOrdTradeVO.setSubsidyPay(ObjectUtil.isNotNull(tradeDetailMap.get(AccWalletIdEnum.SUBSIDY.getKey())) ? ((AccOrdTradeDetailPO)tradeDetailMap.get(AccWalletIdEnum.SUBSIDY.getKey())).getAmount() : BigDecimal.ZERO);
         accOrdTradeVO.setRedEnvelopePay(ObjectUtil.isNotNull(tradeDetailMap.get(AccWalletIdEnum.LUCK_MONEY.getKey())) ? ((AccOrdTradeDetailPO)tradeDetailMap.get(AccWalletIdEnum.LUCK_MONEY.getKey())).getAmount() : BigDecimal.ZERO);
         accOrdTradeVO.setWalletBal(ObjectUtil.isNotNull(tradeDetailMap.get(AccWalletIdEnum.WALLET.getKey())) ? ((AccOrdTradeDetailPO)tradeDetailMap.get(AccWalletIdEnum.WALLET.getKey())).getWalletBal() : BigDecimal.ZERO);
         accOrdTradeVO.setSubBal(ObjectUtil.isNotNull(tradeDetailMap.get(AccWalletIdEnum.SUBSIDY.getKey())) ? ((AccOrdTradeDetailPO)tradeDetailMap.get(AccWalletIdEnum.SUBSIDY.getKey())).getWalletBal() : BigDecimal.ZERO);
         accOrdTradeVO.setRedBal(ObjectUtil.isNotNull(tradeDetailMap.get(AccWalletIdEnum.LUCK_MONEY.getKey())) ? ((AccOrdTradeDetailPO)tradeDetailMap.get(AccWalletIdEnum.LUCK_MONEY.getKey())).getWalletBal() : BigDecimal.ZERO);
         accOrdTradeVO.setAccBal(((AccOrdTradeDetailPO)list.get(0)).getWalletBalTotal());
         return accOrdTradeVO;
      }
   }

   public Map<Long, List<AccTradeWalletDetail>> queryAccTradeWalletDetailByTradeIdList(List<Long> tradeIdList) {
      List<AccTradeWalletDetail> list = ((AccTradeWalletDetailMapper)this.baseMapper).queryAccTradeWalletDetailByTradeIdList(tradeIdList);
      return (Map)(ObjectUtil.isEmpty(list) ? Maps.newHashMap() : (Map)list.stream().collect(Collectors.groupingBy(AccTradeWalletDetail::getTradeId)));
   }

}
