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

import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.framework.constants.ApplicationConstants;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.utils.LocalIpUtils;
import com.neusoft.smart.pos.framework.utils.MapBeanUtils;
import com.neusoft.smart.pos.payment.constants.PaymentErrorCode;
import com.neusoft.smart.pos.payment.constants.WFTPayConstants;
import com.neusoft.smart.pos.payment.constants.WXPayConstants;
import com.neusoft.smart.pos.payment.persistent.domain.MchPayChannel;
import com.neusoft.smart.pos.payment.persistent.domain.PayOrder;
import com.neusoft.smart.pos.payment.persistent.domain.PayTypeDict;
import com.neusoft.smart.pos.payment.persistent.ext.domain.*;
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 lombok.val;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * @author zcf
 * @date 2018-09-26 10：43
 * @description 威富通支付管理使用Repository
 */
@Component("wftPayRepository")
public class WFTPayRepository implements IThirdPayRepository {

	/**
	 * 创建威富通单使用方法
	 * @param payOrder
	 * @param mchPayChannel
	 * @return
	 */
	@Override
	public ThirdPlatformCreateOrder createPayOrderToThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel, PayTypeDict payTypeDict){
		//1.处理数据
		String xyhfRequestData =  wftCreateOrderRequestDataHandle(payOrder,mchPayChannel,payTypeDict);
		//2.请求微信预付单生成接口
        String responseData = "";
        if(StringUtils.isEmpty(payOrder.getScanCode())){
        	//用户主动扫码支付
	        throw new BusinessCommonException(PaymentErrorCode.WFT_PAY_TYPE_NOT_SUPPORT);
//			responseData = HttpClientUtils.postXMLData(WXPayConstants.DOMAIN_API+WXPayConstants.UNIFIEDORDER_URL_SUFFIX,weixinRequestData);
		}else{
        	//商户扫码支付
			responseData = HttpClientUtils.postXMLData(WFTPayConstants.DOMAIN_API,xyhfRequestData);
		}
        //3.记录日志
		LogUtils.savePaymentTradeLog(payOrder.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_WFT.getCode(),LogUtils.LOG_DESCRIPTION_DDSC,xyhfRequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());

		return wftCreateOrderResponseDataHandle(payOrder,responseData);
	}

	/**
	 * 微信数据整理方法
	 * @param payOrder
	 * @param mchPayChannel
	 * @return
	 */
	private String wftCreateOrderRequestDataHandle(PayOrder payOrder, MchPayChannel mchPayChannel,PayTypeDict payTypeDict){
		val wftPayCreateOrder = new WFTPayCreateOrder();
		wftPayCreateOrder.setMch_id(mchPayChannel.getMchId());
		wftPayCreateOrder.setOut_trade_no(payOrder.getmOrderNumber());
		wftPayCreateOrder.setBody(payOrder.getDescription());
		wftPayCreateOrder.setTotal_fee(String.valueOf(payOrder.getOrderAmount()));
		if(StringUtils.isEmpty(payOrder.getPayIp())){
			wftPayCreateOrder.setMch_create_ip(LocalIpUtils.getLocalIP());
		}else{
			wftPayCreateOrder.setMch_create_ip(payOrder.getPayIp());
		}
		wftPayCreateOrder.setAuth_code(payOrder.getScanCode());
		wftPayCreateOrder.setNonce_str(WXPayUtils.generateNonceStr());
		return WXPayUtils.generateSignedXml(MapBeanUtils.beanToMap(wftPayCreateOrder),mchPayChannel.getSecretKey());
	}

	/**
	 * 威富通响应数据处理
	 * @param payOrder
	 * @param responseData
	 * @return
	 */
	private ThirdPlatformCreateOrder wftCreateOrderResponseDataHandle(PayOrder payOrder, String responseData){
		val resultMap = WXPayUtils.xmlToMap(responseData);
		if(resultMap.containsKey("need_query")){
			if(resultMap.get("need_query").equalsIgnoreCase("Y")){
				val thirdPlatformOrder = new ThirdPlatformCreateOrder();
				thirdPlatformOrder.setMcode(payOrder.getMcode());
				thirdPlatformOrder.setTradeId(payOrder.getTradeId());
				thirdPlatformOrder.setMOrderNumber(payOrder.getmOrderNumber());
				thirdPlatformOrder.setOuterOrderNumber("");
				thirdPlatformOrder.setOuterCodeUrl("");
				thirdPlatformOrder.setPayStatus(DictionaryConstant.PAY_STATUS_WFK.getCode());
				return thirdPlatformOrder;
			}
		}
		if(!resultMap.get("status").equalsIgnoreCase("0")){
			throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_GENERATE_ERROR.getCode(),resultMap.get("message"));
		}
		if(!resultMap.get("result_code").equalsIgnoreCase("0")){
			if(resultMap.get("err_code").equalsIgnoreCase("USERPAYING")){
				//等待用户支付
//				throw new BusinessCommonException(PaymentErrorCode.WX_AUTH_CODE_INVALID);
			}else if(resultMap.get("err_code").equalsIgnoreCase("AUTH_CODE_INVALID")){
				throw new BusinessCommonException(PaymentErrorCode.WX_AUTH_CODE_INVALID);
			}else{
				throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_GENERATE_ERROR.getCode(),resultMap.get("err_msg").toString());
			}
		}
		val thirdPlatformOrder = new ThirdPlatformCreateOrder();
		thirdPlatformOrder.setMcode(payOrder.getMcode());
		thirdPlatformOrder.setTradeId(payOrder.getTradeId());
		thirdPlatformOrder.setMOrderNumber(payOrder.getmOrderNumber());
		thirdPlatformOrder.setOuterOrderNumber(resultMap.get("transaction_id"));
		thirdPlatformOrder.setOuterCodeUrl("");
		if(!StringUtils.isEmpty(payOrder.getScanCode())){
			if(resultMap.containsKey("err_code")&&resultMap.get("err_code").equalsIgnoreCase("USERPAYING")){
				thirdPlatformOrder.setPayStatus(DictionaryConstant.PAY_STATUS_WFK.getCode());
			}else if(resultMap.get("pay_result").equalsIgnoreCase("0")){
				thirdPlatformOrder.setPayStatus(DictionaryConstant.PAY_STATUS_YFK.getCode());
			}
		}
		return thirdPlatformOrder;
	}

	/**
	 * 微信预付订单查询方法
	 * @param payOrder
	 * @param mchPayChannel
	 * @return
	 */
	public ThirdPlatformQueryOrder queryPayOrderFromThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel){
		//1.处理数据
		val wftPayQueryOrder = new WFTPayQueryOrder();
		wftPayQueryOrder.setMch_id(mchPayChannel.getMchId());
		wftPayQueryOrder.setNonce_str(WXPayUtils.generateNonceStr());
		wftPayQueryOrder.setOut_trade_no(payOrder.getmOrderNumber());
		String wftRequestData =  WXPayUtils.generateSignedXml(MapBeanUtils.beanToMap(wftPayQueryOrder),mchPayChannel.getSecretKey());

		String responseData = HttpClientUtils.postXMLData(WFTPayConstants.DOMAIN_API,wftRequestData);
		//3.记录日志
		LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_WFT.getCode(),LogUtils.LOG_DESCRIPTION_DDCS,wftRequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		return wftQueryOrderResponseDataHandle(mchPayChannel.getMcode(),payOrder.getmOrderNumber(),responseData);
	}

	/**
	 * 威富通响应数据处理
	 * @return
	 */
	private ThirdPlatformQueryOrder wftQueryOrderResponseDataHandle(String mcode,String orderNumber, String responseData){
		val resultMap = WXPayUtils.xmlToMap(responseData);
		if(resultMap.containsKey("need_query")){
			if(resultMap.get("need_query").equalsIgnoreCase("Y")){
				val thirdPlatformOrder = new ThirdPlatformQueryOrder();
				thirdPlatformOrder.setMcode(mcode);
				thirdPlatformOrder.setMOrderNumber(orderNumber);
				thirdPlatformOrder.setOuterTradeNumber("");
				thirdPlatformOrder.setTradeStatus(DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode());
				thirdPlatformOrder.setTimeEnd("");
				return thirdPlatformOrder;
			}
		}
		if(!resultMap.get("result_code").equalsIgnoreCase("0")){
			val thirdPlatformOrder = new ThirdPlatformQueryOrder();
			thirdPlatformOrder.setMcode(mcode);
			thirdPlatformOrder.setMOrderNumber(orderNumber);
			thirdPlatformOrder.setOuterTradeNumber("");
			thirdPlatformOrder.setTradeStatus(DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode());
			thirdPlatformOrder.setTimeEnd("");
			return thirdPlatformOrder;
//			throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_GENERATE_ERROR.getCode(),resultMap.get("err_msg"));
		}
		val thirdPlatformOrder = new ThirdPlatformQueryOrder();
		thirdPlatformOrder.setMcode(mcode);
		thirdPlatformOrder.setMOrderNumber(orderNumber);
		thirdPlatformOrder.setOuterTradeNumber(resultMap.get("transaction_id")==null?"":resultMap.get("transaction_id"));
		thirdPlatformOrder.setTradeStatus(getTradeStatus(resultMap.get("trade_state")));
		thirdPlatformOrder.setTimeEnd(resultMap.get("time_end"));
		return thirdPlatformOrder;
	}

	/**
	 * 根据微信交易状态返回支付平台订单状态
	 * @param tradeState
	 * @return
	 */
	private String getTradeStatus(String tradeState){
		String tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode();
		switch(tradeState){
			case "SUCCESS":
				//支付成功
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_YZF.getCode();
				break;
			case "REFUND":
				//转入退款
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_YTK.getCode();
				break;
			case "PARTREFUND":
				//转入退款
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_YTK.getCode();
				break;
			case "NOTPAY":
				//未支付
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode();
				break;
			case "CLOSED":
				//已关闭
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_JYGB.getCode();
				break;
			case "USERPAYING":
				//用户支付中
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode();
				break;
			case "PAYERROR":
				//支付失败(其他原因，如银行返回失败)
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode();
				break;
		}
		return tradeStatus;
	}

	/**
	 * 微信预付订单取消方法
	 * @param payOrder
	 * @param mchPayChannel
	 * @return
	 */
	public ThirdPlatformCancelOrder cannelPayOrderFromThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel){
		//1.处理数据
		val weixinPayCannelOrder = new WeixinPayCannelOrder();
		weixinPayCannelOrder.setAppid(mchPayChannel.getAppid());
		weixinPayCannelOrder.setMch_id(mchPayChannel.getMchId());
		weixinPayCannelOrder.setNonce_str(WXPayUtils.generateNonceStr());
		weixinPayCannelOrder.setOut_trade_no(payOrder.getmOrderNumber());
		String weixinRequestData =  WXPayUtils.generateSignedXml(MapBeanUtils.beanToMap(weixinPayCannelOrder),mchPayChannel.getSecretKey());
		//2.请求微信预付单生成接口
		String responseData = HttpClientUtils.postXMLData(WXPayConstants.DOMAIN_API+WXPayConstants.ORDER_CANNEL_URL_SUFFIX,weixinRequestData);
		//3.记录日志
		LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_WFT.getCode(),LogUtils.LOG_DESCRIPTION_DDQX,weixinRequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		return weixinCannelOrderResponseDataHandle(mchPayChannel.getMcode(),payOrder.getmOrderNumber(),responseData);
	}

	/**
	 * 威富通订单取消响应数据处理
	 * @return
	 */
	private ThirdPlatformCancelOrder weixinCannelOrderResponseDataHandle(String mcode,String orderNumber, String responseData){
		val resultMap = WXPayUtils.xmlToMap(responseData);
		val thirdPlatformCancelOrder = new ThirdPlatformCancelOrder();
		thirdPlatformCancelOrder.setMcode(mcode);
		thirdPlatformCancelOrder.setMOrderNumber(orderNumber);
		thirdPlatformCancelOrder.setPayType(DictionaryConstant.PAYMENT_PAY_TYPE_WFT.getCode());
		if(!resultMap.get("return_code").equalsIgnoreCase(ApplicationConstants.SUCCESS)||!resultMap.get("result_code").equalsIgnoreCase(ApplicationConstants.SUCCESS)){
			thirdPlatformCancelOrder.setCancelStatus("0");
		}else{
			thirdPlatformCancelOrder.setCancelStatus("1");
		}
		return thirdPlatformCancelOrder;
	}

	/**
	 * 微信预付订单退款申请方法
	 * @param payOrder
	 * @param mchPayChannel
	 * @param refundAmount:退款金额
	 * @return
	 */
	@Override
	public ThirdPlatformRefundOrder refundPayOrderFromThirdPlatform(PayOrder payOrder,String refundNumber,Long refundAmount, MchPayChannel mchPayChannel,PayTypeDict payTypeDict) {
		val wftPayRefundOrder = new WFTPayRefundOrder();
		wftPayRefundOrder.setMch_id(mchPayChannel.getMchId());
		wftPayRefundOrder.setOp_user_id(mchPayChannel.getMchId());
		wftPayRefundOrder.setOut_trade_no(payOrder.getmOrderNumber());
		wftPayRefundOrder.setOut_refund_no(refundNumber);
		wftPayRefundOrder.setRefund_fee(payOrder.getOrderAmount());
		wftPayRefundOrder.setTotal_fee(payOrder.getOrderAmount());
		wftPayRefundOrder.setNonce_str(WXPayUtils.generateNonceStr());

		String wftRequestData =  WXPayUtils.generateSignedXml(MapBeanUtils.beanToMap(wftPayRefundOrder),mchPayChannel.getSecretKey());
		//2.请求微信预付单生成接口
		String responseData = HttpClientUtils.postXMLData(WFTPayConstants.DOMAIN_API,wftRequestData);

		//3.记录日志
		LogUtils.savePaymentTradeLog(payOrder.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_WFT.getCode(),LogUtils.LOG_DESCRIPTION_SQTK,wftRequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());

		return wftRefundOrderResponseDataHandle(payOrder,responseData);
	}

	/**
	 * 威富通退款申请响应数据处理
	 * @param payOrder
	 * @param responseData
	 * @return
	 */
	private ThirdPlatformRefundOrder wftRefundOrderResponseDataHandle(PayOrder payOrder, String responseData){
		val resultMap = WXPayUtils.xmlToMap(responseData);
		if(!resultMap.get("status").equalsIgnoreCase("0")){
			throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_GENERATE_ERROR.getCode(),resultMap.get("message"));
		}
		val thirdPlatformOrder = new ThirdPlatformRefundOrder();
		thirdPlatformOrder.setMcode(payOrder.getMcode());
		thirdPlatformOrder.setMOrderNumber(payOrder.getmOrderNumber());
		thirdPlatformOrder.setPayType(payOrder.getPayType());
		if(!resultMap.get("result_code").equalsIgnoreCase("0")){
			thirdPlatformOrder.setRefundStatus("0");
		}else{
			thirdPlatformOrder.setRefundNumber(resultMap.get("out_refund_no"));
			thirdPlatformOrder.setThirdRefundNumber(resultMap.get("refund_id"));
			thirdPlatformOrder.setRefundAmount(Long.parseLong(resultMap.get("refund_fee")));
			thirdPlatformOrder.setRefundStatus("2");
		}
		return thirdPlatformOrder;
	}

	/**
	 * 预付单撤销使用方法
	 * @return
	 */
	public ThirdPlatformReverseOrder reversePayOrderFromThirdPlatform(PayOrder payOrder, String orderNumber, MchPayChannel mchPayChannel){
		//1.处理数据
		val wftPayReverseOrder = new WFTPayReverseOrder();
		wftPayReverseOrder.setMch_id(mchPayChannel.getMchId());
		wftPayReverseOrder.setNonce_str(WXPayUtils.generateNonceStr());
		wftPayReverseOrder.setOut_trade_no(orderNumber);
		String wftRequestData =  WXPayUtils.generateSignedXml(MapBeanUtils.beanToMap(wftPayReverseOrder),mchPayChannel.getSecretKey());

		String responseData = HttpClientUtils.postXMLData(WFTPayConstants.DOMAIN_API,wftRequestData);
		//3.记录日志
		LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),orderNumber, DictionaryConstant.PAYMENT_PAY_TYPE_WFT.getCode(),LogUtils.LOG_DESCRIPTION_DDCX,wftRequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		return wftReverseOrderResponseDataHandle(mchPayChannel.getMcode(),orderNumber,responseData);
	}

	/**
	 * 威富通订单撤销响应数据处理
	 * @return
	 */
	private ThirdPlatformReverseOrder wftReverseOrderResponseDataHandle(String mcode,String orderNumber, String responseData){
		val resultMap = WXPayUtils.xmlToMap(responseData);
		if(!resultMap.get("result_code").equalsIgnoreCase("0")){
			throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_GENERATE_ERROR.getCode(),resultMap.get("err_msg"));
		}
		val thirdPlatformReverseOrder = new ThirdPlatformReverseOrder();
		thirdPlatformReverseOrder.setMcode(mcode);
		thirdPlatformReverseOrder.setMOrderNumber(orderNumber);
		thirdPlatformReverseOrder.setPayType(DictionaryConstant.PAYMENT_PAY_TYPE_WFT.getCode());
		if(resultMap.get("result_code").equalsIgnoreCase("0")){
			thirdPlatformReverseOrder.setReverseStatus("2");
		}else{
			thirdPlatformReverseOrder.setReverseStatus("1");
		}
		return thirdPlatformReverseOrder;
	}

}
