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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import com.bonus.common.houqin.constant.LeConstants;
import com.bonus.canteen.core.account.v3.api.dto.AccOrdBaseDTO;
import com.bonus.canteen.core.common.utils.TenantContextHolder;
import com.bonus.canteen.core.marketing.v2.rule.price.dto.RulePriceResultDTO;
import com.bonus.canteen.core.order.utils.LeNumUtil;
import com.bonus.canteen.core.pay.api.dto.UnifyPayDTO;
import com.bonus.canteen.core.pay.channel.cmb.dto.QrCodeApplyDTO;
import com.bonus.canteen.core.pay.common.constants.PayChannelEnum;
import com.bonus.canteen.core.pay.common.constants.PayChannelSelectEnum;
import com.bonus.canteen.core.pay.common.constants.PayStateEnum;
import com.bonus.canteen.core.pay.common.constants.PayTypeEnum;
import com.bonus.canteen.core.pay.common.model.TradeChannel;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.JsonNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.function.Function;

public class ChannelPayDTO {
   private static final Logger log = LoggerFactory.getLogger(ChannelPayDTO.class);
   private Integer scenario;
   private Long tradeChannelId;
   private String outTradeNo;
   private BigDecimal amount;
   private BigDecimal totalAmount;
   private Integer payType;
   private Integer payChannel;
   private Integer tradeType;
   private boolean payForMix = false;
   private LocalDateTime orderTime;
   private LocalDateTime tradeTime;
   private Integer sourceType;
   private Long custId;
   private String custThirdId;
   private String custName;
   private String custNum;
   private String mobile;
   private String orgFullName;
   private String custPhotoUrl;
   private String serialNum;
   private String thirdSerialNum;
   private LocalDate validityDate;
   private String machineName;
   private String machineSn;
   private String machineNum;
   private Integer nuClearMode;
   private String remark;
   private List<UnifyPayDTO.Order> orderList;
   private List<UnifyPayDTO.Detail> detailList;
   private RulePriceResultDTO rulePriceResult;
   private String couponId;
   private String openid;
   private String authCode;
   private String terminalParams;
   private String alipayContractNum;
   private Integer alipayFaceAsync;
   private String attach;
   private String abchDeviceKey;
   private String payPassword;
   private JsonNode extParam;

   public Integer getOnlineState() {
      return PayChannelSelectEnum.isDeviceOffline(this.scenario) ? LeConstants.COMMON_NO : LeConstants.COMMON_YES;
   }

   public String getAttach() {
      Long var10000 = TenantContextHolder.getTenantId();
      return "" + var10000 + "_" + String.valueOf(this.canteenId() != null ? this.canteenId() : "");
   }

   @JsonIgnore
   public boolean isDeviceOnline() {
      return PayChannelSelectEnum.isDeviceOnline(this.scenario);
   }

   @JsonIgnore
   public boolean isDeviceOffline() {
      return PayChannelSelectEnum.isDeviceOffline(this.scenario);
   }

   public <T> T reduceOrderField(Function<UnifyPayDTO.Order, T> func, T defaultValue) {
      return LeNumUtil.reduceField(this.orderList, func, defaultValue);
   }

   public boolean couldSkipChannelPay() {
      return this.getAmount().intValue() == 0 && !PayChannelEnum.THIRD.getKey().equals(this.getPayChannel()) && !PayChannelEnum.ACC.getKey().equals(this.getPayChannel()) && !PayChannelEnum.COUPON.getKey().equals(this.getPayChannel()) && !PayTypeEnum.WECHAT_WITHHOLD.getKey().equals(this.getPayType()) && !PayTypeEnum.ALI_ENTERPRISE_WITHHOLD.getKey().equals(this.getPayType());
   }

   public Long canteenId() {
      return (Long)this.reduceOrderField(UnifyPayDTO.Order::getCanteenId, (Object)null);
   }

   public String canteenName() {
      return (String)this.reduceOrderField(UnifyPayDTO.Order::getCanteenName, "");
   }

   public String macOrderId() {
      return (String)this.reduceOrderField(UnifyPayDTO.Order::getMacOrderId, "");
   }

