package org.springblade.payment.handle.handler;

import lombok.AllArgsConstructor;
import org.springblade.common.enums.AppConstant;
import org.springblade.common.enums.FrozenType;
import org.springblade.common.enums.OrderType;
import org.springblade.common.enums.ResCode;
import org.springblade.common.utils.TradeException;
import org.springblade.ldt.bills.entity.BalanceBills;
import org.springblade.ldt.bills.entity.FrozenRec;
import org.springblade.ldt.bills.service.IBalanceBillsService;
import org.springblade.ldt.bills.service.IFrozenRecService;
import org.springblade.ldt.user.entity.LoginUser;
import org.springblade.ldt.user.service.ILoginUserService;
import org.springblade.payment.entity.SuccessParams;
import org.springblade.payment.handle.entity.HandleData;
import org.springblade.payment.handle.entity.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @author: lianghanqiang
 * @description: 用户账户余额处理
 * @since: 8/26/21 -- 6:24 PM
 */
@Component
@AllArgsConstructor
public class BalanceHandle implements BaseHandle {
	private IBalanceBillsService balanceBillsService;
	private DataHandle dataHandle;
	private IFrozenRecService frozenRecService;
	private ILoginUserService loginUserService;

	/**
	 * 用户的余额扣除，余额足够抵消交易金额，剩余支付金额remain为0，交易结束
	 * 不足抵消，remain将会流转到下一个节点处理
	 */

	public static void main(String[] args) {
		BigDecimal myBalance = BigDecimal.valueOf(2);
		BigDecimal pointRate = BigDecimal.valueOf(0.01);
		BigDecimal consumeMax = myBalance.divide(pointRate.add(BigDecimal.ONE), 2, RoundingMode.FLOOR);
		System.out.println(consumeMax);
	}

	@Override
	public HandleData handle(BigDecimal remain, Order order, SuccessParams successParams) throws TradeException {

		LoginUser user = order.getLoginUser();
		BigDecimal myBalance = user.getBalance();

		//用户账户余额为0
		if (myBalance.compareTo(BigDecimal.ZERO) <= 0) {
			successParams.getBills().setBalanceNum(BigDecimal.ZERO);
			return HandleData.builder().isSuccess(Boolean.TRUE).successParams(successParams).remain(remain).build();
		}


		//余额抵消情况
		BigDecimal handlePrice = remain;
		remain = myBalance.subtract(remain);

		if (remain.compareTo(BigDecimal.ZERO) >= 0) {
			remain = BigDecimal.ZERO;
		} else {
			remain = remain.abs();
			handlePrice = myBalance;
		}

		FrozenRec frozenRec = frozenRecService.addFrozenRec(handlePrice, successParams.getBills(), user, FrozenType.BALANCE, null);
		Assert.isTrue(dataHandle.saveOrUpdateEntity(frozenRecService, frozenRec), () -> {
			throw new TradeException(ResCode.TRADE_ERROR, successParams);
		});
		BalanceBills balanceBills = buildBills(order, user, handlePrice, successParams, BigDecimal.ZERO);
		Assert.isTrue(dataHandle.saveOrUpdateEntity(balanceBillsService, balanceBills), () -> {
			throw new TradeException(ResCode.TRADE_ERROR, successParams);
		});
		Assert.isTrue(dataHandle.saveOrUpdateEntity(loginUserService, user), () -> {
			throw new TradeException(ResCode.TRADE_ERROR, successParams);
		});

		successParams.setBalanceBillsId(balanceBills.getId());
		successParams.getBills().setBalanceNum(handlePrice);
		return HandleData.builder().isSuccess(Boolean.TRUE).successParams(successParams).remain(remain).build();
	}


	/**
	 * 商户积分--构建账单
	 */
	private BalanceBills buildBills(Order order, LoginUser user, BigDecimal price, SuccessParams successParams, BigDecimal pointFee) {
		BalanceBills balanceBills = new BalanceBills();
		balanceBills.setReceiveId(order.getShopId());
		balanceBills.setType(OrderType.PAY_CONSUMER.name());
		balanceBills.setPayStatus(AppConstant.BillPayStatus.待付款.name());
		balanceBills.setTitle(order.getBillsTitle());
		balanceBills.setTradeNo(successParams.getBills().getId());
		balanceBills.setPayId(user.getId());
		balanceBills.setPrice(price);
		balanceBills.setFee(pointFee);
		balanceBills.setTenantId(successParams.getTenantId());
		balanceBills.setTotalPrice(price.add(pointFee));
		return balanceBills;
	}

}
