package org.springblade.payment.callback.trade;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.enums.AppConstant;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.ldt.bills.entity.BalanceBills;
import org.springblade.ldt.bills.entity.Bills;
import org.springblade.ldt.bills.service.IBalanceBillsService;
import org.springblade.ldt.bills.service.IBillsService;
import org.springblade.ldt.shop.entity.Shop;
import org.springblade.ldt.shop.service.IShopService;
import org.springblade.ldt.user.entity.LoginUser;
import org.springblade.ldt.user.entity.Member;
import org.springblade.ldt.user.service.ILoginUserService;
import org.springblade.ldt.user.service.IMemberService;
import org.springblade.payment.entity.SuccessParams;
import org.springblade.payment.event.ShopSendPointEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

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

/**
 * @author: lianghanqiang
 * @description: 商户赠送积分
 * @since: 9/28/21 -- 2:27 PM
 */
@Component
@AllArgsConstructor
@Slf4j
public class ShopSendCallback {
	private IShopService shopService;
	private IMemberService memberService;
	private IBalanceBillsService balanceBillsService;
	private IBillsService billsService;
	private ILoginUserService loginUserService;

	@EventListener
	public void handle(ShopSendPointEvent shopSendPointEvent){
		SuccessParams successParams = shopSendPointEvent.getSuccessParams();
		String requestNo = successParams.getRes().getString("requestNo");
		BalanceBills balanceBills = balanceBillsService.getOne(new QueryWrapper<BalanceBills>().lambda().eq(BalanceBills::getRequestNo, requestNo));
		Shop shop = shopService.getById(balanceBills.getPayId());
		LoginUser user = loginUserService.getById(balanceBills.getReceiveId());
		Bills bills = billsService.getById(balanceBills.getTradeNo());

		//回调已处理，忽略后续回调
		if (!Objects.equals(bills.getPayStatus(), AppConstant.BillPayStatus.待付款.name())){
			return;
		}

		//会员数据更新
		Member member = handleShopMember(balanceBills, bills.getPrice());
		//更新商场数据
		shop.setBalance(shop.getBalance().subtract(balanceBills.getPrice()));
		shop.setTotalBalance(shop.getBalance());
		//更新用户数据
		user.setBalance(user.getBalance().add(balanceBills.getPrice()));
		//更新赠送积分账单
		balanceBills.setPayStatus(AppConstant.BillPayStatus.付款成功.name());

		//同步数据
		try {
			updateData(user,member,shop,balanceBills);
		}catch (ServiceException e){
			balanceBills.setBillDesc(e.getMessage());
			balanceBillsService.saveOrUpdate(balanceBills);
		}

	}

	/**
	 * 	数据同步
	 * */
	@Transactional
	void updateData(LoginUser user, Member member, Shop shop, BalanceBills balanceBills) throws ServiceException {
		Assert.isTrue(loginUserService.saveOrUpdate(user),()->{throw new ServiceException("更新用户信息异常！");});
		Assert.isTrue(memberService.saveOrUpdate(member),()->{throw new ServiceException("更新会员信息异常！");});
		Assert.isTrue(shopService.saveOrUpdate(shop),()->{throw new ServiceException("更新商场信息异常！");});
		Assert.isTrue(balanceBillsService.saveOrUpdate(balanceBills),()->{throw new ServiceException("更新赠送积分账单信息异常！");});
	}

	/**
	 * 	商户会员管理
	 *
	 * @param sendBill
	 * @param payNum
	 * */
	private Member handleShopMember(BalanceBills sendBill, BigDecimal payNum){
		Long receiveId = sendBill.getReceiveId();
		Member member = memberService.getOne(new QueryWrapper<Member>()
			.lambda()
			.eq(Member::getType, AppConstant.PLATFORM.SHOP.name())
			.eq(Member::getUserId, receiveId)
			.eq(Member::getShopId, sendBill.getPayId()));

		if(Objects.isNull(member)){
			LoginUser loginUser = loginUserService.getById(receiveId);
			Shop shop = shopService.getById(sendBill.getPayId());
			member = new Member();
			member.setMallId(shop.getMallId());
			member.setShopId(shop.getId());
			member.setUserId(receiveId);
			member.setPhone(loginUser.getPhone());
			member.setAvatar(loginUser.getAvatar());
			member.setNickName(loginUser.getNickName());
			member.setType(AppConstant.PLATFORM.SHOP.name());
			member.setPointValue(BigDecimal.ZERO);
			member.setPointTotal(BigDecimal.ZERO);
			member.setPayTotal(BigDecimal.ZERO);
			member.setTenantId(shop.getTenantId());
		}

		BigDecimal pointNum = payNum.multiply(sendBill.getSendNum());

		member.setPayTotal(member.getPayTotal().add(payNum));
		member.setPointTotal(member.getPointTotal().add(pointNum));
		member.setPointValue(member.getPointValue().add(sendBill.getPrice()));

		return member;

	}



}

