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

import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.account.funding.dto.base.FundingCallResult;
import com.liquidnet.service.account.funding.dto.base.FundingContextParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;

public abstract class FundingProcessorService {
    private static final Logger log = LoggerFactory.getLogger(FundingProcessorService.class);

    public FundingCallResult<?> service(FundingContextParam context) {
        FundingCallResult<?> paramsCheckResult = this.tradeParamsCheck(context);
        if (!paramsCheckResult.isSuccess()) {
            log.info("PubParameter check failed:[{}], context=[{}]", paramsCheckResult.getMessage(), JsonUtils.toJson(context));
            return paramsCheckResult;
        }
        FundingCallResult<?> paramCheckResult = checkInputParams(context);
        if (!paramCheckResult.isSuccess()) {
            log.info("PriParameter check failed:[{}], context=[{}]", paramCheckResult.getMessage(), JsonUtils.toJson(context));
            return paramCheckResult;
        }
        FundingCallResult<?> commonCheckResult = this.checkCommonLogic(context);
        if (!commonCheckResult.isSuccess()) {
            log.info("PubLogic check failed:[{}], context:[{}]", commonCheckResult.getMessage(), JsonUtils.toJson(context));
            return commonCheckResult;
        }
        FundingCallResult<?> bussinessCheckResult = checkBussinessLogic(context);
        if (!bussinessCheckResult.isSuccess()) {
            log.info("PriLogic check failed:[{}], context:[{}]", bussinessCheckResult.getMessage(), JsonUtils.toJson(context));
            return bussinessCheckResult;
        }
        context.setCreateTime(LocalDateTime.now());

        log.info("Funding Bussiness begin: -----------");
        FundingCallResult<?> result = doBussiness(context);
        log.info("Funding Bussiness end: {}", result.isSuccess());

        return result;
    }

    /**
     * 公共参数校验
     *
     * @param context FundingContextParameter
     * @return FundingCallResult<?>
     */
    protected FundingCallResult<?> tradeParamsCheck(FundingContextParam context) {
        return new FundingCallResult<>();
    }

    protected FundingCallResult<?> checkCommonLogic(FundingContextParam context) {
        return new FundingCallResult<>();
    }

    /**
     * 输入参数必填项、值域等语法级别校验
     *
     * @param context FundingContextParameter
     * @return FundingCallResult<?>
     */
    public abstract FundingCallResult<?> checkInputParams(FundingContextParam context);

    /**
     * 输入参数业务逻辑校验
     *
     * @param context FundingContextParameter
     * @return FundingCallResult<?>
     */
    public abstract FundingCallResult<?> checkBussinessLogic(FundingContextParam context);

    /**
     * 真正业务逻辑
     *
     * @param context FundingContextParameter
     * @return FundingCallResult<?>
     */
    public abstract FundingCallResult<?> doBussiness(FundingContextParam context);
}
