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

import com.alibaba.fastjson.JSON;
import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.payment.request.PostInitFacePayRequest;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.payment.constants.ChinaumsPayConstants;
import com.neusoft.smart.pos.payment.constants.PaymentErrorCode;
import com.neusoft.smart.pos.payment.persistent.ext.domain.*;
import com.neusoft.smart.pos.payment.utils.ChinaumsSign;
import com.neusoft.smart.pos.payment.utils.HttpClientUtils;
import com.neusoft.smart.pos.payment.utils.LogUtils;
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 lombok.val;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Component;

import java.util.HashMap;

/**
 * @author tjm
 * @date 2018-07-25 10：43
 * @description 银联商务B扫C支付使用Repository
 */
@Component("chinaumsPayBScanCRepository")
public class ChinaumsPayBScanCRepository implements IThirdPayRepository {

	/**
	 * 创建银联商务B扫C支付使用方法
	 * @param payOrder
	 * @param mchPayChannel
	 * @return
	 */
	@Override
	public String createPayOrderToThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel, PayTypeDict payTypeDict){
		//1.处理数据
		String chinaumsRequestData =  chinaumsCreateOrderRequestDataHandle(payOrder,mchPayChannel,payTypeDict);
		System.out.println(chinaumsRequestData);
		//2.生成认证签名http头信息
		String authorization = ChinaumsSign.sign(chinaumsRequestData, mchPayChannel.getAppid(), mchPayChannel.getAppSecretKey());
		//3.请求微信预付单生成接口
		String responseData = HttpClientUtils.postDataWithHeader(ChinaumsPayConstants.DOMAIN_BSC_PAY, chinaumsRequestData, authorization);
		System.out.println(responseData);
        //4.记录日志
		LogUtils.savePaymentTradeLog(payOrder.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_YLSW_BSC_SERCIE.getCode(),LogUtils.LOG_DESCRIPTION_DDSC,chinaumsRequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());

		return chinaumsCreateOrderResponseDataHandle(payOrder,responseData);
	}

	/**
	 * 银联商务数据整理方法
	 * @param payOrder
	 * @param mchPayChannel
	 * @return
	 */
	private String chinaumsCreateOrderRequestDataHandle(PayOrder payOrder, MchPayChannel mchPayChannel,PayTypeDict payTypeDict){
		val chinaumsPayOrder = new ChinaumsBscPayCreateOrder();
		chinaumsPayOrder.setMerchantCode(mchPayChannel.getMchId());
		chinaumsPayOrder.setMerchantOrderId(payOrder.getmOrderNumber());
		chinaumsPayOrder.setMerchantRemark(ChinaumsPayConstants.MCH_REMARK);
		JSONObject payInfoJsonObject  = JSONObject.fromObject(payOrder.getRequestDetailInfo());
		try {
			chinaumsPayOrder.setPayCode(payInfoJsonObject.getString("scanCode"));
			payOrder.setScanCode(chinaumsPayOrder.getPayCode());
		} catch (Exception e) {
			throw new BusinessCommonException(PaymentErrorCode.PAY_TYPE_INFO_NOT_EMPTY);
		}
		chinaumsPayOrder.setPayCode(payOrder.getScanCode());
		chinaumsPayOrder.setPayMode(ChinaumsPayConstants.PAY_MODE);
		chinaumsPayOrder.setTerminalCode(mchPayChannel.getSubMchId());
		chinaumsPayOrder.setTransactionAmount(payOrder.getPayAmount());
		chinaumsPayOrder.setTransactionCurrencyCode(ChinaumsPayConstants.CURRENCY_CODE);
		return JSON.toJSONString(chinaumsPayOrder);
	}

	/**
	 * 银联商务支付响应数据处理
	 * @param payOrder
	 * @param responseData
	 * @return
	 */
	private String chinaumsCreateOrderResponseDataHandle(PayOrder payOrder, String responseData){
		val resultMap = JSON.parseObject(responseData, HashMap.class);
		if(!resultMap.get("errCode").toString().equalsIgnoreCase(ChinaumsPayConstants.BSC_SUCCESS)){
			throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_GENERATE_ERROR.getCode(),resultMap.get("errInfo").toString());
		}
		payOrder.setOuterOrderNumber(resultMap.get("orderId").toString());
		payOrder.setCodeUrl(resultMap.get("billQRCode").toString());
		JSONObject payResponseJsonObject = new JSONObject();
		payResponseJsonObject.put("CodeUrl",payOrder.getCodeUrl());
		return payResponseJsonObject.toString();
