package com.neusoft.smart.pos.payment.service;

import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.payment.request.PostApplyPayChannelRequest;
import com.neusoft.smart.pos.dto.payment.request.PutPayChannelRequest;
import com.neusoft.smart.pos.dto.payment.response.DeletePayChannelResponse;
import com.neusoft.smart.pos.dto.payment.response.GetPayChannelResponse;
import com.neusoft.smart.pos.dto.payment.response.PostApplyPayChannelResponse;
import com.neusoft.smart.pos.dto.payment.response.PutPayChannelResponse;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.payment.constants.PaymentErrorCode;
import com.neusoft.smart.pos.payorder.persistent.domain.MchPayChannel;
import com.neusoft.smart.pos.payorder.repository.MchPayChannelRepository;
import com.neusoft.smart.pos.payorder.repository.MchPayInfoRepository;
import com.neusoft.smart.pos.payorder.repository.PayTypeDictRepository;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service("mchPayChannelService")
public class MchPayChannelService {

	@Autowired
    private MchPayChannelRepository mchPayChannelRepository;

    @Autowired
    private MchPayInfoRepository mchPayInfoRepository;

    @Autowired
    private PayTypeDictRepository payTypeDictRepository;

    /**
     * 商户支付渠道申请接口方法
     * @return
     */
    public PostApplyPayChannelResponse applyPayChannel(PostApplyPayChannelRequest applyPayChannelRequest) {
        //1.校验共通基础信息
        if(StringUtils.isEmpty(applyPayChannelRequest.getMcode())){
            throw new BusinessCommonException(PaymentErrorCode.MCODE_NOT_EMPTY);
        }
        if(StringUtils.isEmpty(applyPayChannelRequest.getPayType())){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_NOT_EMPTY);
        }

        //2.校验支付渠道是否存在
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(applyPayChannelRequest.getPayType());
        if(null == payTypeDict){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_ERROR);
        }

        //3.根据支付类型进行参数校验
        payChannelDataValidate(applyPayChannelRequest.getPayType(),applyPayChannelRequest.getAppid(),applyPayChannelRequest.getMchId(),applyPayChannelRequest.getSecretKey(),applyPayChannelRequest.getPrivateKey(),applyPayChannelRequest.getPublicKey());

        //4.校验商户号是否合法，商户是否存在
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(applyPayChannelRequest.getMcode(), DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }

        //5.查询该商户是否已经添加过此类型支付渠道
        val payChannel = mchPayChannelRepository.queryMchPayChannelByMcode(applyPayChannelRequest.getMcode(),applyPayChannelRequest.getPayType());
        if(null != payChannel){
            throw new BusinessCommonException(PaymentErrorCode.PAY_CHANNEL_IS_EXISTS);
        }

        //6.存储支付渠道信息
        val mchPayChannel = new MchPayChannel();
        BeanUtils.copyProperties(applyPayChannelRequest,mchPayChannel);

        mchPayChannelRepository.createMchPayChannel(mchPayChannel);
        return new PostApplyPayChannelResponse(true);
    }

    /**
     * 商户支付渠道详细信息查询方法
     * @param mcode
     * @param payType
     * @return
     */
    public GetPayChannelResponse queryPayChannel(String mcode, String payType){
        //1.校验共通基础信息
        if(StringUtils.isEmpty(mcode)){
            throw new BusinessCommonException(PaymentErrorCode.MCODE_NOT_EMPTY);
        }
        if(StringUtils.isEmpty(payType)){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_NOT_EMPTY);
        }

        //2.校验商户号是否合法，商户是否存在
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(mcode,DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }

        //3.查询支付渠道信息
        val payChannel = mchPayChannelRepository.queryMchPayChannelByMcode(mcode,payType);
        if(null == payChannel){
            throw new BusinessCommonException(PaymentErrorCode.PAY_CHANNEL_IS_EXISTS);
        }
        val payChannelResponse = new GetPayChannelResponse();
        BeanUtils.copyProperties(payChannel,payChannelResponse);
        return payChannelResponse;
    }

    /**
     * 商户支付渠道详细信息查询方法
     * @param mcode
     * @param payType
     * @return
     */
    public DeletePayChannelResponse deletePayChannel(String mcode, String payType){
        //1.校验共通基础信息
        if(StringUtils.isEmpty(mcode)){
            throw new BusinessCommonException(PaymentErrorCode.MCODE_NOT_EMPTY);
        }
        if(StringUtils.isEmpty(payType)){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_NOT_EMPTY);
        }

        //2.校验商户号是否合法，商户是否存在
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(mcode,DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }

        //3.删除支付渠道信息
        val bool = mchPayChannelRepository.deleteMchPayChannelByMcode(mcode,payType);
        if(!bool){
            throw new BusinessCommonException(PaymentErrorCode.PAY_CHANNEL_IS_EMPTY);
        }
        return new DeletePayChannelResponse(bool);
    }

    /**
     * 商户支付渠道信息更新方法
     * @return
     */
    public PutPayChannelResponse updatePayChannel(PutPayChannelRequest payChannelRequest) {
        //1.校验共通基础信息
        if(StringUtils.isEmpty(payChannelRequest.getMcode())){
            throw new BusinessCommonException(PaymentErrorCode.MCODE_NOT_EMPTY);
        }
        if(StringUtils.isEmpty(payChannelRequest.getPayType())){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_NOT_EMPTY);
        }

        //2.根据支付类型进行参数校验
        payChannelDataValidate(payChannelRequest.getPayType(),payChannelRequest.getAppid(),payChannelRequest.getMchId(),payChannelRequest.getSecretKey(),payChannelRequest.getPrivateKey(),payChannelRequest.getPublicKey());

        //3.更新支付渠道信息
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(payChannelRequest.getMcode(),payChannelRequest.getPayType());
        if(!StringUtils.isEmpty(payChannelRequest.getAppid())){
            mchPayChannel.setAppid(payChannelRequest.getAppid());
        }
        if(!StringUtils.isEmpty(payChannelRequest.getMchId())){
            mchPayChannel.setMchId(payChannelRequest.getMchId());
        }
        if(!StringUtils.isEmpty(payChannelRequest.getSubAppid())){
            mchPayChannel.setSubAppid(payChannelRequest.getSubAppid());
        }
        if(!StringUtils.isEmpty(payChannelRequest.getSubMchId())){
            mchPayChannel.setSubMchId(payChannelRequest.getSubMchId());
        }
        if(!StringUtils.isEmpty(payChannelRequest.getSecretKey())){
            mchPayChannel.setSecretKey(payChannelRequest.getSecretKey());
        }
        if(!StringUtils.isEmpty(payChannelRequest.getAppSecretKey())){
            mchPayChannel.setAppSecretKey(payChannelRequest.getAppSecretKey());
        }
        if(!StringUtils.isEmpty(payChannelRequest.getPublicKey())){
            mchPayChannel.setPublicKey(payChannelRequest.getPublicKey());
        }
        if(!StringUtils.isEmpty(payChannelRequest.getPrivateKey())){
            mchPayChannel.setPrivateKey(payChannelRequest.getPrivateKey());
        }
        if(!StringUtils.isEmpty(payChannelRequest.getNotifyUrl())){
            mchPayChannel.setNotifyUrl(payChannelRequest.getNotifyUrl());
        }
        if(!StringUtils.isEmpty(payChannelRequest.getRefundNotifyUrl())){
            mchPayChannel.setRefundNotifyUrl(payChannelRequest.getRefundNotifyUrl());
        }
        if(null != payChannelRequest.getCert() && payChannelRequest.getCert().length > 0){
            mchPayChannel.setCert(payChannelRequest.getCert());
        }
