package com.liquidnet.service.account.funding.service.processor;

import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.account.common.ErrorConstants;
import com.liquidnet.service.account.common.FinConstants;
import com.liquidnet.service.account.funding.dto.FundingTransactionResult;
import com.liquidnet.service.account.funding.dto.base.FundingContextParam;
import com.liquidnet.service.account.funding.entity.FinAccount;
import com.liquidnet.service.account.funding.entity.FinAccountBill;
import com.liquidnet.service.account.funding.service.FinAccountBillService;
import com.liquidnet.service.account.funding.service.FinAccountService;
import com.liquidnet.service.account.funding.service.FundingProcessorService;
import com.liquidnet.service.account.util.FinUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;

@Service
public class FundingTransactionProcessor extends FundingProcessorService {
    private static final Logger log = LoggerFactory.getLogger(FundingTransactionProcessor.class);
    @Autowired
    private FinAccountService accountService;
    @Autowired
    private FinAccountBillService accountBillService;

    @Override
    public FundingTransactionResult checkInputParams(FundingContextParam context) {
        if (StringUtils.isEmpty(context.getAccNo())) {
            return new FundingTransactionResult(ErrorConstants.PARAMS_VALUE_ERROR_CODE, "Invalid accNo");
        }
        if (StringUtils.isEmpty(context.getWalletNo())) {
            return new FundingTransactionResult(ErrorConstants.PARAMS_VALUE_ERROR_CODE, "Invalid walletNo");
        }
        if (StringUtils.isEmpty(context.getFinId())) {
            return new FundingTransactionResult(ErrorConstants.PARAMS_VALUE_ERROR_CODE, "Invalid finId");
        }
        if (null == context.getCategory()) {
            return new FundingTransactionResult(ErrorConstants.PARAMS_VALUE_ERROR_CODE, "Invalid category");
        }
        if (null == context.getAmount() || BigDecimal.ZERO.compareTo(context.getAmount()) >= 0) {
            return new FundingTransactionResult(ErrorConstants.PARAMS_VALUE_ERROR_CODE, "Invalid amount");
        }
        if (StringUtils.isEmpty(context.getTransNo())) {
            return new FundingTransactionResult(ErrorConstants.PARAMS_VALUE_ERROR_CODE, "Invalid transNo");
        }
        if (StringUtils.isEmpty(context.getTracingNo())) {
            return new FundingTransactionResult(ErrorConstants.PARAMS_VALUE_ERROR_CODE, "Invalid tracingNo");
        }
        if (null == context.getTracingTime()) {
            return new FundingTransactionResult(ErrorConstants.PARAMS_VALUE_ERROR_CODE, "Invalid tracingTime");
        }
        return new FundingTransactionResult();
    }

    @Override
    public FundingTransactionResult checkBussinessLogic(FundingContextParam context) {
        return new FundingTransactionResult();
    }

    @Override
    public FundingTransactionResult doBussiness(FundingContextParam context) {
        FinAccount account = accountService.queryByAccNo(context.getAccNo());
        if (null == account) {
            log.warn("Not found funding account[{}]", context.getAccNo());
            return new FundingTransactionResult(ErrorConstants.PARAMS_VALUE_ERROR_CODE, "Invalid accNo");
        }

        FinAccountBill addInfo = FinAccountBill.getNew();
        addInfo.setBillNo(FinUtil.getBillNo());
        addInfo.setAccNo(context.getAccNo());
        addInfo.setWalletId(context.getWalletNo());
        addInfo.setFinId(context.getFinId());
        addInfo.setCategory(context.getCategory().getVal());
        addInfo.setAmount(context.getCategory().equals(FinConstants.CDType.CREDIT)
                ? context.getAmount() : context.getAmount().negate());
        addInfo.setTransNo(context.getTransNo());
        addInfo.setAccStatus(account.getAccStatus());
        addInfo.setTracingNo(context.getTracingNo());
        addInfo.setTracingTime(context.getTracingTime());
        addInfo.setCreateTime(context.getCreateTime());

        if (accountBillService.addAccountBill(addInfo) <= 0) {
            log.warn("Add data failed[account_bill]:[{}]", JsonUtils.toJson(addInfo));
            return new FundingTransactionResult(ErrorConstants.BUSINESS_ERROR_CODE, "Failed to persist bill");
        }
        return new FundingTransactionResult(addInfo.getBillNo());
    }
}
