package com.liquidnet.service.bank.currencycloud.service.impl;
import com.alibaba.fastjson.JSON;
import com.currencycloud.client.CurrencyCloudClient;
import com.currencycloud.client.exception.ApiException;
import com.currencycloud.client.model.Payer;
import com.currencycloud.client.model.Payment;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.bank.common.BankErrorCode;
import com.liquidnet.service.bank.common.BankResultDto;
import com.liquidnet.service.bank.currencycloud.dto.BankCcBeneficiaryParam;
import com.liquidnet.service.bank.currencycloud.dto.BankCcPayerParam;
import com.liquidnet.service.bank.currencycloud.dto.BankCcPaymentParam;
import com.liquidnet.service.bank.currencycloud.entity.BankCcPayment;
import com.liquidnet.service.bank.currencycloud.service.IBankCcBeneficiaryService;
import com.liquidnet.service.bank.currencycloud.service.IBankCcPaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 下发表 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2020-10-13
 */
@Slf4j
@Service("bankCcPaymentService")
public class BankCcPaymentServiceImpl implements IBankCcPaymentService {

    @Autowired
    private CurrencyCloudClient currencyCloudClient;

    @Autowired
    private IBankCcBeneficiaryService bankCcBeneficiaryService;

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public BankResultDto<BankCcPayment> createPayment(String contactId, BankCcPaymentParam paymentParam,
                                                      BankCcBeneficiaryParam beneficiaryParam,
                                                      BankCcPayerParam payerParam) {

        String logFx = paymentParam.getUniqueRequestId() + ",cc create payment.";

        try {
            // 下发信息
            Payment paymentRequest = Payment.create();
            BeanUtils.copyProperties(paymentParam, paymentRequest);
            // 收款人信息
            BankResultDto<BankCcBeneficiaryParam> beneficiaryRep = bankCcBeneficiaryService.createBeneficiary(beneficiaryParam);
            if (beneficiaryRep.isSuccess()) {
                paymentRequest.setBeneficiaryId(beneficiaryRep.getData().getId());
            } else {
                return BankResultDto.failure(beneficiaryRep.getCode(), beneficiaryRep.getMessage());
            }
            // 付款人信息
            Payer payerRequest = Payer.create();
            BeanUtils.copyProperties(payerParam, payerRequest);

            BankCcPayment resp = new BankCcPayment();
            Runnable runnable = () -> {
                log.info(logFx + "request,paymentRequest=[{}],payerRequest=[{}]", JsonUtils.toJson(paymentRequest), JsonUtils.toJson(payerRequest));
                Payment payment = currencyCloudClient.createPayment(paymentRequest, payerRequest);
                log.info(logFx + "response,payment=[{}]", JsonUtils.toJson(payment));
                BeanUtils.copyProperties(payment, resp);
            };
            currencyCloudClient.onBehalfOfDo(contactId, runnable);
            return BankResultDto.success(resp);
        } catch (ApiException e) {

            log.error(logFx + "api eroor, errorCode=[{}],errors=[{}]", e.getErrorCode(), e.getErrors());
            return BankResultDto.failure(e.getErrorCode(), e.getMessage());

//            BankCcPayment dto = new BankCcPayment();
//            dto.setId(UUID.randomUUID().toString());
//            dto.setUniqueRequestId(paymentParam.getUniqueRequestId());
//            dto.setStatus(BankCcPaymentConstants.StatusEnum.READY_TO_SEND.getCode());
//            dto.setFailureReason("test status ready_to_send");
//            return BankResultDto.success(dto);
        } catch (Exception e) {
            log.error(logFx + "exception eroor:[{}]", JSON.toJSONString(e));
            return BankResultDto.failure(BankErrorCode.BANK_CC_001001);
        }

    }

}
