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

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.payment.request.FumaoPayRequest;
import com.neusoft.smart.pos.dto.payment.request.PostInitFacePayRequest;
import com.neusoft.smart.pos.dto.payment.response.*;
import com.neusoft.smart.pos.framework.constants.SignatureConstants;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.utils.SignatureUtils;
import com.neusoft.smart.pos.payment.constants.FumaoPayConstants;
import com.neusoft.smart.pos.payment.constants.PaymentErrorCode;
import com.neusoft.smart.pos.payment.dto.request.FumaoCheckUserRequest;
import com.neusoft.smart.pos.payment.dto.request.FumaoPosOrderSyncRequest;
import com.neusoft.smart.pos.payment.dto.response.FumaoCheckUserResponse;
import com.neusoft.smart.pos.payment.dto.response.FumaoPosOrderSyncResponse;
import com.neusoft.smart.pos.payment.persistent.domain.FumaoUserInfo;
import com.neusoft.smart.pos.payment.persistent.domain.FumaoUserInfoExample;
import com.neusoft.smart.pos.payment.persistent.ext.domain.*;
import com.neusoft.smart.pos.payment.persistent.mapper.FumaoUserInfoExtMapper;
import com.neusoft.smart.pos.payment.persistent.mapper.FumaoUserInfoMapper;
import com.neusoft.smart.pos.payment.utils.HttpClientUtils;
import com.neusoft.smart.pos.payment.utils.LogUtils;
import com.neusoft.smart.pos.payment.utils.WXPayUtils;
import com.neusoft.smart.pos.payorder.persistent.domain.MchPayChannel;
import com.neusoft.smart.pos.payorder.persistent.domain.PayOrder;
import com.neusoft.smart.pos.payorder.persistent.domain.PayTypeDict;
import com.neusoft.smart.pos.redis.bean.DeviceInfo;
import com.neusoft.smart.pos.redis.bean.UserInfo;
import com.neusoft.smart.pos.utils.PosDeviceRedisUtils;
import com.neusoft.smart.pos.utils.UserCacheUtils;
import lombok.val;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 富茂支付使用Repository
 * @author tjm
 * @date 2019-08-21
 */
@Component("fumaoPayRepository")
public class FumaoPayRepository implements IThirdPayRepository {
    private final static Logger logger = LoggerFactory.getLogger(FumaoPayRepository.class);

    @Resource
    FumaoUserInfoExtMapper fumaoUserInfoExtMapper;

    @Resource
    FumaoUserInfoMapper fumaoUserInfoMapper;

