package org.springblade.modules.payment.listener;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.checkerframework.checker.units.qual.A;
import org.springblade.common.constant.SystemConstant;
import org.springblade.core.log.logger.BladeLogger;
import org.springblade.modules.ldt.billrecord.entity.BillRecord;
import org.springblade.modules.ldt.billrecord.service.IBillRecordService;
import org.springblade.modules.ldt.channel.entity.PointChannel;
import org.springblade.modules.ldt.channel.service.IPointChannelService;
import org.springblade.modules.ldt.channeluserpoint.entity.ChannelUserPoint;
import org.springblade.modules.ldt.channeluserpoint.service.IChannelUserPointService;
import org.springblade.modules.ldt.loginuser.entity.LoginUser;
import org.springblade.modules.ldt.loginuser.service.ILoginUserService;
import org.springblade.modules.ldt.mall.entity.Mall;
import org.springblade.modules.ldt.mall.service.IMallService;
import org.springblade.modules.ldt.member.entity.Member;
import org.springblade.modules.ldt.member.service.IMemberService;
import org.springblade.modules.ldt.pointdetail.entity.PointDetail;
import org.springblade.modules.ldt.pointdetail.service.IPointDetailService;
import org.springblade.modules.ldt.shop.entity.Shop;
import org.springblade.modules.ldt.shop.service.IShopService;
import org.springblade.modules.ldt.shopyingshou.entity.ShopYingshou;
import org.springblade.modules.ldt.shopyingshou.service.IShopYingshouService;
import org.springblade.modules.payment.entity.SuccessParams;
import org.springblade.modules.payment.event.UserPayEvent;
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.util.List;

/**
 * @author: lianghanqiang
 * @description: 用户付款回调
 * @since: 8/5/21 -- 3:01 PM
 */
@Component
public class UserPayListener {

	@Autowired
	private IBillRecordService billRecordService;
	@Autowired
	private IPointDetailService pointDetailService;
	@Autowired
	private IChannelUserPointService channelUserPointService;
	@Autowired
	private BladeLogger bladeLogger;
	@Autowired
	private IPointChannelService pointChannelService;
	@Autowired
	private IMallService mallService;
	@Autowired
	private IShopService shopService;
	@Autowired
	private IMemberService memberService;
	@Autowired
	private IShopYingshouService shopYingshouService;
	@Autowired
	private ILoginUserService loginUserService;



