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

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.framework.constants.ApplicationConstants;
import com.neusoft.smart.pos.framework.utils.LocalDateTimeUtils;
import com.neusoft.smart.pos.framework.utils.MapBeanUtils;
import com.neusoft.smart.pos.payment.constants.PaymentErrorCode;
import com.neusoft.smart.pos.payment.persistent.domain.GrantPayOrder;
import com.neusoft.smart.pos.payment.persistent.domain.PayOrder;
import com.neusoft.smart.pos.payment.persistent.ext.domain.AliGrantPayNotify;
import com.neusoft.smart.pos.payment.persistent.ext.domain.AliPayNotify;
import com.neusoft.smart.pos.payment.repository.*;
import com.neusoft.smart.pos.payment.utils.LogUtils;
import lombok.val;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Service("aliGrantPayNotifyService")
public class AliGrantPayNotifyService {

	@Autowired
    private MchPayChannelRepository mchPayChannelRepository;

    @Autowired
    private GrantPayOrderRepository grantPayOrderRepository;

	@Autowired
	private MchPayInfoRepository mchPayInfoRepository;

	@Autowired
	private GrantPayNotifyRepository grantPayNotifyRepository;

    /**
     * 支付宝支付完成通知数据处理方法
     * @return
     */
    public String aliPayNotifyDataHandle(HttpServletRequest request){
    	//1.处理请求参数
    	Map<String, String> params = new HashMap<String, String>();  
	    Map<String, String[]> requestParams = request.getParameterMap();  
	    String sign = "";
	    String resultData = ApplicationConstants.RETURN_SUCCESS;
	    for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
	        String name = iter.next();  
	        String[] values = requestParams.get(name);	        
	        if (name.equalsIgnoreCase("sign")) sign = StringUtils.join(values);
	        if (!name.equalsIgnoreCase("sign") && !name.equalsIgnoreCase("sign_type")) params.put(name, StringUtils.join(values));
	    }
	    //2.排序得到验签序列串
	    String content = AlipaySignature.getSignContent(params);
	    System.out.println("收到异步通知：");
	    System.out.println(content);

	    //3.转换数据格式
        val aliPayNotify = MapBeanUtils.mapToBean(params, AliGrantPayNotify.class);  //将map转成bean对象

        //4.获取支付定单
        GrantPayOrder grantPayOrder = grantPayOrderRepository.queryPayOrderByNumber(aliPayNotify.getOut_order_no(), DictionaryConstant.PAYMENT_PAY_TYPE_ZFBZZSQ.getCode());
        if (grantPayOrder == null) {
        	return PaymentErrorCode.ALIPAY_PAYORDER_IS_NOT_EXIST.getCode();
        }

        //5.获取支付渠道
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelEnableByMcode(grantPayOrder.getMcode(), DictionaryConstant.PAYMENT_PAY_TYPE_ZFBZZSQ.getCode());
        if (mchPayChannel == null) {	    	
        	return PaymentErrorCode.ALIPAY_CHANNEL_IS_NOT_EXIST.getCode();
        }
        
	    try{
	    	//6.校验微信回调签名信息
	    	if (!AlipaySignature.rsaCheck(content, sign, mchPayChannel.getPublicKey(), AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2)){
	    		resultData = PaymentErrorCode.ALIPAY_CHECK_SIGN_ERROR.getMessage();
				LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),aliPayNotify.getOut_order_no(), DictionaryConstant.PAYMENT_PAY_TYPE_ZFBSM.getCode(),LogUtils.LOG_DESCRIPTION_ZFCGHD,resultData,content,DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
		    	return PaymentErrorCode.ALIPAY_CHECK_SIGN_ERROR.getCode();
	    	}
	    }catch (AlipayApiException e){
	    	resultData = PaymentErrorCode.ALIPAY_CHECK_SIGN_ERROR.getMessage();
			LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),aliPayNotify.getOut_order_no(), DictionaryConstant.PAYMENT_PAY_TYPE_ZFBSM.getCode(),LogUtils.LOG_DESCRIPTION_ZFCGHD,resultData,content,DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
	    	return PaymentErrorCode.ALIPAY_CHECK_SIGN_ERROR.getCode();
		}

        //7.更新聚合支付平台订单支付状态信息
        val payOrderUpdate = new GrantPayOrder();
	    payOrderUpdate.setOuterOrderNumber(aliPayNotify.getOperation_id());
	    payOrderUpdate.setAuthNo(aliPayNotify.getAuth_no());
	    payOrderUpdate.setPayerUserId(aliPayNotify.getPayer_user_id());
        payOrderUpdate.setGrantTime(LocalDateTimeUtils.convertLocalDateTimeToDate(LocalDateTimeUtils.convertStringToLocalDateTime(aliPayNotify.getGmt_trans(),LocalDateTimeUtils.DEFAULT_DATETIME_FORMAT)));
        String grantStatus = getGrantStatus(aliPayNotify.getOperation_type());
	    payOrderUpdate.setGrantStatus(grantStatus);
        grantPayOrderRepository.updateOrderPayStatus(payOrderUpdate,mchPayChannel.getMcode(),aliPayNotify.getOut_order_no(),DictionaryConstant.PAYMENT_PAY_TYPE_ZFBZZSQ.getCode());
		LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),aliPayNotify.getOut_order_no(), DictionaryConstant.PAYMENT_PAY_TYPE_ZFBZZSQ.getCode(),LogUtils.LOG_DESCRIPTION_ZFCGHD,resultData,content,DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());

		//8.回调业务系统通知方法(由于目前聚合支付平台不支持独立回调请求，所以暂时只做请求转发)
	    grantPayOrder.setOuterOrderNumber(aliPayNotify.getOperation_id());
	    grantPayOrder.setAuthNo(aliPayNotify.getAuth_no());
	    grantPayOrder.setPayerUserId(aliPayNotify.getPayer_user_id());
	    grantPayOrder.setGrantTime(LocalDateTimeUtils.convertLocalDateTimeToDate(LocalDateTimeUtils.convertStringToLocalDateTime(aliPayNotify.getGmt_trans(),LocalDateTimeUtils.DEFAULT_DATETIME_FORMAT)));
	    grantPayOrder.setGrantStatus(grantStatus);
		val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(mchPayChannel.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
	    grantPayNotifyRepository.sendPayNotify(grantPayOrder,mchPayInfo.getSecretKey());
        return resultData;
    }
    
    /**
	 * 根据支付宝交易状态返回支付平台订单状态
	 * @param operationType
	 * @return
	 */
	private String getGrantStatus(String operationType){
		String grantStatus = DictionaryConstant.PAY_GRANT_STATUS_CLZ.getCode();
		switch(operationType){
			case "FREEZE":
				//授权成功
				grantStatus = DictionaryConstant.PAY_GRANT_STATUS_YSQ.getCode();
				break;
			case "UNFREEZE":
				//解冻成功
				grantStatus = DictionaryConstant.PAY_GRANT_STATUS_YJD.getCode();
				break;
			case "PAY":
				//授权转支付
				grantStatus = DictionaryConstant.PAY_GRANT_STATUS_ZF.getCode();
				break;
		}
		return grantStatus;
	}
   
}
