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

import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.account.common.ErrorConstants;
import com.liquidnet.service.account.funding.dto.*;
import com.liquidnet.service.account.funding.dto.base.FundingCallResult;
import com.liquidnet.service.account.funding.dto.base.FundingContextParam;
import com.liquidnet.service.account.funding.service.processor.FundingQueryBalanceProcessor;
import com.liquidnet.service.account.funding.service.processor.FundingRegisterProcessor;
import com.liquidnet.service.account.funding.service.processor.FundingTransactionProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * FundingProcessorAPI.class
 *
 * @author zhanggb
 * Created by IntelliJ IDEA at 2020/10/21
 */
@Service
public class FundingAPIServiceImpl implements FundingAPIService {
    private static final Logger log = LoggerFactory.getLogger(FundingAPIServiceImpl.class);
    @Autowired
    private FundingRegisterProcessor fundingRegisterProcessor;
    @Autowired
    private FundingQueryBalanceProcessor fundingQueryBalanceProcessor;
    @Autowired
    private FundingTransactionProcessor fundingTransactionProcessor;

    @Override
    public FundingRegisterResult register(FundingRegisterParam parameter) {
        if (null == parameter) {
            return new FundingRegisterResult(ErrorConstants.PARAMS_VALUE_ERROR_DESC, ErrorConstants.PARAMS_VALUE_ERROR_DESC);
        }
        log.info("Call {}:[{}]", parameter.getClass().getSimpleName(), JsonUtils.toJson(parameter));
        FundingContextParam contextParam = FundingContextParam.getNew();
        BeanUtils.copyProperties(parameter, contextParam);
        FundingRegisterResult result = null;
        try {
            FundingCallResult<?> rst = fundingRegisterProcessor.service(contextParam);
            result = rst instanceof FundingRegisterResult ? (FundingRegisterResult) rst
                    : new FundingRegisterResult(rst.getCode(), rst.getMessage());
        } catch (Exception e) {
            log.error("Call {} handle exception:[{}]", parameter.getClass().getSimpleName(), JsonUtils.toJson(parameter), e);
            result = new FundingRegisterResult(ErrorConstants.ACCOUNT_CREATE_ERROR_CODE, ErrorConstants.ACCOUNT_CREATE_ERROR_DESC);
        }
        log.info("Call {}:[{}]", result.getClass().getSimpleName(), JsonUtils.toJson(result));
        return result;
    }

    @Override
    public FundingQueryBalanceResult queryBalance(FundingQueryBalanceParam parameter) {
        if (null == parameter) {
            return new FundingQueryBalanceResult(ErrorConstants.PARAMS_VALUE_ERROR_DESC, ErrorConstants.PARAMS_VALUE_ERROR_DESC);
        }
        log.info("Call {}:[{}]", parameter.getClass().getSimpleName(), JsonUtils.toJson(parameter));
        FundingContextParam contextParam = FundingContextParam.getNew();
        BeanUtils.copyProperties(parameter, contextParam);
        FundingQueryBalanceResult result = null;
        try {
            FundingCallResult<?> rst = fundingQueryBalanceProcessor.service(contextParam);
            result = rst instanceof FundingQueryBalanceResult ? (FundingQueryBalanceResult) rst
                    : new FundingQueryBalanceResult(rst.getCode(), rst.getMessage());
        } catch (Exception e) {
            log.error("Call {} handle exception:[{}]", parameter.getClass().getSimpleName(), JsonUtils.toJson(parameter), e);
            result = new FundingQueryBalanceResult(ErrorConstants.ACCOUNT_CREATE_ERROR_CODE, ErrorConstants.ACCOUNT_CREATE_ERROR_DESC);
        }
        log.info("Call {}:[{}]", result.getClass().getSimpleName(), JsonUtils.toJson(result));
        return result;
    }

    @Override
    public FundingTransactionResult transaction(FundingTransactionParam parameter) {
        if (null == parameter) {
            return new FundingTransactionResult(ErrorConstants.PARAMS_VALUE_ERROR_DESC, ErrorConstants.PARAMS_VALUE_ERROR_DESC);
        }
        log.info("Call {}:[{}]", parameter.getClass().getSimpleName(), JsonUtils.toJson(parameter));
        FundingContextParam contextParam = FundingContextParam.getNew();
        BeanUtils.copyProperties(parameter, contextParam);
        FundingTransactionResult result = null;
        try {
            FundingCallResult<?> rst = fundingTransactionProcessor.service(contextParam);
            result = rst instanceof FundingTransactionResult ? (FundingTransactionResult) rst
                    : new FundingTransactionResult(rst.getCode(), rst.getMessage());
        } catch (Exception e) {
            log.error("Call {} handle exception:[{}]", parameter.getClass().getSimpleName(), JsonUtils.toJson(parameter), e);
            result = new FundingTransactionResult(ErrorConstants.ACCOUNT_CREATE_ERROR_CODE, ErrorConstants.ACCOUNT_CREATE_ERROR_DESC);
        }
        log.info("Call {}:[{}]", result.getClass().getSimpleName(), JsonUtils.toJson(result));
        return result;
    }
}
