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

import com.neusoft.smart.pos.constants.DictionaryConstant;
import com.neusoft.smart.pos.dto.card.request.*;
import com.neusoft.smart.pos.dto.card.response.CardTradeCreateResponse;
import com.neusoft.smart.pos.dto.card.response.CardTradeQueryResponse;
import com.neusoft.smart.pos.dto.card.response.CardTradeRefundResponse;
import com.neusoft.smart.pos.dto.payment.request.PostInitFacePayRequest;
import com.neusoft.smart.pos.framework.constants.ApplicationConstants;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.utils.LocalDateTimeUtils;
import com.neusoft.smart.pos.payment.persistent.ext.domain.*;
import com.neusoft.smart.pos.payment.service.RemoteCardTradeService;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;

/**
 * @author cy
 * 2020-02-28
 * description: 卡余额支付管理使用Repository
 */
@Component("cardBalancePayRepository")
public class CardBalancePayRepository implements IThirdPayRepository {
	private final static Logger logger = LoggerFactory.getLogger(CardBalancePayRepository.class);

	@Resource
	private RemoteCardTradeService remoteCardTradeService;
	/**
	 * 创建卡支付单使用方法
	 * @param payOrder 支付订单
	 * @param mchPayChannel 商户支付渠道信息
	 * @return  返回给前端的jsonString
	 */
	@Override
	public String createPayOrderToThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel, PayTypeDict payTypeDict){
		//1.处理数据
		CardTradeCreateRequest cardTradeCreateRequest = cardCreateOrderRequestDataHandle(payOrder,mchPayChannel,payTypeDict);
		//2.请求卡支付单生成接口
		val responseData = remoteCardTradeService.createOrder(payOrder.getDeviceId(),cardTradeCreateRequest);
		//3.记录日志
		LogUtils.savePaymentTradeLog(payOrder.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_CARD_BALANCE_PAY.getCode(),LogUtils.LOG_DESCRIPTION_DDSC,JSONObject.fromObject(cardTradeCreateRequest).toString(),JSONObject.fromObject(responseData).toString(),DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		if (null == responseData || !ApplicationConstants.SUCCESS_CODE.equals(responseData.getCode())) {
			throw new BusinessCommonException(responseData);
		}

		return cardCreateOrderResponseDataHandle(payOrder,responseData.getResult());
	}

	/**
	 * 卡支付数据整理方法
	 * @param payOrder 支付订单
	 * @param mchPayChannel 商户支付渠道信息
	 * @return 请求数据
	 */
	private CardTradeCreateRequest cardCreateOrderRequestDataHandle(PayOrder payOrder, MchPayChannel mchPayChannel, PayTypeDict payTypeDict){
		val cardTradeCreateRequest = new CardTradeCreateRequest();
		cardTradeCreateRequest.setOutTradeId(payOrder.getTradeId());
		cardTradeCreateRequest.setPayAmount(payOrder.getPayAmount());
		JSONObject payInfoJsonObject  = JSONObject.fromObject(payOrder.getRequestDetailInfo());
		try {
			cardTradeCreateRequest.setSourceCardNum(payInfoJsonObject.getString("sourceCardNum"));
			payOrder.setCardNum(cardTradeCreateRequest.getSourceCardNum());
		} catch (Exception e) {
			logger.info("cardCreateOrderRequestDataHandle:sourceCardNum is null");
		}
		try {
			cardTradeCreateRequest.setSourceCardOtherId(payInfoJsonObject.getString("sourceCardOtherId"));
			payOrder.setCardHidCode(cardTradeCreateRequest.getSourceCardOtherId());
		} catch (Exception e) {
			logger.info("cardCreateOrderRequestDataHandle:sourceCardOtherId is null");
		}
		try {
			cardTradeCreateRequest.setSourceCardAnotherId(payInfoJsonObject.getString("sourceCardAnotherId"));
		} catch (Exception e) {
			logger.info("cardCreateOrderRequestDataHandle:sourceCardAnotherId is null");
		}
		try {
			cardTradeCreateRequest.setTargetCardNum(payInfoJsonObject.getString("targetCardNum"));
		} catch (Exception e) {
			logger.info("cardCreateOrderRequestDataHandle:targetCardNum is null");
		}
		try {
			cardTradeCreateRequest.setTargetCardOtherId(payInfoJsonObject.getString("targetCardOtherId"));
		} catch (Exception e) {
			logger.info("cardCreateOrderRequestDataHandle:targetCardOtherId is null");
		}
		try {
			cardTradeCreateRequest.setTargetCardAnotherId(payInfoJsonObject.getString("targetCardAnotherId"));
		} catch (Exception e) {
			logger.info("cardCreateOrderRequestDataHandle:targetCardAnotherId is null");
		}
		try {
			cardTradeCreateRequest.setCardPassword(payInfoJsonObject.getString("cardPassword"));
		} catch (Exception e) {
			logger.info("cardCreateOrderRequestDataHandle:cardPassword is null");
		}
		cardTradeCreateRequest.setPayType("1"); //@1：卡内余额支付 @2：积分支付

		return cardTradeCreateRequest;
	}

	/**
	 * 卡支付响应数据处理
	 * @param payOrder 支付订单
	 * @param cardTradeCreateResponse 响应数据
	 * @return 给前台数据
	 */
	private String cardCreateOrderResponseDataHandle(PayOrder payOrder, CardTradeCreateResponse cardTradeCreateResponse){
		payOrder.setOuterOrderNumber(cardTradeCreateResponse.getCardTradeNum());
		payOrder.setPayStatus(getTradeStatus(cardTradeCreateResponse.getPayStatus()));
		payOrder.setPayTime(cardTradeCreateResponse.getPayTime());

		JSONObject payResponseJsonObject = new JSONObject();
		payResponseJsonObject.put("balance",cardTradeCreateResponse.getBalance());
		payResponseJsonObject.put("point",cardTradeCreateResponse.getPoint());
		payOrder.setResponseDetailInfo(payResponseJsonObject.toString());
		return payResponseJsonObject.toString();
	}

	/**
	 * 卡支付订单查询方法
	 * @param payOrder 支付订单
	 * @param mchPayChannel 商户支付渠道信息
	 * @return 查询响应
	 */
	public ThirdPlatformQueryOrder queryPayOrderFromThirdPlatform(PayOrder payOrder, MchPayChannel mchPayChannel){
		//1.处理数据
		val cardTradeQueryRequest = new CardTradeQueryRequest();
		cardTradeQueryRequest.setOutTradeId(payOrder.getTradeId());

		//2.请求卡支付单生成接口
		val responseData = remoteCardTradeService.queryOrder(cardTradeQueryRequest);

		//3.记录日志
		LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_CARD_BALANCE_PAY.getCode(),LogUtils.LOG_DESCRIPTION_DDCS,JSONObject.fromObject(cardTradeQueryRequest).toString(),JSONObject.fromObject(responseData).toString(),DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		if (null == responseData || !ApplicationConstants.SUCCESS_CODE.equals(responseData.getCode())) {
			throw new BusinessCommonException(responseData);
		}

		return cardQueryOrderResponseDataHandle(mchPayChannel.getMcode(),payOrder.getmOrderNumber(),responseData.getResult());
	}

	/**
	 * 卡支付响应数据处理
	 * @return 查询响应
	 */
	private ThirdPlatformQueryOrder cardQueryOrderResponseDataHandle(String mcode, String orderNumber, CardTradeQueryResponse cardTradeQueryResponse){
		val thirdPlatformOrder = new ThirdPlatformQueryOrder();
		thirdPlatformOrder.setMcode(mcode);
		thirdPlatformOrder.setMOrderNumber(orderNumber);
		thirdPlatformOrder.setOuterTradeNumber(cardTradeQueryResponse.getCardTradeNum());
		thirdPlatformOrder.setTradeStatus(cardTradeQueryResponse.getPayStatus());
		thirdPlatformOrder.setTimeEnd(LocalDateTimeUtils.convertLocalDateTimeToString(LocalDateTimeUtils.convertDateToLocalDateTime(cardTradeQueryResponse.getPayTime()),LocalDateTimeUtils.DEFAULT_DATETIME_FORMAT));
		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 "CANCELED"://已取消
			case "REVERSE": //已撤销
			case "CLOSED"://已关闭
				tradeStatus = DictionaryConstant.PAYMENT_ORDER_STATUS_JYGB.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 cardTradeCancelRequest = new CardTradeCancelRequest();
		cardTradeCancelRequest.setOutTradeId(payOrder.getTradeId());

		//2.请求卡支付单生成接口
		val responseData = remoteCardTradeService.cancelOrder(cardTradeCancelRequest);

		//3.记录日志
		LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_CARD_BALANCE_PAY.getCode(),LogUtils.LOG_DESCRIPTION_DDQX,JSONObject.fromObject(cardTradeCancelRequest).toString(),JSONObject.fromObject(responseData).toString(),DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		if (null == responseData || !ApplicationConstants.SUCCESS_CODE.equals(responseData.getCode())) {
			throw new BusinessCommonException(responseData);
		}
		return cardCannelOrderResponseDataHandle(mchPayChannel.getMcode(),payOrder.getmOrderNumber());
	}

	/**
	 * 卡支付订单取消响应数据处理
	 * @return 订单取消应答
	 */
	private ThirdPlatformCancelOrder cardCannelOrderResponseDataHandle(String mcode, String orderNumber){
		val thirdPlatformCancelOrder = new ThirdPlatformCancelOrder();
		thirdPlatformCancelOrder.setMcode(mcode);
		thirdPlatformCancelOrder.setMOrderNumber(orderNumber);
		thirdPlatformCancelOrder.setPayType(DictionaryConstant.PAYMENT_PAY_TYPE_CARD_BALANCE_PAY.getCode());
		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) {
		//1.处理数据
		val cardTradeRefundRequest = new CardTradeRefundRequest();
		cardTradeRefundRequest.setOutTradeId(payOrder.getTradeId());
		cardTradeRefundRequest.setOutRefundNumber(refundNumber);
		cardTradeRefundRequest.setCardTradeNum(payOrder.getOuterOrderNumber());
		cardTradeRefundRequest.setRefundAmount(refundAmount);

		//2.请求卡支付单生成接口
		val responseData = remoteCardTradeService.refundOrder(cardTradeRefundRequest);

		//3.记录日志
		LogUtils.savePaymentTradeLog(payOrder.getMcode(),payOrder.getmOrderNumber(), DictionaryConstant.PAYMENT_PAY_TYPE_CARD_BALANCE_PAY.getCode(),LogUtils.LOG_DESCRIPTION_SQTK,JSONObject.fromObject(cardTradeRefundRequest).toString(),JSONObject.fromObject(responseData).toString(),DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		if (null == responseData || !ApplicationConstants.SUCCESS_CODE.equals(responseData.getCode())) {
			throw new BusinessCommonException(responseData);
		}

		return cardRefundOrderResponseDataHandle(payOrder,responseData.getResult());
	}

	/**
	 * 卡支付退款申请响应数据处理
	 * @param payOrder 支付订单
	 * @param cardTradeRefundResponse 第三方应答
	 * @return 退款应答
	 */
	private ThirdPlatformRefundOrder cardRefundOrderResponseDataHandle(PayOrder payOrder, CardTradeRefundResponse cardTradeRefundResponse){
		val thirdPlatformOrder = new ThirdPlatformRefundOrder();
		thirdPlatformOrder.setMcode(payOrder.getMcode());
		thirdPlatformOrder.setMOrderNumber(payOrder.getmOrderNumber());
		thirdPlatformOrder.setPayType(payOrder.getPayType());
		thirdPlatformOrder.setRefundNumber(cardTradeRefundResponse.getOutRefundNumber());
		thirdPlatformOrder.setThirdRefundNumber(cardTradeRefundResponse.getCardRefundNum());
		thirdPlatformOrder.setRefundAmount(cardTradeRefundResponse.getRefundAmount());
		thirdPlatformOrder.setRefundStatus("2");
		return thirdPlatformOrder;
	}

	/**
	 * 卡支付单撤销使用方法
	 * @return 撤销应答
	 */
	public ThirdPlatformReverseOrder reversePayOrderFromThirdPlatform(PayOrder payOrder, String orderNumber, MchPayChannel mchPayChannel){
		//1.处理数据
		val cardTradeReverseRequest = new CardTradeReverseRequest();
		cardTradeReverseRequest.setOutTradeId(payOrder.getTradeId());

		//2.请求卡支付单生成接口
		val responseData = remoteCardTradeService.reverseOrder(cardTradeReverseRequest);

		//3.记录日志
		LogUtils.savePaymentTradeLog(mchPayChannel.getMcode(),orderNumber, DictionaryConstant.PAYMENT_PAY_TYPE_CARD_BALANCE_PAY.getCode(),LogUtils.LOG_DESCRIPTION_DDCX,JSONObject.fromObject(cardTradeReverseRequest).toString(),JSONObject.fromObject(responseData).toString(),DictionaryConstant.PAYMENT_REQUEST_TYPE_ZD.getCode());
		if (null == responseData || !ApplicationConstants.SUCCESS_CODE.equals(responseData.getCode())) {
			throw new BusinessCommonException(responseData);
		}

		return cardReverseOrderResponseDataHandle(mchPayChannel.getMcode(),orderNumber);
	}

	@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 cardReverseOrderResponseDataHandle(String mcode, String orderNumber){
		val thirdPlatformReverseOrder = new ThirdPlatformReverseOrder();
		thirdPlatformReverseOrder.setMcode(mcode);
		thirdPlatformReverseOrder.setMOrderNumber(orderNumber);
		thirdPlatformReverseOrder.setPayType(DictionaryConstant.PAYMENT_PAY_TYPE_CARD_BALANCE_PAY.getCode());
		thirdPlatformReverseOrder.setReverseStatus("1");
		return thirdPlatformReverseOrder;
	}

}
