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

import com.alibaba.fastjson.JSON;
import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.framework.constants.ApplicationConstants;
import com.neusoft.smart.pos.framework.utils.DateUtils;
import com.neusoft.smart.pos.framework.utils.MapBeanUtils;
import com.neusoft.smart.pos.framework.utils.SignatureUtils;
import com.neusoft.smart.pos.payment.persistent.ext.domain.WeixinPayRefundNotify;
import com.neusoft.smart.pos.payment.repository.PayNotifyRepository;
import com.neusoft.smart.pos.payment.utils.ChinaumsUtils;
import com.neusoft.smart.pos.payment.utils.LogUtils;
import com.neusoft.smart.pos.payment.utils.WXPayUtils;
import com.neusoft.smart.pos.payorder.persistent.domain.PayOrder;
import com.neusoft.smart.pos.payorder.repository.MchPayChannelRepository;
import com.neusoft.smart.pos.payorder.repository.MchPayInfoRepository;
import com.neusoft.smart.pos.payorder.repository.PayOrderRepository;
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;

import java.util.Date;
import java.util.Map;

@Service("chinaumsPayNotifyService")
public class ChinaumsPayNotifyService {

	@Autowired
    private MchPayChannelRepository mchPayChannelRepository;

    @Autowired
    private PayOrderRepository payOrderRepository;


    @Autowired
    private MchPayInfoRepository mchPayInfoRepository;

    @Autowired
    private PayNotifyRepository payNotifyRepository;