    /**
     * 富茂会员查询与试算接口
     * @param fumaoPayRequest 富茂请求
     * @return FumaoMemberInfo
     */
    public FumaoMemberInfoRes fumaoMemberInfoToThirdPlatform(FumaoPayRequest fumaoPayRequest){
        logger.debug("fumaoMemberInfoToThirdPlatform enter");
        //1.封装请求数据数据
        String RequestData =  fumaoMemberRequestDataHandle(fumaoPayRequest);
        //2.请求富茂会员接口
        String responseData = HttpClientUtils.postData(FumaoPayConstants.DOMAIN_API + FumaoPayConstants.QUERY_AND_CALC_SUFFIX, RequestData);
        //3.记录日志
        LogUtils.savePaymentTradeLog("","", "",LogUtils.LOG_DESCRIPTION_CXSS,RequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
        //4.封装结果并返回
        return fumaoMemberResponseDataHandle(responseData);
    }

    /**
     * 富茂会员请求数据整理方法
     * @param fumaoPayRequest 富茂请求
     * @return String
     */
    private String fumaoMemberRequestDataHandle(FumaoPayRequest fumaoPayRequest){
        Map<String, String> reqObj = new HashMap<>();
        reqObj.put("dev_id", FumaoPayConstants.BUSINESS_ID);
        reqObj.put("tenant_id", fumaoPayRequest.getTenantId());
        reqObj.put("nonce_str", WXPayUtils.generateNonceStr());//"123456789");
        reqObj.put("merchant_id", fumaoPayRequest.getMerchantId());
        reqObj.put("order_operation_id", fumaoPayRequest.getOrderOperatorId());
        if(fumaoPayRequest.getMemPhone() != null && fumaoPayRequest.getMemPhone().length() == 11) {
            reqObj.put("mem_phone_number", fumaoPayRequest.getMemPhone());
        } else {
            reqObj.put("mem_id", fumaoPayRequest.getMemId());
        }
        reqObj.put("business_type", fumaoPayRequest.getBusinessType());
        reqObj.put("order_amount", fumaoPayRequest.getOrderAmount());
        reqObj.put("order_amount_left", fumaoPayRequest.getOrderAmountLeft());
        reqObj.put("order_create_sn", fumaoPayRequest.getDeviceSN());

        if(fumaoPayRequest.getCouponOrderIdList() != null) {
            reqObj.put("coupon_list", "[".concat(String.join(",", fumaoPayRequest.getCouponOrderIdList())).concat("]"));
        } else {
            reqObj.put("coupon_list", "[]");
        }

        reqObj.put("sign", SignatureUtils.generateSignature(reqObj, FumaoPayConstants.DEV_REQ_KEY, SignatureUtils.SignType.HMACSHA256));
        logger.info("sign:"+SignatureUtils.generateSignature(reqObj, FumaoPayConstants.DEV_REQ_KEY, SignatureUtils.SignType.HMACSHA256));

        JSONObject jsonObject = JSONObject.fromObject(reqObj);
        String result = jsonObject.toString();
        logger.info("fumaoMemberRequestDataHandle:"+result);
        return result;
    }

    /**
     * 富茂会员接口响应数据处理
     * @param responseData response数据
     * @return FumaoMemberInfo
     */
    private FumaoMemberInfoRes fumaoMemberResponseDataHandle(String responseData){
        logger.info("fumaoMemberResponseDataHandle:"+responseData);
        FumaoMemberInfoRes memberInfo;

        Map resultMap = (Map)JSON.parse(responseData);
        String result;
        if(("0").equals(resultMap.get("result_code").toString())){
            result = (String)resultMap.get("result_data");
            JSONObject jsonObject  = JSONObject.fromObject(result);
            memberInfo = (FumaoMemberInfoRes) JSONObject.toBean(jsonObject, FumaoMemberInfoRes.class);
            memberInfo.setReturn_code(resultMap.get("return_code").toString());
            memberInfo.setReturn_msg(resultMap.get("return_msg").toString());
            memberInfo.setResult_code(resultMap.get("result_code").toString());
            String pomotionData = jsonObject.getString("promotion_data");
            JSONObject jsonObjectPromotion  = JSONObject.fromObject(pomotionData);
            FumaoPromotionData fumaoPromotionData = (FumaoPromotionData)JSONObject.toBean(jsonObjectPromotion, FumaoPromotionData.class);
            FumaoPromotionInfo promotionInfo = (FumaoPromotionInfo) JSONObject.toBean(JSONObject.fromObject(fumaoPromotionData.getPromotion_info()),FumaoPromotionInfo.class);
            FumaoCouponData coupon = (FumaoCouponData)JSONObject.toBean(JSONObject.fromObject(promotionInfo.getCoupon()),FumaoCouponData.class) ;
            JSONArray jsonArray = JSONArray.fromObject(coupon.getCoupon_list());
            List<FumaoCouponInfo> couponList =  JSONArray.toList(jsonArray, FumaoCouponInfo.class);
            fumaoPromotionData.getPromotion_info().getCoupon().setCoupon_list(couponList);
            memberInfo.setPromotionData(fumaoPromotionData);

            logger.info("memberInfo.getMemberPhoneNumber():"+memberInfo.getMem_phone_number());
        } else {
            throw new BusinessCommonException(resultMap.get("result_code").toString(), resultMap.get("result_msg").toString());
        }

        return memberInfo;
    }

    /**
     * 门店用户登录检查, 同时会返回会员折扣/优惠券/消费卡是否启用，mall信息及注册二维码及小票二维码规则
     * @param fumaoCheckUserRequest 富茂请求
     * @return FumaoCheckUserResponse
     */
    public FumaoCheckUserResponse fumaoCheckUser(FumaoCheckUserRequest fumaoCheckUserRequest){
        logger.debug("fumaoCheckUser enter");
        //1.封装请求数据数据
        String RequestData =  fumaoCheckUserRequestDataHandle(fumaoCheckUserRequest);
        //2.请求富茂会员接口
        String responseData = HttpClientUtils.postData(FumaoPayConstants.DOMAIN_API + FumaoPayConstants.CHECK_USER_PASSWORD, RequestData);
        //3.记录日志
        LogUtils.savePaymentTradeLog("","", "",LogUtils.LOG_DESCRIPTION_YHDL,RequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
        //4.封装结果并返回
        return fumaoCheckUserResponseDataHandle(responseData);
    }

    /**
     * 富茂门店用户请求数据整理方法
     * @param fumaoCheckUserRequest 富茂请求
     * @return String
     */
    private String fumaoCheckUserRequestDataHandle(FumaoCheckUserRequest fumaoCheckUserRequest){
        Map<String, String> reqObj = new HashMap<>();
        reqObj.put("dev_id", FumaoPayConstants.BUSINESS_ID);
        reqObj.put("tenant_id", fumaoCheckUserRequest.getTenantId());
        reqObj.put("nonce_str", WXPayUtils.generateNonceStr());//"123456789");
        reqObj.put("phone", fumaoCheckUserRequest.getPhone());
        reqObj.put("password", fumaoCheckUserRequest.getPassword());

        reqObj.put("sign", SignatureUtils.generateSignature(reqObj, FumaoPayConstants.DEV_REQ_KEY, SignatureUtils.SignType.HMACSHA256));
        logger.info("sign:"+SignatureUtils.generateSignature(reqObj, FumaoPayConstants.DEV_REQ_KEY, SignatureUtils.SignType.HMACSHA256));

        JSONObject jsonObject = JSONObject.fromObject(reqObj);
        String result = jsonObject.toString();
        logger.info("fumaoCheckUserRequestDataHandle:"+result);
        return result;
    }

    /**
     * 富茂门店用户接口响应数据处理
     * @param responseData response数据
     * @return FumaoCheckUserResponse
     */
    private FumaoCheckUserResponse fumaoCheckUserResponseDataHandle(String responseData){
        logger.info("fumaoCheckUserResponseDataHandle:"+responseData);
        FumaoCheckUserResponse userResponse;

        Map resultMap = (Map)JSON.parse(responseData);
        String result;
        if(("0").equals(resultMap.get("result_code").toString())){
            result = (String)resultMap.get("result_data");
            JSONObject jsonObject  = JSONObject.fromObject(result);
            userResponse = (FumaoCheckUserResponse) JSONObject.toBean(jsonObject, FumaoCheckUserResponse.class);
            return userResponse;
        } else {
            return null;
        }

    }


    /**
     * 富茂订单同步接口
     * @param fumaoPosOrderSyncRequest 富茂请求
     * @return FumaoPosOrderSyncResponse
     */
    public FumaoPosOrderSyncResponse posOrderSync(FumaoPosOrderSyncRequest fumaoPosOrderSyncRequest) {
        logger.debug("posOrderSync enter");
        //1.封装请求数据数据
        String RequestData = fumaoPosOrderSyncRequestDataHandle(fumaoPosOrderSyncRequest);
        //2.请求富茂会员接口
        String responseData = HttpClientUtils.postData(FumaoPayConstants.DOMAIN_API + FumaoPayConstants.POS_ORDER_SYNC, RequestData);
        logger.info("posOrderSync:responseData="+responseData);
        //3.记录日志
        LogUtils.savePaymentTradeLog("",fumaoPosOrderSyncRequest.getOrderNumber(), DictionaryConstant.PAY_TYPE_MULTY_COMBINED.getCode(),LogUtils.LOG_DESCRIPTION_DDTB,RequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
        //4.封装结果并返回
        return fumaoPosOrderSyncResponseDataHandle(responseData);
    }

    /**
     * 富茂订单同步请求数据整理方法
     * @param fumaoPosOrderSyncRequest 富茂请求
     * @return String
     */
    private String fumaoPosOrderSyncRequestDataHandle(FumaoPosOrderSyncRequest fumaoPosOrderSyncRequest) {
        Map<String, String> reqObj = new HashMap<>();
        reqObj.put("dev_id", FumaoPayConstants.BUSINESS_ID);
        reqObj.put("nonce_str", WXPayUtils.generateNonceStr());//"123456789");
        reqObj.put("tenant_id", fumaoPosOrderSyncRequest.getTenantId());
        reqObj.put("merchant_id", fumaoPosOrderSyncRequest.getMerchantId());
        reqObj.put("order_operation_id", fumaoPosOrderSyncRequest.getOrderOperatorId());
        reqObj.put("business_type", fumaoPosOrderSyncRequest.getBusinessType());
        reqObj.put("mem_id", fumaoPosOrderSyncRequest.getMemId());
        reqObj.put("mem_phone_number", fumaoPosOrderSyncRequest.getMemPhone());
        reqObj.put("order_number_of_platform", fumaoPosOrderSyncRequest.getOrderNumber());
        reqObj.put("order_create_sn", fumaoPosOrderSyncRequest.getDeviceSN());
        reqObj.put("order_time_of_platform", fumaoPosOrderSyncRequest.getOrderTimeOfPlatform());
        reqObj.put("order_amount", fumaoPosOrderSyncRequest.getOrderAmount());
        reqObj.put("order_status", fumaoPosOrderSyncRequest.getOrderStatus());
        if(fumaoPosOrderSyncRequest.getOrderStatus().equals("0")) { //payment_detail_list
            JSONArray jsonArray = new JSONArray();
            JSONObject json = new JSONObject();
            jsonArray.addAll(fumaoPosOrderSyncRequest.getPaymentDetailList());
            json.put("payment_detail_list",jsonArray);
            reqObj.put("payment_detail", json.toString());
        } else { //refund_detail_list
            JSONArray jsonArray = JSONArray.fromObject(fumaoPosOrderSyncRequest.getRefundDetailList());
            JSONObject json = new JSONObject();
            json.put("refund_detail_list",jsonArray);
            reqObj.put("refund_detail", json.toString());
        }

        reqObj.put("sign", SignatureUtils.generateSignature(reqObj, FumaoPayConstants.DEV_REQ_KEY, SignatureUtils.SignType.HMACSHA256));
        logger.info("sign:"+SignatureUtils.generateSignature(reqObj, FumaoPayConstants.DEV_REQ_KEY, SignatureUtils.SignType.HMACSHA256));

        JSONObject jsonObject = JSONObject.fromObject(reqObj);
        String result = jsonObject.toString();
        logger.info("fumaoPosOrderSyncRequestDataHandle:"+result);
        return result;
    }

    /**
     * 富茂订单同步接口响应数据处理
     * @param responseData response数据
     * @return FumaoPosOrderSyncResponse
     */
    private FumaoPosOrderSyncResponse fumaoPosOrderSyncResponseDataHandle(String responseData){
        logger.info("fumaoPosOrderSyncResponseDataHandle:"+responseData);
        FumaoPosOrderSyncResponse response;

        Map resultMap = (Map)JSON.parse(responseData);
        String result;
        if(("0").equals(resultMap.get("result_code").toString())){
            result = (String)resultMap.get("result_data");
            JSONObject jsonObject  = JSONObject.fromObject(result);
            response = (FumaoPosOrderSyncResponse) JSONObject.toBean(jsonObject, FumaoPosOrderSyncResponse.class);
            // TODO 等富茂确定返回数据结构后，解析response,把积分存储到order_master_v2表的remard字段中
        } else {
            //throw new BusinessCommonException(resultMap.get("result_code").toString(),resultMap.get("result_msg").toString());
            response  = null;
        }

        return response;
    }

    @Override
    public String createPayOrderToThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel, PayTypeDict payTypeDict) {
        logger.info("createPayOrderToThirdPlatform enter");
        //1.封装请求数据数据
        String couponRequestData = fumaoCouponOrderRequestDataHandle(payOrder);
        logger.info("createPayOrderToThirdPlatform::couponRequestData=" + couponRequestData);
        //2.请求富茂会员接口
        String responseData = HttpClientUtils.postData(FumaoPayConstants.DOMAIN_API + FumaoPayConstants.COUPON_VERIFY_URL_SUFFIX, couponRequestData);
        logger.info("createPayOrderToThirdPlatform::couponResponseData=" + responseData);
        //3.记录日志
        LogUtils.savePaymentTradeLog(payOrder.getMcode(), payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_FM_COUPON_PAY.getCode(), LogUtils.LOG_DESCRIPTION_DDSC, couponRequestData, responseData, DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
        //4.封装结果并返回
        return fumaoCouponOrderVerifyResponseDataHandle(payOrder, responseData);
    }

    /**
     * 富茂优惠数据整理方法
     * @param payOrder 支付请求
     * @return String
     */
    private String fumaoCouponOrderRequestDataHandle(PayOrder payOrder){
        Map<String, String> reqObj = new HashMap<>();
        reqObj.put("dev_id", FumaoPayConstants.BUSINESS_ID);
        reqObj.put("nonce_str", WXPayUtils.generateNonceStr());//"123456789");
        String payInfoString = payOrder.getRequestDetailInfo();
        logger.info("fumaoCouponOrderRequestDataHandle::payInfoString="+payInfoString);
        JSONObject payInfoJsonObject  = JSONObject.fromObject(payInfoString);
        try {
            reqObj.put("order_amount", payInfoJsonObject.getString("orderAmount"));
            reqObj.put("order_amount_left", payInfoJsonObject.getString("orderAmountLeft"));
            if(!payInfoJsonObject.getString("memPhone").equals("")) {
                reqObj.put("mem_phone_number", payInfoJsonObject.getString("memPhone"));
            }
            if(!payInfoJsonObject.getString("memId").equals("")) {
                reqObj.put("mem_id", payInfoJsonObject.getString("memId"));
            }
            reqObj.put("business_type", payInfoJsonObject.getString("businessType"));
            List<String> couponList = (List<String>)payInfoJsonObject.get("couponOrderIdList");
            if(couponList != null) {
                reqObj.put("coupon_list", "[".concat(String.join(",", couponList)).concat("]"));
                payOrder.setOuterOrderNumber(String.join(",", couponList));
            } else {
                reqObj.put("coupon_list", "[]");
            }
        } catch (Exception e) {
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_INFO_NOT_EMPTY);
        }
        FumaoUserInfo fumaoUserInfo = getFumaoUserInfo(payOrder.getDeviceId(),payOrder.getCreatedBy());
        reqObj.put("merchant_id", fumaoUserInfo.getMerchantId());
        reqObj.put("tenant_id", fumaoUserInfo.getTenantId());
        reqObj.put("order_operation_id", fumaoUserInfo.getOrderOperatorId());
        reqObj.put("order_number_of_platform", payOrder.getmOrderNumber());
        reqObj.put("order_create_sn", payOrder.getDeviceId());
        reqObj.put("sign", SignatureUtils.generateSignature(reqObj, FumaoPayConstants.DEV_REQ_KEY, SignatureUtils.SignType.HMACSHA256));
        JSONObject jsonObject = JSONObject.fromObject(reqObj);
        return jsonObject.toString();
    }

    /**
     * 富茂优惠券核销接口响应数据处理
     * @param responseData response数据
     * @return ThirdPlatformCreateOrder
     */
    private String fumaoCouponOrderVerifyResponseDataHandle(PayOrder payOrder, String responseData){
        logger.info("fumaoCouponOrderVerifyResponseDataHandle enter: responseData="+responseData);

        JSONObject resData = JSONObject.fromObject(responseData);
        if(("0").equals(resData.getString("result_code"))) {
            String result = resData.getString("result_data");
            JSONObject jsonObject  = JSONObject.fromObject(result);
            String pomotionData = jsonObject.getString("promotion_data");
            JSONObject jsonObjectPromotion  = JSONObject.fromObject(pomotionData);
            FumaoPromotionData fumaoPromotionData = (FumaoPromotionData)JSONObject.toBean(jsonObjectPromotion, FumaoPromotionData.class);
            FumaoPromotionInfo promotionInfo = (FumaoPromotionInfo) JSONObject.toBean(JSONObject.fromObject(fumaoPromotionData.getPromotion_info()),FumaoPromotionInfo.class);
            FumaoCouponData coupon = (FumaoCouponData)JSONObject.toBean(JSONObject.fromObject(promotionInfo.getCoupon()),FumaoCouponData.class) ;
            JSONArray jsonArray = JSONArray.fromObject(coupon.getCoupon_list());
            List<FumaoCouponInfo> couponList =  JSONArray.toList(jsonArray, FumaoCouponInfo.class);
            ArrayList<FumaoCouponInfo> storeCouponList = new ArrayList<>();
            for(FumaoCouponInfo couponInfo: couponList) {
                if(1 == couponInfo.getIs_selected()) {
                    storeCouponList.add(couponInfo);
                }
            }
            fumaoPromotionData.getPromotion_info().getCoupon().setCoupon_list(storeCouponList);
            Gson mGson = new Gson();
            String paydata = mGson.toJson(fumaoPromotionData);
            payOrder.setResponseDetailInfo(paydata);

//            JSONObject jsonObject  = JSONObject.fromObject(resultData);
//            try {
//                String promotionData = jsonObject.getString("promotion_data");
//                payOrder.setResponseDetailInfo(promotionData);
//            } catch (Exception e) {
////                thirdPlatformOrder.setOuterCodeUrl("");
//            }
            payOrder.setPayStatus(DictionaryConstant.PAY_STATUS_YFK.getCode());
        } else {
            payOrder.setResponseDetailInfo(responseData);
        }
        return new JSONObject().toString();
    }


    @Override
    public ThirdPlatformQueryOrder queryPayOrderFromThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel) {
        return null;
    }

    @Override
    public ThirdPlatformCancelOrder cannelPayOrderFromThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel) {
        logger.info("cannelPayOrderFromThirdPlatform enter");
        //1.封装请求数据数据
        String couponRequestData = fumaoCouponOrderCancelRequestDataHandle(payOrder);
        logger.info("cannelPayOrderFromThirdPlatform::couponRequestData=" + couponRequestData);
        //2.请求富茂会员接口
        String responseData = HttpClientUtils.postData(FumaoPayConstants.DOMAIN_API + FumaoPayConstants.COUPON_VERIFY_CANCEL_URL_SUFFIX, couponRequestData);
        logger.info("cannelPayOrderFromThirdPlatform::couponResponseData=" + responseData);
        //3.记录日志
        LogUtils.savePaymentTradeLog(payOrder.getMcode(), payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_FM_COUPON_PAY.getCode(), LogUtils.LOG_DESCRIPTION_SQTK, couponRequestData, responseData, DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
        //4.封装结果并返回
        return fumaoCouponOrderCancelResponseDataHandle(payOrder, responseData);
    }

    private ThirdPlatformCancelOrder fumaoCouponOrderCancelResponseDataHandle(PayOrder payOrder, String responseData){
        logger.info("fumaoCouponOrderCancelResponseDataHandle enter: responseData="+responseData);
        val thirdPlatformOrder = new ThirdPlatformCancelOrder();
        thirdPlatformOrder.setMcode(payOrder.getMcode());
        thirdPlatformOrder.setMOrderNumber(payOrder.getmOrderNumber());
        thirdPlatformOrder.setPayType(payOrder.getPayType());

        JSONObject resData = JSONObject.fromObject(responseData);
        if(("0").equals(resData.getString("result_code"))) {
            thirdPlatformOrder.setCancelStatus("1"); // 取消成功
            payOrder.setPayStatus(DictionaryConstant.PAY_STATUS_YQX.getCode());
        } else {
            thirdPlatformOrder.setCancelStatus("0"); // 取消失败
        }
        return thirdPlatformOrder;
    }

    @Override
    public ThirdPlatformRefundOrder refundPayOrderFromThirdPlatform(PayOrder payOrder, String refundNumber, Long refundAmount, MchPayChannel mchPayChannel, PayTypeDict payTypeDict) {
        logger.info("refundPayOrderFromThirdPlatform enter");
        //1.封装请求数据数据
        String couponRequestData = fumaoCouponOrderCancelRequestDataHandle(payOrder);
        logger.info("refundPayOrderFromThirdPlatform::couponRequestData=" + couponRequestData);
        //2.请求富茂会员接口
        String responseData = HttpClientUtils.postData(FumaoPayConstants.DOMAIN_API + FumaoPayConstants.COUPON_VERIFY_CANCEL_URL_SUFFIX, couponRequestData);
        logger.info("refundPayOrderFromThirdPlatform::couponResponseData=" + responseData);
        //3.记录日志
        LogUtils.savePaymentTradeLog(payOrder.getMcode(), payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_FM_COUPON_PAY.getCode(), LogUtils.LOG_DESCRIPTION_SQTK, couponRequestData, responseData, DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
        //4.封装结果并返回
        return fumaoCouponOrderRefundResponseDataHandle(payOrder, responseData);
    }

    @Override
    public ThirdPlatformReverseOrder reversePayOrderFromThirdPlatform(PayOrder payOrder, String orderNumber, MchPayChannel mchPayChannel) {
        logger.info("reversePayOrderFromThirdPlatform enter");
        //1.封装请求数据数据
        String couponRequestData = fumaoCouponOrderCancelRequestDataHandle(payOrder);
        logger.info("reversePayOrderFromThirdPlatform::couponRequestData=" + couponRequestData);
        //2.请求富茂会员接口
        String responseData = HttpClientUtils.postData(FumaoPayConstants.DOMAIN_API + FumaoPayConstants.COUPON_VERIFY_CANCEL_URL_SUFFIX, couponRequestData);
        logger.info("reversePayOrderFromThirdPlatform::couponResponseData=" + responseData);
        //3.记录日志
        LogUtils.savePaymentTradeLog(payOrder.getMcode(), payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_FM_COUPON_PAY.getCode(), LogUtils.LOG_DESCRIPTION_SQTK, couponRequestData, responseData, DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
        //4.封装结果并返回
        return fumaoCouponOrderReverseResponseDataHandle(payOrder, responseData);
    }

    private ThirdPlatformReverseOrder fumaoCouponOrderReverseResponseDataHandle(PayOrder payOrder, String responseData){
        logger.info("fumaoCouponOrderReverseResponseDataHandle enter: responseData="+responseData);
        val thirdPlatformOrder = new ThirdPlatformReverseOrder();
        thirdPlatformOrder.setMcode(payOrder.getMcode());
        thirdPlatformOrder.setMOrderNumber(payOrder.getmOrderNumber());
        thirdPlatformOrder.setPayType(payOrder.getPayType());

        JSONObject resData = JSONObject.fromObject(responseData);
        if(("0").equals(resData.getString("result_code"))) {
            thirdPlatformOrder.setReverseStatus("1"); // 撤销成功
            payOrder.setPayStatus(DictionaryConstant.PAY_STATUS_YTK.getCode());
        } else {
            thirdPlatformOrder.setReverseStatus("0"); // 撤销失败
        }
        return thirdPlatformOrder;
    }

    @Override
    public ThirdPlatformInitFacePay initFacePay(PostInitFacePayRequest initFacePayRequest, MchPayChannel mchPayChannel, PayTypeDict payTypeDict) {
        return null;
    }

    @Override
    public ThirdPlatformInitFacePay initFaceLive(PostInitFacePayRequest initFacePayRequest, MchPayChannel mchPayChannel, PayTypeDict payTypeDict) {
        return null;
    }

    @Override
    public boolean IsSupportPartialRefund() {
        return false;
    }

    /**
     * 富茂券核销取消请求数据整理方法
     * @param payOrder 订单
     * @return String
     */
    private String fumaoCouponOrderCancelRequestDataHandle(PayOrder payOrder){
        Map<String, String> reqObj = new HashMap<>();
        reqObj.put("dev_id", FumaoPayConstants.BUSINESS_ID);
        reqObj.put("nonce_str", WXPayUtils.generateNonceStr());//"123456789");
        String payInfoString = payOrder.getRequestDetailInfo();
        logger.info("fumaoCouponOrderCancelRequestDataHandle::payInfoString="+payInfoString);
        JSONObject payInfoJsonObject  = JSONObject.fromObject(payInfoString);
        try {
//            reqObj.put("order_amount", payInfoJsonObject.getString("order_amount"));
            if(!payInfoJsonObject.getString("mem_phone_number").equals("")) {
                reqObj.put("mem_phone_number", payInfoJsonObject.getString("mem_phone_number"));
            }
            if(!payInfoJsonObject.getString("mem_id").equals("")) {
                reqObj.put("mem_id", payInfoJsonObject.getString("mem_id"));
            }
            reqObj.put("business_type", payInfoJsonObject.getString("business_type"));
            JSONObject paymentInfo = new JSONObject();
            paymentInfo.put("coupon_id",payInfoJsonObject.getString("coupon_id"));
            reqObj.put("payment_info", paymentInfo.toString());
        } catch (Exception e) {
            throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_INFO_NOT_EMPTY);
        }
        FumaoUserInfo userInfo = getFumaoUserInfo(payOrder.getDeviceId(),payOrder.getCreatedBy());
        reqObj.put("merchant_id", userInfo.getMerchantId());
        reqObj.put("tenant_id", userInfo.getTenantId());
        reqObj.put("order_operation_id", userInfo.getOrderOperatorId());
        reqObj.put("order_number_of_platform", payOrder.getmOrderNumber());
        reqObj.put("order_create_sn", payOrder.getDeviceId());
        reqObj.put("sign", SignatureUtils.generateSignature(reqObj, FumaoPayConstants.DEV_REQ_KEY, SignatureUtils.SignType.HMACSHA256));
        JSONObject jsonObject = JSONObject.fromObject(reqObj);
        return jsonObject.toString();
    }

    private ThirdPlatformRefundOrder fumaoCouponOrderRefundResponseDataHandle(PayOrder payOrder, String responseData){
        logger.info("fumaoCouponOrderCancelResponseDataHandle enter: responseData="+responseData);
        val thirdPlatformOrder = new ThirdPlatformRefundOrder();
        thirdPlatformOrder.setMcode(payOrder.getMcode());
        thirdPlatformOrder.setMOrderNumber(payOrder.getmOrderNumber());
        thirdPlatformOrder.setPayType(payOrder.getPayType());

        JSONObject resData = JSONObject.fromObject(responseData);
        if(("0").equals(resData.getString("result_code"))) {
            thirdPlatformOrder.setRefundStatus("2"); // 退款成功
            payOrder.setPayStatus(DictionaryConstant.PAY_STATUS_YTK.getCode());
        } else {
            thirdPlatformOrder.setRefundStatus("0"); // 退款失败
        }
        return thirdPlatformOrder;
    }

    public FumaoUserInfo getFumaoUserInfo(String sn, String userName) {
        String tenantId = getTenantId(sn, userName);
        if(StringUtils.isEmpty(tenantId)) {
            throw new BusinessCommonException(PaymentErrorCode.FUMAO_TENANT_ID_NOT_FOUND);
        }
        FumaoUserInfoExample example = new FumaoUserInfoExample();
        example.createCriteria().andTenantIdEqualTo(tenantId)
                .andOrderOperatorPhoneEqualTo(userName);
        List<FumaoUserInfo> list = fumaoUserInfoMapper.selectByExample(example);
        if (list == null || list.size() <= 0) {
            throw new BusinessCommonException(PaymentErrorCode.USERINFO_INFO_NOT_FOUND);
        }
        return list.get(0);
    }

    public String getTenantId(String sn, String userName) {
        Integer orgId = getOrgId(sn, userName);
        if(orgId != null) {
            return fumaoUserInfoExtMapper.selectTenantByOrgId(orgId);
        } else {
            return null;
        }
    }

    private Integer getOrgId(String sn, String userName) {
        Integer orgId;
        // 通过设备SN获得设备所属orgId
        if(StringUtils.isNotEmpty(sn)) {
            DeviceInfo deviceInfo = PosDeviceRedisUtils.getDeviceInfoBySerialNo(sn);
            if(null == deviceInfo) {
                return null;
            }
            orgId = deviceInfo.getOrganizationId();
        } else { //通过userName获得用户所属orgId (富茂集团不同的广场可能用同一个手机号，该分支应该抛异常 TODO)
            UserInfo userInfo = UserCacheUtils.getUserInfo(userName);
            if(null == userInfo) {
                return null;
            }
            orgId = userInfo.getOrgId();
        }
        return orgId;
    }
}