   public TradeChannel toTradeRecordChannel(Long tradeId) {
      TradeChannel tradeChannel = new TradeChannel();
      tradeChannel.setTradeId(tradeId);
      tradeChannel.setTradeChannelId(this.tradeChannelId);
      tradeChannel.setAmount(this.getAmount());
      tradeChannel.setRefundAmount(BigDecimal.ZERO);
      tradeChannel.setPayType(this.getPayType());
      tradeChannel.setPayChannel(this.getPayChannel());
      tradeChannel.setTradeState(PayStateEnum.PAY_INPROCESS.getKey());
      tradeChannel.setOutTradeNo(this.getOutTradeNo());
      return tradeChannel;
   }

   public MobilePayDTO convertToMobilePayDTO() {
      MobilePayDTO mobilePayDTO = (MobilePayDTO)BeanUtil.copyProperties(this, MobilePayDTO.class, new String[0]);
      this.copyProperties(this, mobilePayDTO);
      mobilePayDTO.setIfRecharge(PayChannelSelectEnum.isRecharge(this.scenario));
      return mobilePayDTO;
   }

   public AndroidPayDTO convertToAndroidPayDTO() {
      AndroidPayDTO androidPayDTO = (AndroidPayDTO)BeanUtil.copyProperties(this, AndroidPayDTO.class, new String[0]);
      this.copyProperties(this, androidPayDTO);
      androidPayDTO.setAuthCode(this.getAuthCode());
      androidPayDTO.setTerminalParams(this.getTerminalParams());
      androidPayDTO.setMacOrderId((String)this.reduceOrderField(UnifyPayDTO.Order::getMacOrderId, (Object)null));
      androidPayDTO.setSerialNum(this.getSerialNum());
      androidPayDTO.setMachineSn(this.getMachineSn());
      androidPayDTO.setMachineNum(this.getMachineNum());
      androidPayDTO.setCustId(this.getCustId());
      androidPayDTO.setNuClearMode(this.getNuClearMode());
      androidPayDTO.setIfRecharge(PayChannelSelectEnum.isRecharge(this.scenario));
      return androidPayDTO;
   }

   public QrCodeApplyDTO convertToQrCodeApplyDTO() {
      QrCodeApplyDTO androidPayDTO = (QrCodeApplyDTO)BeanUtil.copyProperties(this, QrCodeApplyDTO.class, new String[0]);
      androidPayDTO.setOrderId(this.getTradeChannelId());
      androidPayDTO.setAmount(this.getAmount().intValue());
      androidPayDTO.setAbcDeviceKey(this.getAbchDeviceKey());
      return androidPayDTO;
   }

   public AccOrdBaseDTO convertToAccPayDTO() {
      AccOrdBaseDTO accPayDTO = (AccOrdBaseDTO)BeanUtil.copyProperties(this, AccOrdBaseDTO.class, new String[0]);
      accPayDTO.setCustId(this.getCustId());
      accPayDTO.setOrderId(this.getTradeChannelId());
      accPayDTO.setIfTrialCalculation(false);
      if (this.getRulePriceResult() != null) {
         accPayDTO.setRulePriceResult(this.getRulePriceResult());
      } else {
         accPayDTO.setRulePriceResult((new RulePriceResultDTO()).setRealAmount(this.getAmount()));
      }

      if (!NumberUtil.equals(this.getAmount(), accPayDTO.getRulePriceResult().getRealAmount())) {
         log.warn("发起支付金额与消费规则结果金额不一致：{}，{}", this.getAmount(), this.getRulePriceResult().getRealAmount());
         this.getRulePriceResult().setRealAmount(this.getAmount());
      }

      accPayDTO.setCanteenId((Long)this.reduceOrderField(UnifyPayDTO.Order::getCanteenId, (Object)null));
      accPayDTO.setCanteenName((String)this.reduceOrderField(UnifyPayDTO.Order::getCanteenName, (Object)null));
      accPayDTO.setShopstallId((Long)this.reduceOrderField(UnifyPayDTO.Order::getStallId, (Object)null));
      accPayDTO.setShopstallName((String)this.reduceOrderField(UnifyPayDTO.Order::getStallName, (Object)null));
      accPayDTO.setMchNum(this.getMachineNum());
      accPayDTO.setMchSn(this.getMachineSn());
      accPayDTO.setOrdTime(this.getOrderTime());
      accPayDTO.setNuClearMode(this.getNuClearMode());
      accPayDTO.setIfOnline(this.getOnlineState());
      accPayDTO.setRemark(this.getRemark());
      accPayDTO.setSourceType(this.getSourceType());
      accPayDTO.setOrderType(CollUtil.isNotEmpty(this.getOrderList()) ? ((UnifyPayDTO.Order)this.getOrderList().get(0)).getOrderType() : null);
      accPayDTO.setExtParam(this.getExtParam());
      return accPayDTO;
   }