//		val thirdPlatformOrder = new ThirdPlatformCreateOrder();
//		thirdPlatformOrder.setMcode(payOrder.getMcode());
//		thirdPlatformOrder.setTradeId(payOrder.getTradeId());
//		thirdPlatformOrder.setMOrderNumber(payOrder.getmOrderNumber());
//		thirdPlatformOrder.setOuterOrderNumber(resultMap.get("orderId").toString());
//		//thirdPlatformOrder.setOuterCodeUrl(resultMap.get("billQRCode").toString());
//		thirdPlatformOrder.setPayStatus(DictionaryConstant.PAY_STATUS_YFK.getCode());
//		return thirdPlatformOrder;
	}

	/**
	 * 银联商务B扫C订单查询方法
	 * @param payOrder
	 * @param mchPayChannel
	 * @return
	 */
	public ThirdPlatformQueryOrder queryPayOrderFromThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel){
		//1.处理数据
		val chinaumsBscQueryOrder = new ChinaumsBscPayQueryOrder();
		chinaumsBscQueryOrder.setMerchantCode(mchPayChannel.getMchId());
		chinaumsBscQueryOrder.setTerminalCode(mchPayChannel.getSubMchId());
		chinaumsBscQueryOrder.setMerchantOrderId(payOrder.getmOrderNumber());
		String chinaumsRequestData = JSON.toJSONString(chinaumsBscQueryOrder);
		//2.生成认证签名http头信息
		String authorization = ChinaumsSign.sign(chinaumsRequestData, mchPayChannel.getAppid(), mchPayChannel.getAppSecretKey());
		//3.请求银商预付单生成接口
		String responseData = HttpClientUtils.postDataWithHeader(ChinaumsPayConstants.DOMAIN_BSC_QUERY, chinaumsRequestData, authorization);
		System.out.println(responseData);
		//4.记录日志
		LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_YLSW_BSC_SERCIE.getCode(),LogUtils.LOG_DESCRIPTION_DDCS,chinaumsRequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		return chinaumsQueryOrderResponseDataHandle(mchPayChannel.getMcode(),payOrder.getmOrderNumber(),responseData);
	}

	/**
	 * 银联商务支付响应数据处理
	 * @return
	 */
	private ThirdPlatformQueryOrder chinaumsQueryOrderResponseDataHandle(String mcode,String orderNumber, String responseData){
		val resultMap = JSON.parseObject(responseData, HashMap.class);
		if(!resultMap.get("errCode").toString().equalsIgnoreCase(ChinaumsPayConstants.BSC_SUCCESS)){
			throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_GENERATE_ERROR.getCode(),resultMap.get("errInfo").toString());
		}
		val thirdPlatformOrder = new ThirdPlatformQueryOrder();
		thirdPlatformOrder.setMcode(mcode);
		thirdPlatformOrder.setMOrderNumber(orderNumber);
		//处理支付信息
		if (resultMap.get("queryResCode").toString().equalsIgnoreCase(ChinaumsPayConstants.QUERY_SUCCESS)){
			thirdPlatformOrder.setTradeStatus(DictionaryConstant.PAYMENT_ORDER_STATUS_YZF.getCode());
			thirdPlatformOrder.setOuterTradeNumber(resultMap.get("orderId").toString());
			thirdPlatformOrder.setTimeEnd(resultMap.get("originalTransactionTime").toString());
		}else{
			thirdPlatformOrder.setTradeStatus(DictionaryConstant.PAYMENT_ORDER_STATUS_JYGB.getCode());
		}
		return thirdPlatformOrder;
	}

	/**
	 * 根据银联商务交易状态返回支付平台订单状态
	 * @param tradeState
	 * @return
	 */
