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.PayOrder;
import com.neusoft.smart.pos.payment.persistent.ext.domain.AliPayNotify;
import com.neusoft.smart.pos.payment.repository.MchPayChannelRepository;
import com.neusoft.smart.pos.payment.repository.MchPayInfoRepository;
import com.neusoft.smart.pos.payment.repository.PayNotifyRepository;
import com.neusoft.smart.pos.payment.repository.PayOrderRepository;
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("aliPayNotifyService")
public class AliPayNotifyService {

	@Autowired
    private MchPayChannelRepository mchPayChannelRepository;

    @Autowired
    private PayOrderRepository payOrderRepository;

	@Autowired
	private MchPayInfoRepository mchPayInfoRepository;

	@Autowired
	private PayNotifyRepository payNotifyRepository;

    /**
     * 支付宝支付完成通知数据处理方法
     * @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(content);

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

        //4.获取支付定单
        PayOrder payOrder = payOrderRepository.queryPayOrderByNumber(aliPayNotify.getOut_trade_no(), DictionaryConstant.PAYMENT_PAY_TYPE_ZFBSM.getCode());
        if (payOrder == null) {
        	return PaymentErrorCode.ALIPAY_PAYORDER_IS_NOT_EXIST.getCode();
        }

        //5.获取支付渠道
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelEnableByMcode(payOrder.getMcode(), DictionaryConstant.PAYMENT_PAY_TYPE_ZFBSM.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_trade_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_trade_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.更新聚合支付平台订单支付状态信息
//        if(aliPayNotify.getTotal_amount() * 100 == payOrder.getOrderAmount()){
        	val payOrderUpdate = new PayOrder();
            payOrderUpdate.setPayTime(LocalDateTimeUtils.convertLocalDateTimeToDate(LocalDateTimeUtils.convertStringToLocalDateTime(aliPayNotify.getGmt_payment(),LocalDateTimeUtils.DEFAULT_DATETIME_FORMAT)));
            payOrderUpdate.setOuterOrderNumber(aliPayNotify.getTrade_no());
            payOrderRepository.updateOrderPayStatus(getTradeStatus(aliPayNotify.getTrade_status()),payOrderUpdate,mchPayChannel.getMcode(),aliPayNotify.getOut_trade_no(),DictionaryConstant.PAYMENT_PAY_TYPE_ZFBSM.getCode());
			LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),aliPayNotify.getOut_trade_no(), DictionaryConstant.PAYMENT_PAY_TYPE_ZFBSM.getCode(),LogUtils.LOG_DESCRIPTION_ZFCGHD,resultData,content,DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
            System.out.println("Asyn Notification ok");

			//8.回调业务系统通知方法(由于目前聚合支付平台不支持独立回调请求，所以暂时只做请求转发)
			val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(mchPayChannel.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
			payNotifyRepository.sendPayNotify(payOrder,mchPayInfo.getSecretKey());
            return resultData;
//        }else{
//        	resultData = PaymentErrorCode.ALIPAY_AMOUNT_ERROR.getMessage();
//			LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),aliPayNotify.getOut_trade_no(), DictionaryConstant.PAYMENT_PAY_TYPE_ZFBSM.getCode(),LogUtils.LOG_DESCRIPTION_ZFCGHD,resultData,content,DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
//	    	return PaymentErrorCode.ALIPAY_AMOUNT_ERROR.getCode();
//        }
    }
    
    /**
	 * 根据支付宝交易状态返回支付平台订单状态
	 * @param tradeState
	 * @return
	 */
	private String getTradeStatus(String tradeState){
		String tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode();
		switch(tradeState){
			case "TRADE_SUCCESS":
				//交易支付成功
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_YZF.getCode();
				break;
			case "WAIT_BUYER_PAY":
				//交易创建，等待买家付款
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode();
				break;
			case "TRADE_CLOSED":
				//未付款交易超时关闭，或支付完成后全额退款
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_JYGB.getCode();
				break;
			case "TRADE_FINISHED":
				//交易结束，不可退款
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_FINISH.getCode();
				break;
		}
		return tradeStatus;
	}
   
}