    /**
     * 银联商务支付完成通知数据处理方法
     * @param notifyDataMap：微信回调数据
     * @return
     */
    public String chinaumsNotifyDataHandle(Map<String,String> notifyDataMap){
        //2.根据微信商户号查询微信商户信息
        String orderNumber = notifyDataMap.get("billNo").toString();
        String payType = DictionaryConstant.PAYMENT_PAY_TYPE_YLSW_SERCIE.getCode();
        PayOrder payOrder = payOrderRepository.queryPayOrderByNumber(orderNumber, DictionaryConstant.PAYMENT_PAY_TYPE_YLSW_SERCIE.getCode());
//        if(payOrder.getPayStatus().equals(DictionaryConstant.PAY_STATUS_YFK.getCode())){
//            return ApplicationConstants.SUCCESS;
//        }
        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMcode(payOrder.getMcode(), payType);
        //3.校验微信回调签名信息
        if(!ChinaumsUtils.checkSign(mchPayChannel.getSecretKey(),notifyDataMap)){
            LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),orderNumber, payType,LogUtils.LOG_DESCRIPTION_ZFCGHD,ApplicationConstants.FAIL, JSON.toJSONString(notifyDataMap),DictionaryConstant.PAYMENT_REQUEST_TYPE_BD.getCode());
            return ApplicationConstants.FAIL;
        }

        //4.更新聚合支付平台订单支付状态信息
        val payOrderTemp = new PayOrder();
        if(notifyDataMap.containsKey("billPayment")){
            String billPaymentStr = notifyDataMap.get("billPayment");
            Map billPaymentMap = JSON.parseObject(billPaymentStr,Map.class);
            if(billPaymentMap.get("payTime") != null){
                Date payDate = DateUtils.parse(billPaymentMap.get("payTime").toString(),DateUtils.FORMAT_LONG);
                payOrder.setPayTime(payDate);
                payOrderRepository.updateOrderPayStatus(payOrderTemp,mchPayChannel.getMcode(),orderNumber,payType);
            }
        }

        //5.回调业务系统通知方法(由于目前聚合支付平台不支持独立回调请求，所以暂时只做请求转发)
        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(mchPayChannel.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
        Boolean bool = payNotifyRepository.sendPayNotify(payOrder,mchPayInfo.getSecretKey());
        LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),orderNumber, payType,LogUtils.LOG_DESCRIPTION_ZFCGHD,ApplicationConstants.SUCCESS,JSON.toJSONString(notifyDataMap),DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
        if(bool){
            return ApplicationConstants.SUCCESS;
        }else{
            return ApplicationConstants.FAIL;
        }
    }

    /**
     * 银联商务退款完成通知数据处理方法
     * @param notifyData：微信回调数据
     * @return
     */
    public String chinaumsRefundNotifyDataHandle(String notifyData){
//        if(StringUtils.isEmpty(notifyXmlData)){
//            return getWeixinResultData(ApplicationConstants.FALSE);
//        }
//
//        //1.将微信通知数据转换成bean
//        val weixinPayRefundNotify = getWeixinPayRefundNotifyData(notifyXmlData);
//
//        //2.根据退款单号信息查询聚合平台退款单信息
//
//        val payRefundOrder = payOrderRepository.queryPayRefundOrder(weixinPayRefundNotify.getOut_trade_no(),weixinPayRefundNotify.getRefund_id(),weixinPayRefundNotify.getOut_refund_no());
//        //4.更新聚合支付平台订单支付状态信息
//        String payType;
//        if(!StringUtils.isEmpty(weixinPayRefundNotify.getSub_mch_id())){
//            payType = DictionaryConstant.PAYMENT_PAY_TYPE_WXZF_SERCIE.getCode();
//        }else{
//            payType = DictionaryConstant.PAYMENT_PAY_TYPE_WXSM.getCode();
//        }
//        if(weixinPayRefundNotify.getRefund_status().equalsIgnoreCase(ApplicationConstants.SUCCESS)){
//            //更新退款订单状态
//            val payOrder = new PayOrder();
//            payOrderRepository.updateOrderRefundStatus(payOrder,payRefundOrder.getMcode(),weixinPayRefundNotify.getOut_trade_no(),payType);
//
//            //更新退款单状态
//            if(payRefundOrder.getRefundStatus() != DictionaryConstant.REFUND_STATUS_TKWC.getCode()){
//                val payRefundOrderTemp = new PayRefundOrder();
//                payRefundOrderTemp.setRefundStatus(DictionaryConstant.REFUND_STATUS_TKWC.getCode());
//                payRefundOrderTemp.setRefundedTime(DateUtils.parse(weixinPayRefundNotify.getSuccess_time(),DateUtils.FORMAT_LONG));
//                payOrderRepository.updatePayRefundOrderStatus(payRefundOrderTemp,weixinPayRefundNotify.getOut_trade_no(),weixinPayRefundNotify.getRefund_id(),weixinPayRefundNotify.getOut_refund_no());
//            }
//        }
//        payRefundOrder.setRefundStatus(DictionaryConstant.REFUND_STATUS_TKWC.getCode());
//        payRefundOrder.setRefundedTime(DateUtils.parse(weixinPayRefundNotify.getSuccess_time(),DateUtils.FORMAT_LONG));
//        //5.回调业务系统通知方法(由于目前聚合支付平台不支持独立回调请求，所以暂时只做请求转发)
//        val mchPayInfo = mchPayInfoRepository.queryMchPayInfoByMcode(payRefundOrder.getMcode(),DictionaryConstant.PAYMENT_MCH_STATUS_SHTG.getCode());
//        Boolean bool = payNotifyRepository.sendPayRefundNotify(payRefundOrder,mchPayInfo.getSecretKey());
//        LogUtils.savePaymentTradeLog(payRefundOrder.getMcode(),weixinPayRefundNotify.getOut_trade_no(), payType,LogUtils.LOG_DESCRIPTION_TKCGHD,getWeixinResultData(bool),notifyXmlData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
//        return getWeixinResultData(bool);
        return ApplicationConstants.SUCCESS;
    }

    /**
     * 根据银联商务返回的xml数据获取Bean数据信息
     * @param notifyXmlData
     * @return
     */
    private WeixinPayRefundNotify getWeixinPayRefundNotifyData(String notifyXmlData){
        //1.获取未加密的数据信息
        Map<String,String> notifyMapData = SignatureUtils.xmlToMap(notifyXmlData);  //将xml数据转成Map
        val weixinPayRefundNotify = MapBeanUtils.mapToBean(notifyMapData,WeixinPayRefundNotify.class);  //将map转成bean对象

        String payType;
        if(!StringUtils.isEmpty(weixinPayRefundNotify.getSub_mch_id())){
            payType = DictionaryConstant.PAYMENT_PAY_TYPE_WXZF_SERCIE.getCode();
        }else{
            payType = DictionaryConstant.PAYMENT_PAY_TYPE_WXSM.getCode();
        }

        val mchPayChannel = mchPayChannelRepository.queryMchPayChannelByMchId(weixinPayRefundNotify.getMch_id(), payType);

        //2.获取加密的数据信息
        String notifyDetailData = notifyMapData.get("req_info");
        Map<String,String> notifyDetailMapData = SignatureUtils.xmlToMap(WXPayUtils.getRefundDecrypt(notifyDetailData,mchPayChannel.getSecretKey()));
        val weixinPayRefundNotifyDetails = MapBeanUtils.mapToBean(notifyDetailMapData,WeixinPayRefundNotify.class);
        weixinPayRefundNotifyDetails.setAppid(weixinPayRefundNotify.getAppid());
        weixinPayRefundNotifyDetails.setMch_id(weixinPayRefundNotify.getMch_id());
        weixinPayRefundNotifyDetails.setSub_mch_id(weixinPayRefundNotify.getSub_mch_id());
        BeanUtils.copyProperties(weixinPayRefundNotifyDetails,weixinPayRefundNotify);
        return weixinPayRefundNotify;
    }
}