//	private String getTradeStatus(String tradeState){
//		String tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode();
//		switch(tradeState){
//			case "PAID":
//				//支付成功
//				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_YZF.getCode();
//				break;
//			case "REFUND":
//				//转入退款
//				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_TKZ.getCode();
//				break;
//			case "UNPAID":
//				//未支付
//				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_DZF.getCode();
//				break;
//			case "CLOSED":
//				//已关闭
//				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_JYGB.getCode();
//				break;
//		}
//		return tradeStatus;
//	}

	/**
	 * 银联商务B扫C订单取消方法
	 * @param payOrder
	 * @param mchPayChannel
	 * @return
	 */
	public ThirdPlatformCancelOrder cannelPayOrderFromThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel){
		//1.处理数据
		val chinaumsPayVoidOrder = new ChinaumsBscPayVoidOrder();
		chinaumsPayVoidOrder.setMerchantCode(mchPayChannel.getMchId());
		chinaumsPayVoidOrder.setTerminalCode(mchPayChannel.getSubMchId());
		chinaumsPayVoidOrder.setOriginalOrderId(payOrder.getOuterOrderNumber());
		String chinaumsRequestData = JSON.toJSONString(chinaumsPayVoidOrder);
		//2.生成认证签名http头信息
		String authorization = ChinaumsSign.sign(chinaumsRequestData, mchPayChannel.getAppid(), mchPayChannel.getAppSecretKey());
		//3.发送取消接口请求
		String responseData = HttpClientUtils.postDataWithHeader(ChinaumsPayConstants.DOMAIN_BSC_VOID, chinaumsRequestData, authorization);
		System.out.println(responseData);
		//4.记录日志
		LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_YLSW_BSC_SERCIE.getCode(),LogUtils.LOG_DESCRIPTION_DDQX,chinaumsRequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		return chinaumsCannelOrderResponseDataHandle(mchPayChannel.getMcode(),payOrder.getmOrderNumber(),responseData);
	}

	/**
	 * 银联商务B扫C订单取消响应数据处理
	 * @return
	 */
	private ThirdPlatformCancelOrder chinaumsCannelOrderResponseDataHandle(String mcode,String orderNumber, String responseData){
		val resultMap = JSON.parseObject(responseData, HashMap.class);
		if(!resultMap.get("errCode").toString().equalsIgnoreCase(ChinaumsPayConstants.BSC_SUCCESS)){
			throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_GENERATE_ERROR.getCode(),resultMap.get("errInfo").toString());
		}
		val thirdPlatformCancelOrder = new ThirdPlatformCancelOrder();
		thirdPlatformCancelOrder.setMcode(mcode);
		thirdPlatformCancelOrder.setMOrderNumber(orderNumber);
		thirdPlatformCancelOrder.setPayType(DictionaryConstant.PAYMENT_PAY_TYPE_YLSW_BSC_SERCIE.getCode());
		thirdPlatformCancelOrder.setCancelStatus("1");
		return thirdPlatformCancelOrder;
	}

	/**
	 * 银联商务B扫C订单退款申请方法
	 * @param payOrder
	 * @param mchPayChannel
	 * @param refundAmount:退款金额
	 * @return
	 */
	@Override
	public ThirdPlatformRefundOrder refundPayOrderFromThirdPlatform(PayOrder payOrder,String refundNumber,Long refundAmount, MchPayChannel mchPayChannel,PayTypeDict payTypeDict) {
		//1.处理数据
		val chinaumsPayRefundOrder = new ChinaumsBscPayRefundOrder();
		chinaumsPayRefundOrder.setMerchantCode(mchPayChannel.getMchId());
		chinaumsPayRefundOrder.setTerminalCode(mchPayChannel.getSubMchId());
		chinaumsPayRefundOrder.setMerchantOrderId(payOrder.getmOrderNumber());
		chinaumsPayRefundOrder.setRefundRequestId(Long.toString(System.currentTimeMillis()));
		chinaumsPayRefundOrder.setTransactionAmount(payOrder.getPayAmount());
		String chinaumsRequestData = JSON.toJSONString(chinaumsPayRefundOrder);
		//2.生成认证签名http头信息
		String authorization = ChinaumsSign.sign(chinaumsRequestData, mchPayChannel.getAppid(), mchPayChannel.getAppSecretKey());
		//3.发送取消接口请求		
		String responseData = HttpClientUtils.postDataWithHeader(ChinaumsPayConstants.DOMAIN_BSC_REFUND, chinaumsRequestData, authorization);
		System.out.println(responseData);
		//3.记录日志
		LogUtils.savePaymentTradeLog(payOrder.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_YLSW_BSC_SERCIE.getCode(),LogUtils.LOG_DESCRIPTION_SQTK,chinaumsRequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		return chinaumsRefundOrderResponseDataHandle(payOrder,refundNumber,responseData);
	}

	/**
	 * 银联商务退款申请响应数据处理
	 * @param payOrder
	 * @param responseData
	 * @return
	 */
	private ThirdPlatformRefundOrder chinaumsRefundOrderResponseDataHandle(PayOrder payOrder,String refundNumber, String responseData){
		val resultMap = JSON.parseObject(responseData, HashMap.class);
		if(!resultMap.get("errCode").toString().equalsIgnoreCase(ChinaumsPayConstants.BSC_SUCCESS)){
			throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_GENERATE_ERROR.getCode(),resultMap.get("errInfo").toString());
		}
		val thirdPlatformOrder = new ThirdPlatformRefundOrder();
		thirdPlatformOrder.setMcode(payOrder.getMcode());
		thirdPlatformOrder.setMOrderNumber(payOrder.getmOrderNumber());
		thirdPlatformOrder.setPayType(payOrder.getPayType());
		thirdPlatformOrder.setRefundNumber(refundNumber);
		thirdPlatformOrder.setRefundAmount(payOrder.getPayAmount());
		thirdPlatformOrder.setRefundStatus("2");
		thirdPlatformOrder.setThirdRefundNumber(resultMap.get("retrievalRefNum").toString());		
		return thirdPlatformOrder;
	}

	/**
	 * 预付单撤销使用方法
	 * @return
	 */
	public ThirdPlatformReverseOrder reversePayOrderFromThirdPlatform(PayOrder payOrder, String orderNumber, MchPayChannel mchPayChannel){
		//1.处理数据
		val chinaumsBscPayReverseOrder = new ChinaumsBscPayReverseOrder();
		chinaumsBscPayReverseOrder.setMerchantCode(mchPayChannel.getMchId());
		chinaumsBscPayReverseOrder.setTerminalCode(mchPayChannel.getSubMchId());
		chinaumsBscPayReverseOrder.setMerchantOrderId(orderNumber);
		chinaumsBscPayReverseOrder.setTransactionAmount(payOrder.getPayAmount());
		chinaumsBscPayReverseOrder.setTransactionCurrencyCode(ChinaumsPayConstants.CURRENCY_CODE);
		String chinaumsRequestData = JSON.toJSONString(chinaumsBscPayReverseOrder);
		//2.生成认证签名http头信息
		String authorization = ChinaumsSign.sign(chinaumsRequestData, mchPayChannel.getAppid(), mchPayChannel.getAppSecretKey());
		//3.发送取消接口请求		
		String responseData = HttpClientUtils.postDataWithHeader(ChinaumsPayConstants.DOMAIN_BSC_REVERSE, chinaumsRequestData, authorization);
		System.out.println(responseData);		
		
		//3.记录日志
		LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),orderNumber, DictionaryConstant.PAYMENT_PAY_TYPE_YLSW_BSC_SERCIE.getCode(),LogUtils.LOG_DESCRIPTION_DDCX,chinaumsRequestData,responseData,DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		return chinaumsReverseOrderResponseDataHandle(mchPayChannel.getMcode(),orderNumber,responseData);
	}

	@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;
	}

	/**
	 * 银联商务支付订单撤销响应数据处理
	 * @return
	 */
	private ThirdPlatformReverseOrder chinaumsReverseOrderResponseDataHandle(String mcode,String orderNumber, String responseData){
		val resultMap = JSON.parseObject(responseData, HashMap.class);
		if(!resultMap.get("errCode").toString().equalsIgnoreCase(ChinaumsPayConstants.BSC_SUCCESS)){
			throw new BusinessCommonException(PaymentErrorCode.MCH_ORDER_GENERATE_ERROR.getCode(),resultMap.get("errInfo").toString());
		}
		val thirdPlatformReverseOrder = new ThirdPlatformReverseOrder();
		thirdPlatformReverseOrder.setMcode(mcode);
		thirdPlatformReverseOrder.setMOrderNumber(orderNumber);
		thirdPlatformReverseOrder.setPayType(DictionaryConstant.PAYMENT_PAY_TYPE_YLSW_BSC_SERCIE.getCode());
		thirdPlatformReverseOrder.setReverseStatus("2");
		return thirdPlatformReverseOrder;
	}
}
