package org.springblade.payment.handle.handler;

import lombok.AllArgsConstructor;
import org.springblade.common.cache.PlatformCache;
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.FrozenRec;
import org.springblade.ldt.bills.entity.PointBills;
import org.springblade.ldt.bills.service.IFrozenRecService;
import org.springblade.ldt.bills.service.IPointBillsService;
import org.springblade.ldt.user.entity.LoginUser;
import org.springblade.ldt.user.entity.UserChannelPoint;
import org.springblade.ldt.user.service.ILoginUserService;
import org.springblade.ldt.user.service.IUserChannelPointService;
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.util.Objects;


/**
 * @author: lianghanqiang
 * @description: 积分交易处理
 * @since: 8/26/21 -- 1:51 PM
 */
@Component
@AllArgsConstructor
public class ChannelPointHandle implements BaseHandle {

	private IPointBillsService pointBillsService;
	private IUserChannelPointService userChannelPointService;
	private DataHandle dataHandle;
	private IFrozenRecService frozenRecService;
	private ILoginUserService loginUserService;


	/**
	 * 抵消用户的渠道积分，积分足够抵消交易金额，剩余支付金额remain为0，交易结束
	 * 不足抵消，remain将会流转到下一个节点处理
	 */
	@Override
	public HandleData handle(BigDecimal remain, Order order, SuccessParams successParams) throws TradeException {

		BigDecimal pointRate = BigDecimal.valueOf(PlatformCache.platFormConfig().getPointFee());

		LoginUser user = order.getLoginUser();
		UserChannelPoint channelPoint = userChannelPointService.getById(successParams.getChannelId());


		//用户渠道积分为0或者用户渠道积分查找失败
		if (Objects.isNull(channelPoint) ||
			channelPoint.getAvailable().compareTo(BigDecimal.ZERO) <= 0
			|| !channelPoint.getUserId().equals(successParams.getUserId())) {
			successParams.getBills().setPointNum(BigDecimal.ZERO);
			return HandleData.builder().isSuccess(Boolean.TRUE).successParams(successParams).remain(remain).build();
		}

		//积分抵消情况
		BigDecimal handlePrice = remain;
		remain = channelPoint.getAvailable().subtract(remain);

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

		}
		PointBills pointBills = buildBillRecord(order, user, handlePrice, channelPoint, successParams, BigDecimal.ZERO);
		Assert.isTrue(dataHandle.saveOrUpdateEntity(pointBillsService, pointBills), () -> {
			throw new TradeException(ResCode.TRADE_ERROR, successParams);
		});

		FrozenRec frozenRec = frozenRecService.addFrozenRec(handlePrice, successParams.getBills(), user, FrozenType.POINT, channelPoint);
		Assert.isTrue(dataHandle.saveOrUpdateEntity(frozenRecService, frozenRec), () -> {
			throw new TradeException(ResCode.TRADE_ERROR, successParams);
		});
		Assert.isTrue(dataHandle.saveOrUpdateEntity(loginUserService, user), () -> {
			throw new TradeException(ResCode.TRADE_ERROR, successParams);
		});
		Assert.isTrue(dataHandle.saveOrUpdateEntity(userChannelPointService, channelPoint), () -> {
			throw new TradeException(ResCode.TRADE_ERROR, successParams);
		});
		successParams.setPointBillsId(pointBills.getId());
		successParams.getBills().setPointNum(handlePrice);

		return HandleData.builder().isSuccess(Boolean.TRUE).successParams(successParams).remain(remain).build();
	}


	/**
	 * 构建渠道积分账单
	 *
	 * @return
	 */
	private PointBills buildBillRecord(Order order, LoginUser user, BigDecimal price,
									   UserChannelPoint userChannelPoint,
									   SuccessParams successParams, BigDecimal pointFee) {

		PointBills pointBills = new PointBills();
		pointBills.setType(OrderType.PAY_CONSUMER.name());
		pointBills.setPayId(user.getId());
		pointBills.setReceiveId(order.getShopId());
		pointBills.setPayStatus(AppConstant.BillPayStatus.付款成功.name());
		pointBills.setTitle("商家扫码收款");
		pointBills.setPrice(price);
		pointBills.setTotalPrice(price.add(pointFee));
		pointBills.setTradeNo(successParams.getBills().getId());
		pointBills.setFee(pointFee);
		pointBills.setChannelPointRate(userChannelPoint.getPointRate());
		pointBills.setChannelId(userChannelPoint.getId());
		pointBills.setChannelName(userChannelPoint.getChannelName());
		pointBills.setChannelLogo(userChannelPoint.getChannelLogo());
		pointBills.setTenantId(successParams.getTenantId());
		return pointBills;
	}

}