   private void copyProperties(ChannelPayDTO payDTO, PayBaseDTO payBaseDTO) {
      payBaseDTO.setTradeId(payDTO.getTradeChannelId());
      payBaseDTO.setAmount(BigDecimal.valueOf(payDTO.getAmount().longValue()));
      payBaseDTO.setPayType(payDTO.getPayType());
      payBaseDTO.setPayChannel(payDTO.getPayChannel());
      payBaseDTO.setTradeType(payDTO.getTradeType());
      payBaseDTO.setCustId(payDTO.getCustId());
      payBaseDTO.setCustName(payDTO.getCustName());
      payBaseDTO.setCustNum(payDTO.getCustNum());
      payBaseDTO.setOpenid(payDTO.getOpenid());
      payBaseDTO.setSourceType(payDTO.getSourceType());
      payBaseDTO.setRemark(payDTO.getRemark());
      payBaseDTO.setAttach(payDTO.getAttach());
      payBaseDTO.setThirdSerialNum(payDTO.getThirdSerialNum());
      payBaseDTO.setCustThirdId(payDTO.getCustThirdId());
      payBaseDTO.setCanteenId((Long)payDTO.reduceOrderField(UnifyPayDTO.Order::getCanteenId, (Object)null));
      payBaseDTO.setCanteenName((String)payDTO.reduceOrderField(UnifyPayDTO.Order::getCanteenName, (Object)null));
      payBaseDTO.setStallId((Long)payDTO.reduceOrderField(UnifyPayDTO.Order::getStallId, (Object)null));
      payBaseDTO.setStallName((String)payDTO.reduceOrderField(UnifyPayDTO.Order::getStallName, (Object)null));
      payBaseDTO.setMealtimeType((Integer)payDTO.reduceOrderField(UnifyPayDTO.Order::getMealtimeType, (Object)null));
      payBaseDTO.setMealtimeName((String)payDTO.reduceOrderField(UnifyPayDTO.Order::getMealtimeName, (Object)null));
      payBaseDTO.setOrderTime((LocalDateTime)payDTO.reduceOrderField(UnifyPayDTO.Order::getOrderTime, LocalDateTime.now()));
      payBaseDTO.setOrderList(payDTO.getOrderList());
   }

   public static String[] logFields() {
      return new String[]{"tradeId", "amount", "payType", "payChannel", "tradeType", "custId", "custName", "custNum", "openid", "couponId", "sourceType", "remark", "attach", "thirdSerialNum", "custThirdId", "canteenId", "canteenName", "stallId", "stallName", "mealtimeType", "mealtimeName", "orderTime", "authCode", "terminalParams", "serialNum", "machineSn", "machineNum", "nuClearMode", "mktTimeQuotaPayDTO", "rulePriceResult"};
   }

   public static String[] logFieldsAmount() {
      return new String[]{"tradeId", "amount", "payType", "payChannel", "tradeType", "custId", "couponId", "sourceType", "mktTimeQuotaPayDTO", "rulePriceResult"};
   }

   public Integer getScenario() {
      return this.scenario;
   }

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

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

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

   public BigDecimal getTotalAmount() {
      return this.totalAmount;
   }

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

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

   public Integer getTradeType() {
      return this.tradeType;
   }

   public boolean isPayForMix() {
      return this.payForMix;
   }

   public LocalDateTime getOrderTime() {
      return this.orderTime;
   }

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

   public Integer getSourceType() {
      return this.sourceType;
   }

   public Long getCustId() {
      return this.custId;
   }

   public String getCustThirdId() {
      return this.custThirdId;
   }

   public String getCustName() {
      return this.custName;
   }

   public String getCustNum() {
      return this.custNum;
   }

   public String getMobile() {
      return this.mobile;
   }

   public String getOrgFullName() {
      return this.orgFullName;
   }

   public String getCustPhotoUrl() {
      return this.custPhotoUrl;
   }

   public String getSerialNum() {
      return this.serialNum;
   }

   public String getThirdSerialNum() {
      return this.thirdSerialNum;
   }

