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.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.modules.guosen.bussinessInfo.entity.BussinessInfo;
import org.springblade.modules.guosen.bussinessInfo.service.IBussinessInfoService;
import org.springblade.yeePay.event.RechargeOrderEvent;
import org.springblade.yeePay.event.RechargeServiceFeeTransferNotifyEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
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 java.math.BigDecimal;
import java.util.Objects;


@Component
public class RechargeOrderNotifyListener {

	@Autowired
	private IBillRecordService billRecordService;
	@Autowired
	private IBussinessService bussinessService;
	@Autowired
	private PlatformTransactionManager platformTransactionManager;
	@Autowired
	private TransactionDefinition transactionDefinition;
	@Autowired
	private ApplicationEventPublisher eventPublisher;
	@Autowired
	private IBussinessInfoService bussinessInfoService;

	/**
	 * 网银充值回调业务逻辑处理（新版）
	 *
	 * @param rechargeOrderEvent 回调事件
	 */
	@EventListener
	@Async
	public void notify(RechargeOrderEvent rechargeOrderEvent) {
		JSONObject decryptData = rechargeOrderEvent.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()) {
			return;
		}else{
			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.updateById(bussiness);
						}
						billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
						billRecord.setPayWay(payWay);
						billRecord.setThirdPayLog(decryptData.toJSONString());
						billRecordService.updateById(billRecord);
						//提交事务
						platformTransactionManager.commit(transaction);
						//发送异步事件，发起转账，扣除充值的服务费。
						BussinessInfo info = bussinessInfoService.getByBussinessId(bussiness.getId());
						if(info.getBusinessRole().equals("SETTLED_MERCHANT")){
							RechargeServiceFeeTransferNotifyEvent rsftEvent = new RechargeServiceFeeTransferNotifyEvent(billRecord);
							eventPublisher.publishEvent(rsftEvent);
						}
					}catch (Exception e){
						//回滚事务
						platformTransactionManager.rollback(transaction);
						e.printStackTrace();
						billRecord.setThirdPayLog(e.getMessage());
						billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.ERROR.getValue());
						billRecordService.updateById(billRecord);
					}
				}else if(Objects.equals(status, "FAIL")){
					billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.FAIL.getValue());
					billRecord.setPayWay(payWay);
					billRecord.setThirdPayLog(decryptData.toJSONString());
					billRecord.setFailReason(decryptData.getString("failReason"));
					billRecordService.updateById(billRecord);
				}else if(Objects.equals(status, "ACCOUNTING_EXCEPTION")){
					billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.ACCOUNTING_EXCEPTION.getValue());
					billRecord.setPayWay(payWay);
					billRecord.setThirdPayLog(decryptData.toJSONString());
					billRecord.setFailReason(decryptData.getString("failReason"));
					billRecordService.updateById(billRecord);
				}
			}
		}
	}
}
