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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.bonus.canteen.core.customer.vo.CustPayVO;
import com.bonus.canteen.core.order.utils.LeNumUtil;
import com.bonus.canteen.core.pay.common.constants.LeRetCodeEnum;
import com.bonus.canteen.core.pay.common.constants.PayChannelEnum;

import java.util.Iterator;
import java.util.List;

public class PayChannelSelectResultVO {
   private Integer payType;
   private Integer payChannel;
   private List<ErrorInfo> errorInfoList = CollUtil.newArrayList(new ErrorInfo[0]);
   private List<PayChannelSplitVO> payChannelSplits = CollUtil.newArrayList(new PayChannelSplitVO[0]);
   private String couponId;
   private String openId;
   private String alipayContractNum;
   private boolean queriedAliContractNum;
   private CustPayVO custPayVO;

   public static PayChannelSelectResultVO of(PayChannelSelectDTO dto) {
      PayChannelSelectResultVO vo = new PayChannelSelectResultVO();
      vo.setCouponId(dto.getCouponNum());
      vo.setOpenId(dto.getOpenId());
      return vo;
   }

   public Integer getPayType() {
      return CollUtil.isNotEmpty(this.payChannelSplits) ? ((PayChannelSplitVO)CollUtil.getLast(this.payChannelSplits)).getPayType() : this.payType;
   }

   public Integer getPayChannel() {
      if (CollUtil.isEmpty(this.payChannelSplits)) {
         return this.payChannel;
      } else {
         return CollUtil.size(this.payChannelSplits) == 1 ? ((PayChannelSplitVO)CollUtil.getFirst(this.payChannelSplits)).getPayChannel() : PayChannelEnum.MIXTURE.getKey();
      }
   }

   public void setPayChannelSplit(PayChannelSplitVO payChannelSplitVO) {
      this.payChannelSplits = CollUtil.newArrayList(new PayChannelSplitVO[]{payChannelSplitVO});
   }

   public void setPayChannelSplit(Integer payType, Integer payChannel) {
      this.setPayChannelSplit(PayChannelSplitVO.of(payType, payChannel));
   }

   public void addPayChannelSplit(PayChannelSplitVO payChannelSplitVO, boolean insertFirstIfNotExists) {
      Iterator var3 = this.payChannelSplits.iterator();

      PayChannelSplitVO channelSplitVO;
      do {
         if (!var3.hasNext()) {
            if (insertFirstIfNotExists) {
               this.payChannelSplits.add(0, payChannelSplitVO);
            } else {
               this.payChannelSplits.add(payChannelSplitVO);
            }

            return;
         }

         channelSplitVO = (PayChannelSplitVO)var3.next();
      } while(!channelSplitVO.getPayType().equals(payChannelSplitVO.getPayType()) && !channelSplitVO.getPayChannel().equals(payChannelSplitVO.getPayChannel()));

      channelSplitVO.setPayType(payChannelSplitVO.getPayType());
      channelSplitVO.setPayChannel(payChannelSplitVO.getPayChannel());
   }

   public void addPayChannelSplit(Integer payType, Integer payChannel) {
      this.addPayChannelSplit(PayChannelSplitVO.of(payType, payChannel), false);
   }

   public void addPayChannelSplitFirst(Integer payType, Integer payChannel) {
      this.addPayChannelSplit(PayChannelSplitVO.of(payType, payChannel), true);
   }

   public void removePayChannel(Integer payChannel) {
      this.payChannelSplits.removeIf((s) -> {
         return s.getPayChannel().equals(payChannel);
      });
   }

   public void switchPayChannel(Integer oldChannel, Integer newChannel, Integer newPayType) {
      this.payChannelSplits.stream().filter((s) -> {
         return s.getPayChannel().equals(oldChannel);
      }).forEach((s) -> {
         s.setPayChannel(newChannel);
         s.setPayType(newPayType);
      });
   }

   public boolean containsPayChannel(Integer payChannel) {
      return this.payChannelSplits.stream().anyMatch((s) -> {
         return s.getPayChannel().equals(payChannel);
      });
   }

   public boolean containsPayType(Integer payType) {
      return this.payChannelSplits.stream().anyMatch((s) -> {
         return s.getPayType().equals(payType);
      });
   }

   public boolean noValidPayChannel() {
      return !LeNumUtil.isValidId(this.getPayChannel());
   }

   public void setErrorInfo(Exception e) {
      Integer errorCode = LeRetCodeEnum.FAIL.getKey();
      this.setErrorInfo(errorCode, e.getMessage());
   }

   public void setErrorInfo(Integer errorCode, String errorMsg) {
      this.errorInfoList.add(ErrorInfo.of(errorCode, errorMsg));
   }

   public void setErrorInfo(LeRetCodeEnum errorEnum) {
      this.errorInfoList.add(ErrorInfo.of(errorEnum.getKey(), errorEnum.getDesc()));
   }

   public boolean hasErrorInfo() {
      return CollUtil.isNotEmpty(this.errorInfoList);
   }

   public Integer getErrorCode() {
      return this.hasErrorInfo() ? ((ErrorInfo)this.errorInfoList.get(0)).getErrorCode() : null;
   }

   public String getErrorMsg() {
      return this.hasErrorInfo() ? ((ErrorInfo)this.errorInfoList.get(0)).getErrorMsg() : null;
   }

   public void removeErrorInfoIfCode(Integer... errorCodes) {
      this.errorInfoList.removeIf((e) -> {
         return ArrayUtil.contains(errorCodes, e.getErrorCode());
      });
   }

   public List<ErrorInfo> getErrorInfoList() {
      return this.errorInfoList;
   }

   public List<PayChannelSplitVO> getPayChannelSplits() {
      return this.payChannelSplits;
   }

   public String getCouponId() {
      return this.couponId;
   }

   public String getOpenId() {
      return this.openId;
   }

   public String getAlipayContractNum() {
      return this.alipayContractNum;
   }

   public boolean isQueriedAliContractNum() {
      return this.queriedAliContractNum;
   }

   public CustPayVO getCustPayVO() {
      return this.custPayVO;
   }

   public void setCouponId(final String couponId) {
      this.couponId = couponId;
   }

   public void setOpenId(final String openId) {
      this.openId = openId;
   }

   public void setAlipayContractNum(final String alipayContractNum) {
      this.alipayContractNum = alipayContractNum;
   }

   public void setQueriedAliContractNum(final boolean queriedAliContractNum) {
      this.queriedAliContractNum = queriedAliContractNum;
   }

   public void setCustPayVO(final CustPayVO custPayVO) {
      this.custPayVO = custPayVO;
   }

   public static class ErrorInfo {
      private Integer errorCode;
      private String errorMsg;

      public static ErrorInfo of(Integer errorCode, String errorMsg) {
         ErrorInfo info = new ErrorInfo();
         info.setErrorCode(errorCode);
         info.setErrorMsg(errorMsg);
         return info;
      }

      public Integer getErrorCode() {
         return this.errorCode;
      }

      public String getErrorMsg() {
         return this.errorMsg;
      }

      public void setErrorCode(final Integer errorCode) {
         this.errorCode = errorCode;
      }

      public void setErrorMsg(final String errorMsg) {
         this.errorMsg = errorMsg;
      }
   }
}
