

package com.nantian.sc.cloud.pay.handler.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.EnumUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jpay.ext.kit.PaymentKit;
import com.jpay.weixin.api.WxPayApiConfigKit;
import com.nantian.sc.cloud.common.data.tenant.TenantContextHolder;
import com.nantian.sc.cloud.pay.entity.PayGoodsOrder;
import com.nantian.sc.cloud.pay.entity.PayNotifyRecord;
import com.nantian.sc.cloud.pay.entity.PayTradeOrder;
import com.nantian.sc.cloud.pay.handler.MessageDuplicateCheckerHandler;
import com.nantian.sc.cloud.pay.service.PayGoodsOrderService;
import com.nantian.sc.cloud.pay.service.PayNotifyRecordService;
import com.nantian.sc.cloud.pay.service.PayTradeOrderService;
import com.nantian.sc.cloud.pay.utils.PayConstants;
import com.nantian.sc.cloud.pay.utils.TradeStatusEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 *
 * @date 2019-06-27
 * <p>
 * 微信回调处理
 */
@Slf4j
@AllArgsConstructor
@Service("weChatCallback")
public class WeChatPayNotifyCallbackHandler extends AbstractPayNotifyCallbakHandler {
	private final MessageDuplicateCheckerHandler duplicateCheckerHandler;
	private final PayTradeOrderService tradeOrderService;
	private final PayGoodsOrderService goodsOrderService;
	private final PayNotifyRecordService recordService;

	/**
	 * 维护租户信息
	 *
	 * @param params
	 */
	@Override
	public void before(Map<String, String> params) {
		Integer tenant = MapUtil.getInt(params, "attach");
		TenantContextHolder.setTenantId(tenant);
	}

	/**
	 * 去重处理
	 *
	 * @param params 回调报文
	 * @return
	 */
	@Override
	public Boolean duplicateChecker(Map<String, String> params) {
		// 判断10秒内是否已经回调处理
		if (duplicateCheckerHandler.isDuplicate(params.get(PayConstants.OUT_TRADE_NO))) {
			log.info("微信订单重复回调 {} 不做处理", params);
			this.saveNotifyRecord(params, "重复回调");
			return true;
		}
		return false;
	}

	/**
	 * 验签逻辑
	 *
	 * @param params 回调报文
	 * @return
	 */
	@Override
	public Boolean verifyNotify(Map<String, String> params) {
		if (!PaymentKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey())) {
			log.warn("微信支付回调验签失败", params);
			return null;
		}

		return true;
	}

	/**
	 * 解析报文
	 *
	 * @param params
	 * @return
	 */
	@Override
	public String parse(Map<String, String> params) {
		String tradeStatus = EnumUtil.fromString(TradeStatusEnum.class, params.get(PayConstants.RESULT_CODE)).getStatus();

		String orderNo = params.get(PayConstants.OUT_TRADE_NO);
		PayGoodsOrder goodsOrder = goodsOrderService.getOne(Wrappers.<PayGoodsOrder>lambdaQuery()
				.eq(PayGoodsOrder::getPayOrderId, orderNo));
		goodsOrder.setStatus(tradeStatus);
		goodsOrderService.updateById(goodsOrder);

		PayTradeOrder tradeOrder = tradeOrderService.getOne(Wrappers.<PayTradeOrder>lambdaQuery()
				.eq(PayTradeOrder::getOrderId, orderNo));
		Long succTime = MapUtil.getLong(params, "time_end");
		tradeOrder.setPaySuccTime(succTime);
		tradeOrder.setStatus(tradeStatus);
		tradeOrder.setChannelOrderNo(params.get("transaction_id"));
		tradeOrder.setErrMsg(params.get("err_code_des"));
		tradeOrder.setErrCode(params.get("err_code"));
		tradeOrderService.updateById(tradeOrder);

		Map<String, String> xml = new HashMap<>(4);
		xml.put("return_code", "SUCCESS");
		xml.put("return_msg", "OK");
		return PaymentKit.toXml(xml);
	}

	/**
	 * 保存回调记录
	 *
	 * @param result 处理结果
	 * @param params 回调报文
	 */
	@Override
	public void saveNotifyRecord(Map<String, String> params, String result) {
		PayNotifyRecord record = new PayNotifyRecord();
		String notifyId = params.get("transaction_id");
		saveRecord(params, result, record, notifyId, recordService);
	}
}
