package org.springblade.yeePay.listener;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springblade.common.constant.SystemConstant;
import org.springblade.common.utils.MoneyDesUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.guosen.billRecord.entity.BillRecord;
import org.springblade.modules.guosen.billRecord.service.IBillRecordService;
import org.springblade.modules.guosen.bussiness.entity.Bussiness;
import org.springblade.modules.guosen.bussiness.service.IBussinessService;
import org.springblade.yeePay.event.GatewayEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Objects;


@Component
public class GatewayNotifyListener {

	@Autowired
	private IBillRecordService billRecordService;
	@Autowired
	private IBussinessService bussinessService;
	@Autowired
	private PlatformTransactionManager platformTransactionManager;
	@Autowired
	private TransactionDefinition transactionDefinition;

	/**
	 * 网关充值回调业务逻辑处理（旧版）
	 *
	 * @param gatewayEvent 回调事件
	 */
	@EventListener
	@Async
	public void notifyBusiness(GatewayEvent gatewayEvent) {
		JSONObject decryptData = gatewayEvent.getDecryptData(); //获取回调信息，解密后的数据

		//通过orderId获取订单详细
		BillRecord billRecord = billRecordService.getBaseMapper().selectOne(new QueryWrapper<>(new BillRecord()).lambda().eq(BillRecord::getOrderId, decryptData.get("requestNo")));
		if(billRecord == null){
			return;
		}
		if (billRecord.getPayStatus() != SystemConstant.BillRecordPayStatus.PAYED.getValue() || billRecord.getPayStatus() != SystemConstant.BillRecordPayStatus.FAIL.getValue()) {
			if (billRecord.getType() == SystemConstant.BillRecordType.ADS.getValue()) {//采购商充值
				Object status = decryptData.get("status");
				String payWay = decryptData.getString("payType");
				if (Objects.equals(status, "SUCCESS")) {
					Bussiness bussiness = bussinessService.getById(billRecord.getUserId());
					TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
					//处理逻辑
					try {
						if (bussiness != null) {
							//接口查询采购商余额
							R<BigDecimal> newRemainR = bussinessService.queryBalance(bussiness.getMerchantNo());
							BigDecimal newRemain = newRemainR.getData();
							bussiness.setRemain(MoneyDesUtil.encrypt(newRemain.toString(),MoneyDesUtil.KEY_FOR_UC));
							bussinessService.updateRemain(bussiness);
						}
						billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
						billRecord.setPayWay(payWay);
						billRecord.setThirdPayLog(decryptData.toJSONString());
						billRecordService.updateById(billRecord);
						//提交事务
						platformTransactionManager.commit(transaction);
					}catch (Exception e){
						//回滚事务
						platformTransactionManager.rollback(transaction);
						e.printStackTrace();
						billRecord.setThirdPayLog(e.getMessage());
						billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.ERROR.getValue());
						billRecordService.updateById(billRecord);
					}
				}else{
					billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.FAIL.getValue());
					billRecord.setPayWay(payWay);
					billRecord.setThirdPayLog(decryptData.toJSONString());
					billRecord.setFailReason(decryptData.getString("failReason"));
					billRecordService.updateById(billRecord);
				}
			}
		}

	}

	/**
	 * 网关充值回调业务逻辑处理（旧版）
	 *
	 * @param gatewayEvent 回调事件
	 */
//	@EventListener
//	@Async
//	@Transactional
	/*public void notifyBusiness_old(GatewayEvent gatewayEvent) {
		JSONObject decryptData = gatewayEvent.getDecryptData(); //获取回调信息，解密后的数据

		//通过orderId获取订单详细
		BillRecord billRecord = billRecordService.getBaseMapper().selectOne(new QueryWrapper<>(new BillRecord()).lambda().eq(BillRecord::getOrderId, decryptData.get("orderId")));
		if (billRecord != null && billRecord.getPayStatus() != SystemConstant.BillRecordPayStatus.PAYED.getValue()) {
			if (billRecord.getType() == SystemConstant.BillRecordType.ADS.getValue()) {//采购商充值
				Object status = decryptData.get("status");
				String payWay = decryptData.getString("payWay");
				if (Objects.equals(status, "SUCCESS")) {
					Bussiness bussiness = bussinessService.getById(billRecord.getUserId());
					if (bussiness != null) {
						//旧的方式是自己做账，新的方式，直接查询商户余额
						String remain = MoneyDesUtil.decrypt(bussiness.getRemain(), MoneyDesUtil.KEY_FOR_UC);
						BigDecimal rare = new BigDecimal(remain);
						rare =rare.add(billRecord.getPrice());
						//减去平台固定服务费
						rare = rare.subtract(billRecord.getBussinessFee());
						//减去扫码支付服务费
						if(StringUtil.isNotBlank(payWay) && payWay.equals("USER_SCAN")){
							BigDecimal userScanBussinessFee = billRecord.getPrice().multiply(new BigDecimal("0.0022"));
							rare = rare.subtract(userScanBussinessFee);
						}
						bussiness.setRemain(MoneyDesUtil.encrypt(rare.toString(),MoneyDesUtil.KEY_FOR_UC));
						bussinessService.updateRemain(bussiness);
					}
					billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
					billRecord.setPayWay(payWay);
					billRecord.setThirdPayLog(decryptData.toJSONString());
					billRecord.setFailReason(decryptData.get("failReason") != null ? decryptData.get("failReason").toString() : null);
					billRecord.setThirdOrderNo(decryptData.getString("uniqueOrderNo"));
					billRecordService.updateById(billRecord);
				}else{
					billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.CANCEL.getValue());
					billRecord.setPayWay(payWay);
					billRecord.setThirdPayLog(decryptData.toJSONString());
					billRecord.setThirdOrderNo(decryptData.getString("uniqueOrderNo"));
					billRecord.setFailReason(decryptData.get("failReason") != null ? decryptData.get("failReason").toString() : null);
					billRecordService.updateById(billRecord);
				}
			}
		}

	}*/


}
