package org.springblade.payment.handle.handler;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.common.cache.PlatformCache;
import org.springblade.common.config.entity.PlatformConfig;
import org.springblade.common.config.json.LongTypeFilter;
import org.springblade.common.enums.AppConstant;
import org.springblade.common.enums.OrderType;
import org.springblade.common.enums.PaymentScene;
import org.springblade.common.enums.ResCode;
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.entity.PointBills;
import org.springblade.ldt.bills.service.IBalanceBillsService;
import org.springblade.ldt.bills.service.IBillsService;
import org.springblade.ldt.bills.service.IPointBillsService;
import org.springblade.ldt.channel.entity.PointChannel;
import org.springblade.ldt.channel.service.IPointChannelService;
import org.springblade.ldt.mall.entity.Mall;
import org.springblade.ldt.mall.service.IMallService;
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.service.ILoginUserService;
import org.springblade.payment.entity.SuccessParams;
import org.springblade.payment.handle.entity.HandleData;
import org.springblade.payment.handle.entity.Order;
import org.springblade.webSocket.WebSocketServer;
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 -- 6:54 PM
 */
@Component
@AllArgsConstructor
public class WxPayHandle implements BaseHandle {

	private WebSocketServer webSocketServer;
	private DataHandle dataHandle;
	private IBillsService billsService;
	private IShopService shopService;
	private IMallService mallService;
	private ILoginUserService loginUserService;
	private IBalanceBillsService balanceBillsService;
	private IPointBillsService pointBillsService;
	private IPointChannelService pointChannelService;

	/**
	 * 未抵消的余额，发送订单信息到用户，用户根据订单信息调起微信支付
	 */
	@Override
	public HandleData handle(BigDecimal remain, Order order, SuccessParams successParams) throws ServiceException {
		Bills bills = successParams.getBills();
		bills.setPayScene(PaymentScene.MINI_PROGRAM.name());
		bills.setPrice(remain);
		dataHandle.saveOrUpdateEntity(billsService, bills);
		LoginUser user = loginUserService.getById(successParams.getUserId());

		//赠送积分
		sendPoint(bills, user);
		//通知用户调起支付
		webSocketServer.sendInfo(AppConstant.SOCKET_PRE.USER.getName() + order.getLoginUser().getId().toString(), JSON.toJSONString(bills, new LongTypeFilter()));
		return HandleData.builder().isSuccess(Boolean.TRUE).successParams(successParams).remain(remain).build();
	}

	/**
	 * 商场、商家赠送用户积分
	 **/
	private boolean sendPoint(Bills bills, LoginUser user) {
		PlatformConfig platformConfig = PlatformCache.platFormConfig();
		BigDecimal pointFee = BigDecimal.valueOf(platformConfig.getPointFee());
		if (!Objects.isNull(bills)) {
			//赠送用户积分
			BigDecimal payNum = bills.getPrice();
			Shop shop = shopService.getById(bills.getReceiveId());
			Mall mall = mallService.getById(shop.getMallId());
			mallSendPoint(mall, user, payNum, bills, pointFee);
			shopSendPoint(shop, user, payNum, bills, pointFee);
		}
		return true;
	}

	/**
	 * 商家赠送积分
	 */
	public boolean shopSendPoint(Shop shop, LoginUser user, BigDecimal payNum, Bills bills, BigDecimal pointFee) {
		//商家若是开启了会员中心则赠送积分
		if (!Objects.isNull(shop) && shop.getIsOpenMember() != 0 && payNum.compareTo(BigDecimal.ZERO) > 0) {
			BalanceBills sendBill = new BalanceBills();
			sendBill.setType(OrderType.SHOP_SEND.name());
			sendBill.setPayStatus(AppConstant.BillPayStatus.待付款.name());
			sendBill.setTitle("商家赠送积分");
			sendBill.setReceiveId(user.getId());
			sendBill.setPayId(shop.getId());
			sendBill.setTradeNo(bills.getId());
			if (!Objects.isNull(shop)) {
				BigDecimal sendNum = payNum.multiply(shop.getSendPointUnit());
				BigDecimal sendPrice = sendNum.multiply(shop.getPointRate()).setScale(2, BigDecimal.ROUND_FLOOR);
				BigDecimal fee = sendPrice.multiply(pointFee);
				sendBill.setPrice(sendPrice);
				sendBill.setSendNum(sendNum);
				sendBill.setFee(fee);
				sendBill.setTotalPrice(fee.add(sendPrice));
				if (sendPrice.compareTo(BigDecimal.valueOf(0.01)) < 0) {
					sendBill.setBillDesc("账户余额不足或赠送积分值小于0.01");
				} else {
					String requestNo = IdUtil.simpleUUID();
					sendBill.setRequestNo(requestNo);
				}

			} else {
				sendBill.setBillDesc("商家不存在");
			}
			Assert.isTrue(dataHandle.saveOrUpdateEntity(balanceBillsService, sendBill), () -> {
				throw new ServiceException(ResCode.USER_PAY_CALLBACK_ERROR);
			});
		}
		return true;
	}


	/**
	 * 商场赠送积分
	 */
	public boolean mallSendPoint(Mall mall, LoginUser user, BigDecimal payNum, Bills bills, BigDecimal pointFee) {
		//商场若是开启了会员中心则赠送积分
		if (!Objects.isNull(mall) && mall.getUseMember() != 0 && payNum.compareTo(BigDecimal.ZERO) > 0) {
			PointBills sendBill = new PointBills();
			sendBill.setType(OrderType.MALL_SEND.name());
			sendBill.setPayStatus(AppConstant.BillPayStatus.待付款.name());
			sendBill.setTitle("商场赠送积分");
			sendBill.setReceiveId(user.getId());
			sendBill.setPayId(mall.getId());
			sendBill.setTradeNo(bills.getId());
			if (!Objects.isNull(mall)) {
				BigDecimal sendNum = payNum.multiply(mall.getSendPointUnnit());
				BigDecimal sendPrice = sendNum.multiply(mall.getPointRate()).setScale(2, BigDecimal.ROUND_FLOOR);
				BigDecimal fee = sendPrice.multiply(pointFee);
				sendBill.setSendNum(sendNum);
				sendBill.setPrice(sendPrice);
				sendBill.setFee(fee);
				sendBill.setTotalPrice(fee.add(sendPrice));
				if (sendPrice.compareTo(BigDecimal.valueOf(0.01)) < 0) {
					sendBill.setBillsDesc("账户余额不足或赠送积分值小于1");
				} else {
					String requestNo = IdUtil.simpleUUID();
					sendBill.setRequestNo(requestNo);
				}
				PointChannel pointChannel = pointChannelService.getOne(Wrappers.<PointChannel>lambdaQuery().eq(PointChannel::getRelationId, mall.getId()));
				sendBill.setChannelId(pointChannel.getId());
				sendBill.setChannelLogo(pointChannel.getLogo());
				sendBill.setChannelName(pointChannel.getName());
				sendBill.setChannelPointRate(pointChannel.getPointRate());
			} else {
				sendBill.setBillsDesc("商场不存在");
			}
			Assert.isTrue(dataHandle.saveOrUpdateEntity(pointBillsService, sendBill), () -> {
				throw new ServiceException(ResCode.USER_PAY_CALLBACK_ERROR);
			});
		}
		return true;
	}

}