//        BeanUtils.copyProperties(payChannelRequest,mchPayChannel);
        val bool = mchPayChannelRepository.updateMchPayChannelByMcode(mchPayChannel);
        if(!bool){
            throw new BusinessCommonException(PaymentErrorCode.PAY_CHANNEL_IS_EMPTY);
        }
        return new PutPayChannelResponse(bool);
    }

    /**
     * 参数校验方法
     * @param payType
     * @param appid
     * @param mchId
     * @param secretKey
     */
    private void payChannelDataValidate(String payType,String appid,String mchId,String secretKey,String privateKey,String publicKey){
        DictionaryConstant dict = DictionaryConstant.getEnumByCode(DictionaryConstant.PAYMENT_PAY_TYPE.getCode(),payType);
        //根据支付类型进行参数校验
        switch(dict){
            //微信支付渠道参数校验
            case PAYMENT_PAY_TYPE_WXSM:
                weixinPayParamsValidate(appid,mchId,secretKey);
                break;
            //支付宝支付渠道参数校验
            case PAYMENT_PAY_TYPE_ZFBSM:
                zhifubaoPayParamsValidate(appid,privateKey,publicKey);
                break;
        }
    }

    /**
     * 微信支付方式信息校验
     */
    private void weixinPayParamsValidate(String appid,String mchId,String secretKey){
        if(StringUtils.isEmpty(appid)){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_APPID_NOT_EMPTY);
        }
        if(StringUtils.isEmpty(mchId)){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_MCHID_NOT_EMPTY);
        }
        if(StringUtils.isEmpty(secretKey)){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_SECRETKEY_NOT_EMPTY);
        }
    }

    /**
     * 支付宝支付方式信息校验
     */
    private void zhifubaoPayParamsValidate(String appid,String privateKey,String publicKey){
        if(StringUtils.isEmpty(appid)){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_APPID_NOT_EMPTY);
        }
        if(StringUtils.isEmpty(privateKey)){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_PRIVATE_KEY_NOT_EMPTY);
        }
        if(StringUtils.isEmpty(publicKey)){
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_PUBILC_KEY_NOT_EMPTY);
        }
    }
}