   public LocalDate getValidityDate() {
      return this.validityDate;
   }

   public String getMachineName() {
      return this.machineName;
   }

   public String getMachineSn() {
      return this.machineSn;
   }

   public String getMachineNum() {
      return this.machineNum;
   }

   public Integer getNuClearMode() {
      return this.nuClearMode;
   }

   public String getRemark() {
      return this.remark;
   }

   public List<UnifyPayDTO.Order> getOrderList() {
      return this.orderList;
   }

   public List<UnifyPayDTO.Detail> getDetailList() {
      return this.detailList;
   }

   public RulePriceResultDTO getRulePriceResult() {
      return this.rulePriceResult;
   }

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

   public String getOpenid() {
      return this.openid;
   }

   public String getAuthCode() {
      return this.authCode;
   }

   public String getTerminalParams() {
      return this.terminalParams;
   }

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

   public Integer getAlipayFaceAsync() {
      return this.alipayFaceAsync;
   }

   public String getAbchDeviceKey() {
      return this.abchDeviceKey;
   }

   public String getPayPassword() {
      return this.payPassword;
   }

   public JsonNode getExtParam() {
      return this.extParam;
   }

   public void setScenario(final Integer scenario) {
      this.scenario = scenario;
   }

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

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

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

   public void setTotalAmount(final BigDecimal totalAmount) {
      this.totalAmount = totalAmount;
   }

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

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

   public void setTradeType(final Integer tradeType) {
      this.tradeType = tradeType;
   }

   public void setPayForMix(final boolean payForMix) {
      this.payForMix = payForMix;
   }

   public void setOrderTime(final LocalDateTime orderTime) {
      this.orderTime = orderTime;
   }

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

   public void setSourceType(final Integer sourceType) {
      this.sourceType = sourceType;
   }

   public void setCustId(final Long custId) {
      this.custId = custId;
   }

   public void setCustThirdId(final String custThirdId) {
      this.custThirdId = custThirdId;
   }

   public void setCustName(final String custName) {
      this.custName = custName;
   }

   public void setCustNum(final String custNum) {
      this.custNum = custNum;
   }

   public void setMobile(final String mobile) {
      this.mobile = mobile;
   }

   public void setOrgFullName(final String orgFullName) {
      this.orgFullName = orgFullName;
   }

   public void setCustPhotoUrl(final String custPhotoUrl) {
      this.custPhotoUrl = custPhotoUrl;
   }

   public void setSerialNum(final String serialNum) {
      this.serialNum = serialNum;
   }

   public void setThirdSerialNum(final String thirdSerialNum) {
      this.thirdSerialNum = thirdSerialNum;
   }

   public void setValidityDate(final LocalDate validityDate) {
      this.validityDate = validityDate;
   }

   public void setMachineName(final String machineName) {
      this.machineName = machineName;
   }

   public void setMachineSn(final String machineSn) {
      this.machineSn = machineSn;
   }

   public void setMachineNum(final String machineNum) {
      this.machineNum = machineNum;
   }

   public void setNuClearMode(final Integer nuClearMode) {
      this.nuClearMode = nuClearMode;
   }

   public void setRemark(final String remark) {
      this.remark = remark;
   }

   public void setOrderList(final List<UnifyPayDTO.Order> orderList) {
      this.orderList = orderList;
   }

   public void setDetailList(final List<UnifyPayDTO.Detail> detailList) {
      this.detailList = detailList;
   }

   public void setRulePriceResult(final RulePriceResultDTO rulePriceResult) {
      this.rulePriceResult = rulePriceResult;
   }

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

   public void setOpenid(final String openid) {
      this.openid = openid;
   }

   public void setAuthCode(final String authCode) {
      this.authCode = authCode;
   }

   public void setTerminalParams(final String terminalParams) {
      this.terminalParams = terminalParams;
   }

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

   public void setAlipayFaceAsync(final Integer alipayFaceAsync) {
      this.alipayFaceAsync = alipayFaceAsync;
   }

   public void setAttach(final String attach) {
      this.attach = attach;
   }

   public void setAbchDeviceKey(final String abchDeviceKey) {
      this.abchDeviceKey = abchDeviceKey;
   }

   public void setPayPassword(final String payPassword) {
      this.payPassword = payPassword;
   }

   public void setExtParam(final JsonNode extParam) {
      this.extParam = extParam;
   }

}
