/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.guosen.pointsGoods.service.impl;

import org.springblade.core.mp.support.Condition;
import org.springblade.core.tool.api.R;
import org.springblade.modules.guosen.activity.entity.Activity;
import org.springblade.modules.guosen.activity.service.IActivityService;
import org.springblade.modules.guosen.billRecord.entity.BillRecord;
import org.springblade.modules.guosen.billRecord.service.IBillRecordService;
import org.springblade.modules.guosen.helpRecord.service.IHelpRecordService;
import org.springblade.modules.guosen.hotDetail.entity.HotDetail;
import org.springblade.modules.guosen.hotDetail.service.IHotDetailService;
import org.springblade.modules.guosen.loginUser.entity.LoginUser;
import org.springblade.modules.guosen.loginUser.service.ILoginUserService;
import org.springblade.modules.guosen.pointsDetail.entity.PointsDetail;
import org.springblade.modules.guosen.pointsDetail.service.IPointsDetailService;
import org.springblade.modules.guosen.pointsGoods.dto.ExchangeDTO;
import org.springblade.modules.guosen.pointsGoods.dto.PointsGoodsDTO;
import org.springblade.modules.guosen.pointsGoods.entity.PointsGoods;
import org.springblade.modules.guosen.pointsGoods.vo.PointsGoodsVO;
import org.springblade.modules.guosen.pointsGoods.mapper.PointsGoodsMapper;
import org.springblade.modules.guosen.pointsGoods.service.IPointsGoodsService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.guosen.pointsProportion.entity.PointsProportion;
import org.springblade.modules.guosen.pointsProportion.service.IPointsProportionService;
import org.springblade.modules.guosen.userActivityStatistical.dto.UserUsableHotAndPoints;
import org.springblade.modules.guosen.userActivityStatistical.entity.UserActivityStatistical;
import org.springblade.modules.guosen.userActivityStatistical.service.IUserActivityStatisticalService;
import org.springblade.modules.guosen.userAddress.entity.UserAddress;
import org.springblade.modules.guosen.userAddress.service.IUserAddressService;
import org.springblade.modules.guosen.userPointsGoods.entity.UserPointsGoods;
import org.springblade.modules.guosen.userPointsGoods.service.IUserPointsGoodsService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 *  服务实现类
 *
 * @author BladeX
 * @since 2021-06-28
 */
@Service
public class PointsGoodsServiceImpl extends BaseServiceImpl<PointsGoodsMapper, PointsGoods> implements IPointsGoodsService {

	@Resource
	private IPointsProportionService pointsProportionService;
	@Resource
	private IActivityService activityService;
	@Resource
	private IUserActivityStatisticalService userActivityStatisticalService;
	@Resource
	private IUserPointsGoodsService userPointsGoodsService;
	@Resource
	private IUserAddressService userAddressService;
	@Resource
	private ILoginUserService loginUserService;
	@Resource
	private IPointsDetailService pointsDetailService;
	@Resource
	private IHotDetailService hotDetailService;

	@Override
	public IPage<PointsGoodsVO> selectPointsGoodsPage(IPage<PointsGoodsVO> page, PointsGoodsVO pointsGoods) {
		return page.setRecords(baseMapper.selectPointsGoodsPage(page, pointsGoods));
	}

