package org.springblade.yeePay.listener;

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSONObject;
import org.springblade.common.constant.SystemConstant;
import org.springblade.common.utils.MoneyDesUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.modules.guosen.bussiness.entity.Bussiness;
import org.springblade.modules.guosen.bussiness.entity.BussinessDebit;
import org.springblade.modules.guosen.bussiness.service.IBussinessDebitService;
import org.springblade.modules.guosen.bussiness.service.IBussinessService;
import org.springblade.modules.guosen.withdrawRecords.entity.WithdrawRecords;
import org.springblade.yeePay.event.BatchTransferEvent;
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.sql.PreparedStatement;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


@Component
public class BatchTransferNotifyListener {

	@Autowired
	private IBussinessDebitService bussinessDebitService;
	@Autowired
	private IBussinessService bussinessService;

	@Autowired
	private PlatformTransactionManager platformTransactionManager;
	@Autowired
	private TransactionDefinition transactionDefinition;


	/**
	 * 转账回调业务逻辑处理  ---采购商批量付款专用
	 *
	 * @param event 回调事件
	 */
	@EventListener
	@Async
	public void notifyBusiness(BatchTransferEvent event) {
		JSONObject decryptData = event.getDecryptData(); //获取回调信息，解密后的数据

		//易宝订单状态 “SUCCESS"为成功
		String status = decryptData.getString("status");

		//通过订单号获取采购商分润明细记录
		String requestNo = decryptData.getString("requestNo");
		BussinessDebit bussinessDebit = bussinessDebitService.getById(Long.valueOf(requestNo));
		if (bussinessDebit != null) {
			if (bussinessDebit.getStatus() == SystemConstant.BussinessDebitStatus.SUCCESS.getValue()) {//2为已成功过，无需再重复处理
				return;
			} else {
				if ("SUCCESS".equals(status)) {
					//修改分佣流水表的状态为成功
					bussinessDebit.setStatus(SystemConstant.BussinessDebitStatus.SUCCESS.getValue());
					//从流水表中获取商户账户id
					String bussinessId = bussinessDebit.getBussinessId().toString();
					synchronized (bussinessId.intern()) {//为每个商户加锁，减小锁的粒度
						boolean flag = true;
						while (flag) {//如果修改账户余额时发现版本不对要重试
							//开启事务
							TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
							//处理逻辑
							try {

								//获取商户余额信息
								Bussiness bussiness = bussinessService.getById(bussinessDebit.getBussinessId());
								if (bussiness != null) {
									String remain = MoneyDesUtil.decrypt(bussiness.getRemain(), MoneyDesUtil.KEY_FOR_UC);
									BigDecimal rare = new BigDecimal(remain);
									rare = rare.subtract(bussinessDebit.getFee()).subtract(bussinessDebit.getPrice());
									bussiness.setRemain(MoneyDesUtil.encrypt(rare.toString(), MoneyDesUtil.KEY_FOR_UC));
									//修改商户余额信息
									boolean result = bussinessService.updateRemain(bussiness);
									if(result){

										//修改分佣流水表的分佣状态为成功
										bussinessDebitService.updateById(bussinessDebit);

										//提交事务
										platformTransactionManager.commit(transaction);
										flag = false;//修改成功跳出循環
									}

								}


							} catch (Exception e) {
								flag = false;
								//回滚事务
								platformTransactionManager.rollback(transaction);
								e.printStackTrace();
								bussinessDebit.setStatus(SystemConstant.BussinessDebitStatus.FAIL.getValue());
								bussinessDebit.setThirdPayLog(e.getMessage());
								bussinessDebitService.updateById(bussinessDebit);
							}
						}

					}

				} else {//第三方支付回调结果为失败，记录分佣流水失败的原因
					bussinessDebit.setStatus(SystemConstant.BussinessDebitStatus.FAIL.getValue());
					bussinessDebit.setThirdPayLog(decryptData.toJSONString());
					bussinessDebit.setFailReason(decryptData.getString("failReason"));
					bussinessDebitService.updateById(bussinessDebit);
				}

			}
		}


	}




}
