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

import com.alibaba.fastjson.JSON;
import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.payment.request.PostInitFacePayRequest;
import com.neusoft.smart.pos.dto.payment.response.PostInitFacePayResponse;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.utils.MapBeanUtils;
import com.neusoft.smart.pos.framework.utils.SignUtils;
import com.neusoft.smart.pos.framework.utils.SpringUtils;
import com.neusoft.smart.pos.payment.constants.PaymentErrorCode;
import com.neusoft.smart.pos.payment.persistent.ext.domain.*;
import com.neusoft.smart.pos.payment.repository.IThirdPayRepository;
import com.neusoft.smart.pos.payorder.persistent.domain.PayOrder;
import com.neusoft.smart.pos.payorder.persistent.domain.PayRefundOrder;
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.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service("PaymentService")
public class PaymentService {

    @Autowired
    private MchPayChannelRepository mchPayChannelRepository;

    @Autowired
    private PayTypeDictRepository payTypeDictRepository;

    @Autowired
    private MchPayInfoRepository mchPayInfoRepository;


    /**
     * 支付单生成方法
     * @return
     */
    public String createPayOrder(PayOrder payOrder) {
        //1.根据支付方式查询支付信息
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(payOrder.getPayType());

        //2.校验支付成功回调url
        if(StringUtils.isEmpty(payTypeDict.getPayPlatformType())) {
            return "";
        }
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(payOrder.getMcode(),payTypeDict.getPayPlatformType());
        if(null == mchPayChannel){
            throw new BusinessCommonException(PaymentErrorCode.MCH_THIRD_PLATFORM_NOT_CONFIG);
        }

        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(), IThirdPayRepository.class);
        return thirdPayRepository.createPayOrderToThirdPlatform(payOrder, mchPayChannel, payTypeDict);
    }

    /**
     * 订单查询使用方法
     * @return
     */
    public ThirdPlatformQueryOrder queryPayOrder(PayOrder payOrder) {
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(payOrder.getPayType());
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(payOrder.getMcode(),payTypeDict.getPayPlatformType());
        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayRepository.class);
        return thirdPayRepository.queryPayOrderFromThirdPlatform(payOrder, mchPayChannel);
    }

    /**
     * 订单取消使用方法
     * @return
     */
    public ThirdPlatformCancelOrder canclePayOrder(PayOrder payOrder) {
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(payOrder.getPayType());
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(payOrder.getMcode(),payTypeDict.getPayPlatformType());
        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayRepository.class);
        return thirdPayRepository.cannelPayOrderFromThirdPlatform(payOrder, mchPayChannel);
    }

    /** 订单撤销使用方法
     * @return
     */
    public ThirdPlatformReverseOrder reversePayOrder(PayOrder payOrder) {
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(payOrder.getPayType());
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(payOrder.getMcode(),payTypeDict.getPayPlatformType());
        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayRepository.class);
        return thirdPayRepository.reversePayOrderFromThirdPlatform(payOrder, payOrder.getmOrderNumber(), mchPayChannel);
    }

    /** 订单退款使用方法
     * @return
     */
    public ThirdPlatformRefundOrder refundPayOrder(PayOrder payOrder, String refundNumber, Long refundAmount) {
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(payOrder.getPayType());
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(payOrder.getMcode(),payTypeDict.getPayPlatformType());
        val thirdPayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayRepository.class);
        return thirdPayRepository.refundPayOrderFromThirdPlatform(payOrder, refundNumber, refundAmount, mchPayChannel, payTypeDict);
    }

    /** 人脸支付初始化使用方法
     * @return
     */
    public PostInitFacePayResponse initFacePay(PostInitFacePayRequest initFacePayRequest) {
        //1.查询商户号信息
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(initFacePayRequest.getMcode(), DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        if(null == mchPayInfo){
            throw new BusinessCommonException(PaymentErrorCode.MCH_INFO_NOT_EXIST);
        }

        //2.校验签名信息
        if(!SignUtils.isSignatureValid(MapBeanUtils.beanToMap(initFacePayRequest),mchPayInfo.getSecretKey())){
            throw new BusinessCommonException(PaymentErrorCode.SIGN_VALID_ERROR);
        }

        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(initFacePayRequest.getPayType());
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcodeWithBlob(initFacePayRequest.getMcode(),payTypeDict.getPayPlatformType());
        val thirdFacePayRepository = SpringUtils.getBean(payTypeDict.getBeanName(),IThirdPayRepository.class);
        ThirdPlatformInitFacePay thirdPlatformInitFacePay = new ThirdPlatformInitFacePay();
        if(!StringUtils.isEmpty(initFacePayRequest.getFaceType())&&initFacePayRequest.getFaceType().equals("1")){
            //刷脸支付
            thirdPlatformInitFacePay = thirdFacePayRepository.initFacePay(initFacePayRequest,mchPayChannel,payTypeDict);
        }else{
            //刷脸生活
            //设置业务类型默认值
            if(StringUtils.isEmpty(initFacePayRequest.getBizType())){
//            1，表明1：1身份核验场景（姓名＋身份证号）
//            2，表明1：N刷脸搜索， 支付宝UID入库
//            3，表明1：N刷脸搜索， 支付宝手机号入库
//            4，表明1：1身份核验场景（手机号）
                initFacePayRequest.setBizType("4");
            }
            thirdPlatformInitFacePay = thirdFacePayRepository.initFaceLive(initFacePayRequest,mchPayChannel,payTypeDict);
        }

        //3.查询第三方支付平台预付单信息
        val initFacePayResponseResponse = new PostInitFacePayResponse();
        initFacePayResponseResponse.setZimId(thirdPlatformInitFacePay.getZimId());
        initFacePayResponseResponse.setZimInitClientData(thirdPlatformInitFacePay.getZimInitClientData());
        initFacePayResponseResponse.setInitStatus(thirdPlatformInitFacePay.getInitStatus());
        initFacePayResponseResponse.setAuthinfo(thirdPlatformInitFacePay.getAuthinfo());
        initFacePayResponseResponse.setExpiresIn(thirdPlatformInitFacePay.getExpiresIn());
        val sign = SignUtils.generateSign(MapBeanUtils.beanToMap(initFacePayResponseResponse),mchPayInfo.getSecretKey());
        initFacePayResponseResponse.setSign(sign);
//        LogUtils.saveMchPaymentTradeLog(initFacePayResponseResponse.getMcode(),"",initFacePayRequest.getPayType(),LogUtils.LOG_DESCRIPTION_RLCSH, JSON.toJSONString(initFacePayResponseResponse), JSON.toJSONString(initFacePayRequest),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
        return initFacePayResponseResponse;
    }

    /** 是否支持部分退款
     * @return
     */
    boolean IsSupportPartialRefund(String payType) { //TODO
        val payTypeDict = payTypeDictRepository.queryEnablePayTypeDict(payType);
        return true;
    }
}
