package cn.quant.baa.pay.jpa;

import cn.quant.baa.pay.acquirer.AcquirerProperties;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.dict.*;
import cn.quant.baa.pay.jpa.entity.*;
import cn.quant.baa.pay.model.web.GoodsDetail;
import cn.quant.baa.pay.model.web.PayRequestData;
import cn.quant.spring.util.DateUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;

import static cn.quant.baa.pay.Constant.MINI_LOCAL_DATE;
import static cn.quant.baa.pay.Constant.PAY_DUE_TIME;

/**
 * Created by Administrator on 2021/8/27 0027.
 */
public class EntityBuilder {

    public static int nextTxnNo(AccountEntity account, TransactionSummaryEntity history) {
        Integer txnNo = account.getNextTxnNo();
        account.setTxnNo(txnNo);
        account.setNextTxnNo(txnNo + 1);
        history.setTxnNo(txnNo);
        return txnNo;
    }

    public static AccountEntity account(AccountIds ids, String productId, long accountId, String buyerId, int partitionKey) {
        LocalDate now = LocalDate.now();
        AccountEntity account = new AccountEntity();
        account.setIds(ids);
        account.setAccountId(accountId);
        account.setAcctTypeId(AcctTypeId.EMPS);
        account.setAutoPaymentFlag(false);
        account.setAutoPaymentWarnDate(MINI_LOCAL_DATE);
        account.setAutoStatus(StatusCode.NORM);
        account.setAutoStatusDate(now);
        account.setCorpotateAcctFlag(false);
        account.setCreditTxnCount(0);
        account.setCurrencyCode(CurrencyCode.CNY);
        account.setCurrentCycleNo(1);
        account.setDebitTxtCount(0);
        account.setExternalAcctNo(buyerId);
        account.setManualStatus(null);
        account.setManualStatusDate(null);
        account.setNextTxnNo(1);
        account.setOpenDate(now);
        account.setProductId(productId);
        account.setProtocolRule(null);
        account.setTotalCredit(BigDecimal.ZERO);
        account.setTotalDebit(BigDecimal.ZERO);
        account.setTxnNo(0);

        Date date = DateUtils.now();
        account.setCreatedDate(date);
        account.setModifiedDate(date);
        account.setPartitionKey(partitionKey);
        return account;
    }

    public static TransactionSummaryEntity payHistory(AccountEntity account, long historyId, PayRequestData data, AcquirerProperties properties
            , TransactionSession session) {

        BigDecimal discount = new BigDecimal(data.getDiscounts());
        BigDecimal origAmt = new BigDecimal(data.getOriginalAmount());
        BigDecimal cash = new BigDecimal(data.getCashAmount());
        BigDecimal credit = new BigDecimal(data.getCreditAmount());
        BigDecimal amount = new BigDecimal(data.getAmount());
        String signer = data.getGoodsSigner();

        TransactionSummaryEntity entity = new TransactionSummaryEntity();
        entity.setInstitutionId(properties.getInstitutionId());
        entity.setProductId(properties.getProductId());
        entity.setAccountId(account.getAccountId());
        entity.setAddress(data.getAddress());
        entity.setAttachText(data.getAttach());
        entity.setCreditDebitFlag(CreditDebitFlag.C);
        entity.setCurrencyCode(CurrencyCode.CNY);
        entity.setCustomerGenFlag(true);
        entity.setChannelId(properties.getMchChanId());
        entity.setDiscAmount(discount);
        entity.setExternalOrderNo(data.getOutTradeNo());
        entity.setGenFeeAmount(BigDecimal.ZERO);
        entity.setGenOrderNo("");
        entity.setGoodsSigner(signer);
        entity.setShopName(data.getShopName());
        entity.setMobilePhone(data.getPhoneNo());
        entity.setOriginalTxnAmount(origAmt);
        entity.setPayMethod(PayMethod.DRST);
        entity.setPostCashAmount(cash);
        entity.setPostCreditAmount(credit);
        entity.setPartitionKey(account.getPartitionKey());
        entity.setRequestTime(session.getRequestTime());
        entity.setShopName(data.getShopName());
        entity.setStatementeFlag(true);
        entity.setStatisticsCode("PYMT");
        entity.setStatusCode(StatusCode.PEND);
        entity.setSubject(data.getSubject());
        entity.setTransactionId(historyId);
        entity.setTxnAmount(amount);
        entity.setTxnDate(session.getBusinessLocalDate());
        entity.setTxnTime(session.getBusinessLocalTime());
        entity.setTxnType("PYMT");
        if (cash.compareTo(BigDecimal.ZERO) > 0) {
            entity.setTxnCode("R001");
        } else {
            entity.setTxnCode("R002");
        }
        if (cash.add(credit).compareTo(cash.max(credit)) > 0) {
            entity.setTxnCode("R003");
        }
        return entity;
    }

    public static PayGoodsDetailEntity goodsDetail(long goodsId, long historyId, GoodsDetail detail) {
        BigDecimal amount = new BigDecimal(detail.getAmount());
        BigDecimal discount = new BigDecimal(detail.getDiscounts());
        BigDecimal price = new BigDecimal(detail.getPrice());
        int qiantity = Integer.parseInt(detail.getQuantity(), 10);

        PayGoodsDetailEntity entity = new PayGoodsDetailEntity();
        entity.setAttachText(detail.getAttach());
        entity.setDiscAmount(discount);
        entity.setTxnAmount(amount);
        entity.setTransactionId(historyId);
        entity.setGoodsId(goodsId);
        entity.setGoodsName(detail.getGoodsName());
        entity.setGoodsOrderNo(detail.getGoodsNo());
        entity.setPrice(price);
        entity.setQuantity(qiantity);

        return entity;
    }

    public static BatchCycleTriggerEntity payTrigger(Long triggerId, TransactionSummaryEntity history) {
        BatchCycleTriggerEntity entity = new BatchCycleTriggerEntity();
        entity.setAccountId(history.getAccountId());
        entity.setChanNotifyStatus(StatusCode.PEND);
        entity.setEntityCode(history.getTxnType());
        entity.setMchNotifyStatus(StatusCode.PEND);
        entity.setPayDueTime(LocalDateTime.now().plus(PAY_DUE_TIME));
        entity.setTargetId(history.getTransactionId());
        entity.setTriggerId(triggerId);
        entity.setPartitionKey(history.getPartitionKey());
        return entity;
    }
}