	@EventListener
	@Async
	@Transactional
	public void PaySuccess(UserPayEvent userPayEvent){
		SuccessParams successParams = userPayEvent.getSuccessParams();

		System.out.println("用户支付成功的回调数据："+successParams);
		//用户支付成功的回调数据：SuccessParams(billId=1425261064655839233, platformId=1013202108110000002503142099, orderId=null, status=success, orderType=USER_PAY)
		BillRecord billRecord = billRecordService.getById(successParams.getBillId());
		if(billRecord ==null ){
			bladeLogger.error("第三方支付返回的订单不存在",successParams.toString());
		}else{
			String shopId = billRecord.getShopId().toString();
			synchronized (shopId.intern()){//对商户加锁

				try{
					Shop shop = shopService.getById(billRecord.getShopId());

					if(SystemConstant.BillRecordPayStatus.PAYING.getValue() == billRecord.getPayStatus() && "success".equals(successParams.getStatus())){//只处理待支付订单变成已支付成功的情况

						if(billRecord.getUserId() == null){//非平台用户支付直接增加用户可提现余额，无需赠送积分
							billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
							billRecord.setSubsidy(BigDecimal.valueOf(1));
							billRecord.setPayWay(successParams.getPayChannel().equals("WECHAT")?"微信用户":"支付宝用户");
							billRecordService.updateById(billRecord);
							shop.setWithdrawTotalPrice(shop.getWithdrawTotalPrice() != null ?
								shop.getWithdrawTotalPrice().add(billRecord.getRealPayAmount()) : billRecord.getRealPayAmount());
							shopService.updateById(shop);
							return;
						}

						/**                  平台用户支付回调                 **/
						//增加商户的可提现余额
						LoginUser loginUser = loginUserService.getById(billRecord.getUserId());
						shop.setWithdrawTotalPrice(shop.getWithdrawTotalPrice().add(billRecord.getRealPayAmount()));
						shop.setSales(shop.getSales() != null?shop.getSales()+1:1);
						shop.setTradeTimes(shop.getTradeTimes() != null ? shop.getTradeTimes() +1 : 1);
						shopService.updateById(shop);
						//支付成功增加商场和商家的积分成本，增加用户的可用积分余额

						//查询是否有商场送积分的待确认记录
						List<PointDetail> mallPointDetails = pointDetailService.getBaseMapper().selectList(new QueryWrapper<>(new PointDetail()).lambda()
							.eq(PointDetail::getBillRecordId,billRecord.getId())
							.eq(PointDetail::getType,SystemConstant.PointDetailType.MALL_SEND.getValue()).orderByDesc(PointDetail::getCreateTime));
						Member shopMember  = memberService.getBaseMapper().selectOne(new QueryWrapper<>(new Member()).lambda()
							.eq(Member::getUserId,billRecord.getUserId())
							.eq(Member::getType,SystemConstant.MALLORSHOP.SHOP.getValue())
							.eq(Member::getShopId,billRecord.getShopId()));
						Member mallMember =  memberService.getBaseMapper().selectOne(new QueryWrapper<>(new Member()).lambda()
							.eq(Member::getType,SystemConstant.MALLORSHOP.MALL.getValue())
							.eq(Member::getUserId,billRecord.getUserId())
							.eq(Member::getMallId,billRecord.getMallId()));
						ChannelUserPoint channelUserPoint = null;
						if (mallPointDetails.size() > 0) {
							PointDetail mallPointDetail = mallPointDetails.get(0);
							/**
							 * 增加商场的积分成本
							 */
							mallPointDetail.setBillRecordStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
							pointDetailService.updateById(mallPointDetail);
							//获取商场的积分渠道
							PointChannel pointChannel = pointChannelService.getBaseMapper().selectOne(new QueryWrapper<>(new PointChannel()).lambda()
								.eq(PointChannel::getType,SystemConstant.PointChannelType.MALL.getValue())
								.eq(PointChannel::getRelationId,billRecord.getMallId()));
							//获取该用户在商场渠道的积分信息
							 channelUserPoint = channelUserPointService.getBaseMapper().selectOne(new QueryWrapper<>(new ChannelUserPoint()).lambda()
								.eq(ChannelUserPoint::getUserId, billRecord.getUserId())
								.eq(ChannelUserPoint::getChannelId, pointChannel.getId()));
							//增加该用户在该商场的积分信息
							channelUserPoint.setUsablePoint(channelUserPoint.getUsablePoint().add(mallPointDetail.getPoint()));
							channelUserPoint.setTotalPoint(channelUserPoint.getTotalPoint().add(mallPointDetail.getPoint()));
							channelUserPoint.setUsablePointValue(channelUserPoint.getUsablePoint().multiply(pointChannel.getPointValue()).divide(BigDecimal.valueOf(100)));
							channelUserPointService.updateById(channelUserPoint);
							//增加该商场的积分总价值
							Mall mall = mallService.getById(billRecord.getMallId());
							mall.setTotalPointValue(mall.getTotalPointValue() != null?mall.getTotalPointValue().add(mallPointDetail.getPointValue()):mallPointDetail.getPointValue());
							mallService.updateById(mall);
							//修改用户信息的渠道总积分价值

							loginUser.setChannelPointValue(loginUser.getChannelPointValue() != null ? loginUser.getChannelPointValue().add(mallPointDetail.getPointValue()):mallPointDetail.getPointValue());
							loginUserService.updateById(loginUser);
							//增加会员的可用积分

							mallMember.setPointTotal(mallMember.getPointTotal() != null?mallMember.getPointTotal().add(mallPointDetail.getPoint()) :mallPointDetail.getPoint());
							mallMember.setPointValue(mallMember.getPointValue() != null?mallMember.getPointValue().add(mallPointDetail.getPointValue()):mallPointDetail.getPointValue());
							mallMember.setPayTotal(mallMember.getPayTotal()!= null ? mallMember.getPayTotal().add(billRecord.getPrice()):billRecord.getPrice());
							memberService.updateById(mallMember);
						}

						/**
						 * 商场送积分的待确认记录
						 */
						List<PointDetail> shopPointDetails = pointDetailService.getBaseMapper().selectList(new QueryWrapper<>(new PointDetail()).lambda()
							.eq(PointDetail::getBillRecordId,billRecord.getId())
							.eq(PointDetail::getType,SystemConstant.PointDetailType.SHOP_SEND.getValue()).orderByDesc(PointDetail::getCreateTime));
						if(shopPointDetails.size()>0){
							PointDetail shopPointDetail = shopPointDetails.get(0);

							//增加商家的积分成本
							shop.setTotalPointValue(shop.getTotalPointValue() != null ? shop.getTotalPointValue().add(shopPointDetail.getPointValue()):shopPointDetail.getPointValue());
							shopService.updateById(shop);
							shopPointDetail.setBillRecordStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
							pointDetailService.updateById(shopPointDetail);
							//修改该用户的
							//增加该商店会员的可用积分

							shopMember.setPointValue(shopMember.getPointValue() != null ? shopMember.getPointValue().add(shopPointDetail.getPointValue()): shopPointDetail.getPointValue());
							shopMember.setPointTotal(shopMember.getPointTotal() != null ? shopMember.getPointTotal().add(shopPointDetail.getPoint()): shopPointDetail.getPoint());
							shopMember.setPayTotal(shopMember.getPayTotal() != null ? shopMember.getPayTotal().add(billRecord.getPrice()):billRecord.getPrice());
							memberService.updateById(shopMember);
							loginUser.setPointValue(loginUser.getPointValue() != null ? loginUser.getPointValue().add(shopPointDetail.getPointValue()):shopPointDetail.getPointValue());
							loginUser.setPoint(loginUser.getPoint() != null ? loginUser.getPoint().add(shopPointDetail.getPoint()):shopPointDetail.getPoint());
							loginUserService.updateById(loginUser);

						}




						//判断用户是否使用了大B的积分支付
						PointDetail channelPointDetail = pointDetailService.getBaseMapper().selectOne(new QueryWrapper<>(new PointDetail()).lambda()
							.eq(PointDetail::getBillRecordId,billRecord.getId()).eq(PointDetail::getType,SystemConstant.PointDetailType.USER_PAY)
							.eq(PointDetail::getMemberId,mallMember.getId()).eq(PointDetail::getBillRecordStatus,SystemConstant.BillRecordPayStatus.PAYING.getValue()));
						if(channelPointDetail != null){
							channelPointDetail.setBillRecordStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
							pointDetailService.updateById(channelPointDetail);
							if(channelUserPoint != null){
								channelUserPoint.setUsablePointValue(channelUserPoint.getUsablePoint().subtract(channelPointDetail.getPoint()));
								channelUserPointService.updateById(channelUserPoint);
								//减少用户信息的渠道积分
								loginUser.setChannelPointValue(loginUser.getChannelPointValue().subtract(channelPointDetail.getPointValue()));
								loginUserService.updateById(loginUser);
								/**   判断是否有商家待应收记录   **/
								ShopYingshou shopYingshou = shopYingshouService.getBaseMapper().selectOne(new QueryWrapper<>(new ShopYingshou()).lambda()
									.eq(ShopYingshou::getBillRecordStatus, SystemConstant.BillRecordPayStatus.PAYING.getValue())
									.eq(ShopYingshou::getBillRecordId, billRecord.getId()));
								if(shopYingshou != null){
									//增加商户的总应收
									shopYingshou.setBillRecordStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
									shop.setTotalFunkPrice(shop.getTotalFunkPrice() != null? shop.getTotalFunkPrice().add(shopYingshou.getPointValue()):shopYingshou.getPointValue());
									shopService.updateById(shop);
								}
							}
						}





						//判断用户是否使用了小B的积分支付
						PointDetail shopPointDetail = pointDetailService.getBaseMapper().selectOne(new QueryWrapper<>(new PointDetail()).lambda()
							.eq(PointDetail::getBillRecordId,billRecord.getId()).eq(PointDetail::getType,SystemConstant.PointDetailType.USER_PAY)
							.eq(PointDetail::getMemberId,shopMember.getId()).eq(PointDetail::getBillRecordStatus,SystemConstant.BillRecordPayStatus.PAYING.getValue()));
						if(shopPointDetail != null){
							shopPointDetail.setBillRecordStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
							pointDetailService.updateById(shopPointDetail);
							//减少用户信息的可用余额
							loginUser.setPointValue(loginUser.getPointValue().subtract(shopPointDetail.getPointValue()));
							loginUserService.updateById(loginUser);
						}

						//修改订单状态
						billRecord.setPayStatus(SystemConstant.BillRecordPayStatus.PAYED.getValue());
						billRecordService.updateById(billRecord);

					}
				}catch (Exception e){

					e.printStackTrace();

				}

			}

		}
	}
}
