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

import cn.hutool.core.collection.CollUtil;
import com.bonus.canteen.core.account.v3.api.vo.AccExceptionRecordApiVO;
import com.bonus.canteen.core.pay.common.constants.PayChannelEnum;
import com.bonus.canteen.core.pay.common.constants.PayStateEnum;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

public class OrderTradeInfoVO {
   private Long orderRechargeId;
   private List<Trade> tradeList = CollUtil.newArrayList(new Trade[0]);

   public Trade findLastTrade() {
      if (CollUtil.isEmpty(this.tradeList)) {
         return null;
      } else {
         Trade lastTrade = this.findPartPayTrade();
         if (lastTrade == null) {
            lastTrade = (Trade)this.tradeList.stream().filter((s) -> {
               return PayStateEnum.isPayingState(s.getTradeState());
            }).findFirst().orElse(null);
         }

         return lastTrade;
      }
   }

   public Trade findPartPayTrade() {
      return CollUtil.isEmpty(this.tradeList) ? null : (Trade)this.tradeList.stream().filter((s) -> {
         return PayStateEnum.isPartPayState(s.getTradeState());
      }).findFirst().orElse(null);
   }

   public AccExceptionRecordApiVO findAccException() {
      Trade trade = this.findPartPayTrade();
      return trade == null ? null : trade.getAccExceptionRecord();
   }

   public static OrderTradeInfoVO of(Long orderRechargeId, List<Trade> tradeList) {
      OrderTradeInfoVO orderTradeInfoVO = new OrderTradeInfoVO();
      orderTradeInfoVO.setOrderRechargeId(orderRechargeId);
      orderTradeInfoVO.setTradeList(tradeList);
      return orderTradeInfoVO;
   }

   public Long getOrderRechargeId() {
      return this.orderRechargeId;
   }

   public List<Trade> getTradeList() {
      return this.tradeList;
   }

   public void setOrderRechargeId(final Long orderRechargeId) {
      this.orderRechargeId = orderRechargeId;
   }

   public void setTradeList(final List<Trade> tradeList) {
      this.tradeList = tradeList;
   }

   public static class Trade {
      private Long orderRechargeId;
      private Long tradeId;
      private String outTradeNo;
      private Integer tradeState;
      private String tradeResult;
      private AccExceptionRecordApiVO accExceptionRecord;
      private List<Channel> channelList = CollUtil.newArrayList(new Channel[0]);

      public Channel findLastAccChannel() {
         return CollUtil.isEmpty(this.channelList) ? null : (Channel)this.channelList.stream().filter((s) -> {
            return PayChannelEnum.ACC.getKey().equals(s.getPayChannel());
         }).findFirst().orElse(null);
      }

      public Long getOrderRechargeId() {
         return this.orderRechargeId;
      }

      public Long getTradeId() {
         return this.tradeId;
      }

      public String getOutTradeNo() {
         return this.outTradeNo;
      }

      public Integer getTradeState() {
         return this.tradeState;
      }

      public String getTradeResult() {
         return this.tradeResult;
      }

      public AccExceptionRecordApiVO getAccExceptionRecord() {
         return this.accExceptionRecord;
      }

      public List<Channel> getChannelList() {
         return this.channelList;
      }

      public void setOrderRechargeId(final Long orderRechargeId) {
         this.orderRechargeId = orderRechargeId;
      }

      public void setTradeId(final Long tradeId) {
         this.tradeId = tradeId;
      }

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

      public void setTradeState(final Integer tradeState) {
         this.tradeState = tradeState;
      }

      public void setTradeResult(final String tradeResult) {
         this.tradeResult = tradeResult;
      }

      public void setAccExceptionRecord(final AccExceptionRecordApiVO accExceptionRecord) {
         this.accExceptionRecord = accExceptionRecord;
      }

      public void setChannelList(final List<Channel> channelList) {
         this.channelList = channelList;
      }

   }

   public static class Channel {
      private Long tradeId;
      private Long tradeChannelId;
      private Integer tradeState;
      private String tradeResult;
      private Integer payType;
      private Integer payChannel;
      private BigDecimal amount;
      private String outTradeNo;
      private LocalDateTime tradeTime;

      public Long getTradeId() {
         return this.tradeId;
      }

      public Long getTradeChannelId() {
         return this.tradeChannelId;
      }

      public Integer getTradeState() {
         return this.tradeState;
      }

      public String getTradeResult() {
         return this.tradeResult;
      }

      public Integer getPayType() {
         return this.payType;
      }

      public Integer getPayChannel() {
         return this.payChannel;
      }

      public BigDecimal getAmount() {
         return this.amount;
      }

      public String getOutTradeNo() {
         return this.outTradeNo;
      }

      public LocalDateTime getTradeTime() {
         return this.tradeTime;
      }

      public void setTradeId(final Long tradeId) {
         this.tradeId = tradeId;
      }

      public void setTradeChannelId(final Long tradeChannelId) {
         this.tradeChannelId = tradeChannelId;
      }

      public void setTradeState(final Integer tradeState) {
         this.tradeState = tradeState;
      }

      public void setTradeResult(final String tradeResult) {
         this.tradeResult = tradeResult;
      }

      public void setPayType(final Integer payType) {
         this.payType = payType;
      }

      public void setPayChannel(final Integer payChannel) {
         this.payChannel = payChannel;
      }

      public void setAmount(final BigDecimal amount) {
         this.amount = amount;
      }

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

      public void setTradeTime(final LocalDateTime tradeTime) {
         this.tradeTime = tradeTime;
      }

   }
}
