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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.bonus.canteen.core.pay.common.constants.PayStateEnum;
import com.bonus.canteen.core.pay.common.model.TradeRecord;
import com.bonus.canteen.core.pay.common.vo.TradeChannelVO;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

public class UnifyRefundVO {
   private Integer code;
   private String msg;
   private Long refundTradeId;
   private String outTradeNo;
   private BigDecimal refundAmount;
   private List<TradeChannelVO> refundDetailList = CollUtil.newArrayList(new TradeChannelVO[0]);

   public String getOutTradeNo() {
      return (String)this.refundDetailList.stream().sorted(Comparator.comparing(TradeChannelVO::getTradeChannelId).reversed()).map(TradeChannelVO::getOutTradeNo).filter(CharSequenceUtil::isNotEmpty).findFirst().orElse(null);
   }

   public void fillChannelRefund(TradeChannelVO tradeChannelVO) {
      this.code = tradeChannelVO.getTradeState();
      this.msg = tradeChannelVO.getTradeResult();
   }

   public BigDecimal getRefundAmount() {
      return PayStateEnum.isPaidState(this.code) && CollUtil.isNotEmpty(this.refundDetailList) ? (BigDecimal)this.refundDetailList.stream().filter((s) -> {
         return PayStateEnum.isPaidState(s.getTradeState());
      }).map(TradeChannelVO::getAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add) : this.refundAmount;
   }

   public static UnifyRefundVO newInstanceOf(Long refundTradeId, List<TradeChannelVO> refundTradeChannels) {
      UnifyRefundVO payRefundVO = new UnifyRefundVO();
      payRefundVO.setRefundTradeId(refundTradeId);
      payRefundVO.setCode(PayStateEnum.PAY_INPROCESS.getKey());
      payRefundVO.setMsg(PayStateEnum.PAY_INPROCESS.getDesc());
      payRefundVO.setRefundAmount(BigDecimal.ZERO);
      payRefundVO.setRefundDetailList(CollUtil.isNotEmpty(refundTradeChannels) ? CollUtil.newArrayList(refundTradeChannels) : CollUtil.newArrayList(new TradeChannelVO[0]));
      return payRefundVO;
   }

   public static UnifyRefundVO of(TradeRecord refundTradeRecord, List<TradeChannelVO> refundTradeChannels) {
      UnifyRefundVO payRefundVO = new UnifyRefundVO();
      payRefundVO.setCode(refundTradeRecord.getTradeState());
      payRefundVO.setMsg(refundTradeRecord.getTradeResult());
      payRefundVO.setRefundTradeId(refundTradeRecord.getId());
      payRefundVO.setOutTradeNo(refundTradeRecord.getOutTradeNo());
      payRefundVO.setRefundAmount(refundTradeRecord.getAmount());
      payRefundVO.setRefundDetailList(refundTradeChannels);
      return payRefundVO;
   }

   public Integer getCode() {
      return this.code;
   }

   public String getMsg() {
      return this.msg;
   }

   public Long getRefundTradeId() {
      return this.refundTradeId;
   }

   public List<TradeChannelVO> getRefundDetailList() {
      return this.refundDetailList;
   }

   public void setCode(final Integer code) {
      this.code = code;
   }

   public void setMsg(final String msg) {
      this.msg = msg;
   }

   public void setRefundTradeId(final Long refundTradeId) {
      this.refundTradeId = refundTradeId;
   }

   public void setOutTradeNo(final String outTradeNo) {
      this.outTradeNo = outTradeNo;
   }

   public void setRefundAmount(final BigDecimal refundAmount) {
      this.refundAmount = refundAmount;
   }

   public void setRefundDetailList(final List<TradeChannelVO> refundDetailList) {
      this.refundDetailList = refundDetailList;
   }
}