	@Override
	@Transactional
	public R exchange(ExchangeDTO exchangeDTO) {
		PointsGoods pointsGoods = this.getById(exchangeDTO.getPointsGoodsId());
		//积分值比例
		BigDecimal proportion = pointsProportionService.list().get(0).getPointsProportion();
		//热力值比例
		Long activityId = pointsGoods.getActivityId();
		Activity activity = activityService.getById(activityId);
		BigDecimal bonusProportion = activity.getBonusProportion();

		LoginUser loginUser = loginUserService.getById(exchangeDTO.getUserId());

		//商品需要的价格
		BigDecimal totalCashValue = pointsGoods.getCashValue();

		//兑换的现金值
		BigDecimal cashValue = exchangeDTO.getCashValue() == null ? BigDecimal.ZERO : exchangeDTO.getCashValue();
		//兑换的热力值等于多少现金
		BigDecimal hotValue = exchangeDTO.getHotValue() == null ? BigDecimal.ZERO : exchangeDTO.getHotValue();
		BigDecimal hotCash= hotValue.multiply(bonusProportion);
		//兑换的积分值等于多少现金
		BigDecimal pointsValue = exchangeDTO.getPointsValue() == null ? BigDecimal.ZERO : exchangeDTO.getPointsValue();
		BigDecimal pointsCash = pointsValue.multiply(proportion);
		//总的值
		BigDecimal add = cashValue.add(hotCash).add(pointsCash);

		//如果前端输入数据的总值少于商品需要的总值，就抛出异常
		if (add.compareTo(totalCashValue) != 0) {
			return R.fail("兑换失败,总金额不等于商品所需总金额");
		}

		//获取用户该活动的可用积分和可用热力值
		UserActivityStatistical statistical = userActivityStatisticalService.getOne(Condition.getQueryWrapper(new UserActivityStatistical()).lambda()
			.eq(UserActivityStatistical::getActivityId, activityId)
			.eq(UserActivityStatistical::getUserId, exchangeDTO.getUserId()));

		//获取用户地址
		UserAddress userAddress = userAddressService.getOne(Condition.getQueryWrapper(new UserAddress()).lambda()
			.eq(UserAddress::getUserId, exchangeDTO.getUserId()));

		if (statistical.getUsableHotValue().compareTo(hotValue) == -1) {
			return R.fail("兑换失败,您可用热力不足");
		}
		if (statistical.getUsablePointsValue().compareTo(pointsValue) == -1) {
			return R.fail("兑换失败，您可用积分不足");
		}
		if (userAddress == null) {
			return R.fail("兑换失败，用户未选择地址");
		}
		//开始兑换

		//插入用户积分商品记录
		UserPointsGoods userPointsGoods = new UserPointsGoods();
		userPointsGoods.setActivityId(activityId);
		userPointsGoods.setAddressId(userAddress.getId());
		userPointsGoods.setCashValue(cashValue);
		userPointsGoods.setHotValue(hotValue);
		userPointsGoods.setPrice(totalCashValue);
		userPointsGoods.setPointsValue(pointsValue);
		userPointsGoods.setName(pointsGoods.getName());
		userPointsGoods.setImage(pointsGoods.getImage());
		userPointsGoods.setUserId(exchangeDTO.getUserId());
		userPointsGoods.setPointsGoodsId(pointsGoods.getId());
		userPointsGoods.setPointsGoodsStatus(0);//待收货
		userPointsGoodsService.save(userPointsGoods);

		//消耗用户可用积分和用户的活动统计的可用积分
		if (pointsValue.compareTo(BigDecimal.ZERO) != 0) {
			statistical.setUsablePointsValue(statistical.getUsablePointsValue().subtract(pointsValue));
			loginUser.setUsablePoints(loginUser.getUsablePoints().subtract(pointsValue));

			//插入积分明细
			PointsDetail pointsDetail = new PointsDetail();
			pointsDetail.setNote(pointsGoods.getName() + "兑换");
			pointsDetail.setType(5);
			pointsDetail.setRelationId(pointsGoods.getId());
			pointsDetail.setUserId(exchangeDTO.getUserId());
			pointsDetail.setPointsValue(pointsValue.negate());
			pointsDetailService.save(pointsDetail);
		}
		//消耗用户的可用热力和用户活动统计的可用热力
		if (hotValue.compareTo(BigDecimal.ZERO) != 0) {
			statistical.setUsableCash(statistical.getUsableCash().subtract(hotCash));
			statistical.setUsableHotValue(statistical.getUsableHotValue().subtract(hotValue));
			loginUser.setUsableHot(loginUser.getUsableHot().subtract(hotValue));

			//插入热力明细
			HotDetail hotDetail = new HotDetail();
			hotDetail.setNote(pointsGoods.getName() + "兑换");
			hotDetail.setHotValue(hotValue.negate());
			hotDetail.setUserId(exchangeDTO.getUserId());
			hotDetail.setType(2);
			hotDetail.setRelationId(pointsGoods.getId());
			hotDetailService.save(hotDetail);
		}
		userActivityStatisticalService.updateById(statistical);



		return R.data(loginUserService.updateById(loginUser));
	}

}
