package com.cyksj.web.controller.manage.coupon;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.annotation.Log;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.Jsons;
import com.cyksj.config.corp.WeChatCorpFactory;
import com.cyksj.dto.Result;
import com.cyksj.enums.BusinessType;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.CouponUserPopupsMapper;
import com.cyksj.mapper.CouponUserPopupsOrderRelateMapper;
import com.cyksj.mapper.OrderDonMapper;
import com.cyksj.mapper.corp.CorpUserAuthMapper;
import com.cyksj.mapper.corp.CorpUserMapper;
import com.cyksj.mapper.manage.coupon.*;
import com.cyksj.model.entity.*;
import com.cyksj.model.request.CorpCouponSendReq;
import com.cyksj.model.request.CouponActiveReq;
import com.cyksj.model.request.CouponClassificationReq;
import com.cyksj.model.request.CouponDistributeReq;
import com.cyksj.model.request.corp.CorpXmlMessage;
import com.cyksj.model.views.*;
import com.cyksj.service.corp.msg.CorpEventActionService;
import com.cyksj.service.coupon.EquipmentActivityReduceService;
import com.cyksj.service.mange.coupon.CouponCommonService;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.SearchResult;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Min;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/*
 *项目名: netflix
 *文件名: CouponController
 *创建者: JavaZou
 *创建时间:2022/11/17 13:44
 */
@RestController
@RequestMapping("/manage/coupon")
@RequiredArgsConstructor
@Slf4j
public class CouponController {
	private final CouponCommonService couponCommonService;

	private final CouponMapper couponMapper;

	private final BeanSearcher beanSearcher;

	private final CouponRecommendMapper couponRecommendMapper;

	private final CouponDistributePopularizeMapper couponDistributePopularizeMapper;

	private final CouponActiveMapper couponActiveMapper;

	private final CouponUserMapper couponUserMapper;

	private final CouponSkuMapper couponSkuMapper;

	private final CorpUserMapper corpUserMapper;

	private final CorpEventActionService corpEventActionService;

	private final CorpUserAuthMapper corpUserAuthMapper;

	private final CouponClassificationMapper couponClassificationMapper;

	private final OrderDonMapper orderDonMapper;

	private final HttpServletRequest request;

	private final EquipmentActivityReduceService equipmentActivityReduceService;

	private final CouponUserPopupsMapper couponUserPopupsMapper;

	private final CouponUserPopupsOrderRelateMapper couponUserPopupsOrderRelateMapper;

	/**
	 * 新增优惠券
	 */
	@PostMapping
	@Log(module = "优惠券/新增优惠券", businessType = BusinessType.POST, isSaveRequestData = true)
	public Result<String> couponSave(@RequestBody @Validated Coupon coupon) throws Exception {
		couponCommonService.saveCoupon(coupon);
		return GatewayResponse.SUCCESS.newBuilder().toResult("新增优惠券成功");
	}

	/**
	 * 删除优惠券
	 */
	@DeleteMapping("/{id}")
	@Transactional(rollbackFor = Throwable.class)
	@Log(module = "优惠券/删除优惠券", businessType = BusinessType.DELETE)
	public Result<String> couponSave(@PathVariable Long id) throws Exception {
		couponMapper.deleteById(id);
		couponSkuMapper.deleteByCid(id);
		couponActiveMapper.deleteByCouponId(id);
		couponRecommendMapper.deleteByCouponId(id);
		couponDistributePopularizeMapper.deleteByCouponId(id);
		return GatewayResponse.SUCCESS.newBuilder().toResult("删除优惠券成功");
	}

	/**
	 * 修改优惠券
	 */
	@PutMapping
	@Log(module = "优惠券/编辑优惠券", businessType = BusinessType.PUT, isSaveRequestData = true)
	public Result<String> putCoupon(@RequestBody @Validated Coupon coupon) throws Exception {
		couponCommonService.updateCoupon(coupon);
		return GatewayResponse.SUCCESS.newBuilder().toResult("修改优惠券成功");
	}

	/**
	 * 发放优惠券
	 */
	@PostMapping("/send")
	@Log(module = "优惠券/发放优惠券", businessType = BusinessType.POST, isSaveRequestData = true)
	public Result<String> senCoupon(@RequestBody @Validated CouponActiveReq couponActiveReq) throws Exception {
		couponCommonService.sendCoupon(couponActiveReq);
		return GatewayResponse.SUCCESS.newBuilder().toResult("发放优惠券成功");
	}

	/**
	 * 优惠券 设置为推荐优惠券
	 */
	@PutMapping("/set/hot/{couponId}")
	@Log(module = "优惠券/推荐优惠券", businessType = BusinessType.POST)
	public Result<String> setHotCoupon(@PathVariable @Min(value = 1) Long couponId, @RequestBody CouponRecommend recommend) {
		recommend.setCouponId(couponId);
		couponCommonService.setHotCoupon(recommend);
		return GatewayResponse.SUCCESS.newBuilder().toResult("推荐优惠券成功");
	}

	/**
	 * 优惠券关联固定推广者
	 */
	@PostMapping("/set/relation")
	public Result<String> setPopularizeRelation(@RequestBody CouponDistributeReq couponDistributeReq) {
		couponCommonService.setPopularizeRelation(couponDistributeReq);
		return GatewayResponse.SUCCESS.newBuilder().toResult("优惠券关联固定推广者成功");
	}

	/**
	 * 设置固定推广者兑换码
	 */
	@PutMapping("/set/relation/exCode")
	public Result<String> setPopularizeRelationCode(@RequestBody CouponDistributePopularize couponDistributePopularize) {
		couponCommonService.setPopularizeRelationCode(couponDistributePopularize);
		return GatewayResponse.SUCCESS.newBuilder().toResult("设置固定推广者兑换码成功");
	}

	/**
	 * 关联某优惠券列表
	 */
	@GetMapping("/get/relation/list")
	public Result<SearchResult<CouponDistributePopularizeView>> getRelationList(HttpServletRequest request) {
		SearchResult<CouponDistributePopularizeView> search = beanSearcher.search(CouponDistributePopularizeView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
		search.getDataList().forEach(data -> {
			Integer usedNum = orderDonMapper.selectCouponCodeUserNum(data.getId(), data.getExCode(), Constant.noOrderAllStatus);
			data.setUsedNum(usedNum);
		});
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 删除固定推广者关联
	 */
	@DeleteMapping("/relation/del/{relationId}")
	public Result<String> deleteRelationById(@PathVariable Long relationId) {
		couponDistributePopularizeMapper.deleteById(relationId);
		return GatewayResponse.SUCCESS.newBuilder().toResult("删除推广者关联成功");
	}

	/**
	 * 优惠券列表
	 */
	@GetMapping
	public Result<SearchResult<CouponView>> couponList(HttpServletRequest request) {
		SearchResult<CouponView> search = beanSearcher.search(CouponView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
		search.getDataList().forEach(data -> {
			data.setRelationNum(couponDistributePopularizeMapper.selectCount(Wrappers.lambdaQuery(CouponDistributePopularize.class).eq(CouponDistributePopularize::getDeleted, 1).eq(CouponDistributePopularize::getCouponId, data.getId())));

			Map<String, Long> couponUserNumData = couponUserMapper.selectCouponUserNumData(data.getId());
			Integer usedNum = Integer.parseInt(couponUserNumData.get("usedNum").toString());
			data.setUsedNum(usedNum);
			Integer receiptNum = Integer.parseInt(couponUserNumData.get("receiptNum").toString());
			data.setReceiptNum(receiptNum);

			List<GoodsDonSkuView> skuViewList = couponSkuMapper.selectGoodsSkuViewList(data.getId());
			data.setSkuViewList(skuViewList);
		});
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 所有优惠券列表
	 */
	@GetMapping("/get/couponList")
	public Result<List<Coupon>> getCouponList() {
		List<Coupon> couponList = beanSearcher.searchAll(Coupon.class, MapUtils.flatBuilder(request.getParameterMap())
				.field(Coupon::getDeleted, true)
				.onlySelect(Coupon::getId, Coupon::getName)
				.build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(couponList);
	}

	/**
	 * 优惠券发放列表
	 */
	@GetMapping("/active/list")
	public Result<SearchResult<CouponActiveView>> couponActiveList(HttpServletRequest request) {
		SearchResult<CouponActiveView> search = beanSearcher.search(CouponActiveView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
		search.getDataList().forEach(data -> {
			Integer usedNum = couponUserMapper.selectCount(Wrappers.lambdaQuery(CouponUser.class)
					.eq(CouponUser::getCouponActiveId, data.getId()).eq(CouponUser::getStatus, CouponUser.Status.used));
			Integer receiptNum = couponUserMapper.selectCount(Wrappers.lambdaQuery(CouponUser.class)
					.eq(CouponUser::getCouponActiveId, data.getId()));
			data.setReceiptNum(receiptNum);
			data.setUsedNum(usedNum);

			List<GoodsDonSkuView> skuViewList = couponSkuMapper.selectGoodsSkuViewList(data.getCouponId());
			data.setSkuViewList(skuViewList);
		});
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 发放优惠券停用
	 */
	@PutMapping("/active/putStatus/{couponActiveId}")
	public Result<String> activePutStatus(@PathVariable Long couponActiveId) {
		CouponActive couponActive = couponActiveMapper.selectById(couponActiveId);
		if (couponActive == null || !couponActive.getDeleted()) {
			throw BusinessRuntimeException.getInstance("发放记录已不存在");
		}
		if (!couponActive.getStatus()) {
			throw BusinessRuntimeException.getInstance("该发放优惠券已停用");
		}
		couponActive.setStatus(false);
		couponActiveMapper.updateById(couponActive);
		return GatewayResponse.SUCCESS.newBuilder().toResult("停用发放优惠券成功");
	}

	/**
	 * 发放优惠券失效
	 */
	@PutMapping("/active/putExpiryStatus/{couponActiveId}")
	public Result<String> activePutExpiryStatus(@PathVariable Long couponActiveId) {
		CouponActive couponActive = couponActiveMapper.selectById(couponActiveId);
		if (couponActive == null || !couponActive.getDeleted()) {
			throw BusinessRuntimeException.getInstance("发放记录已不存在");
		}
		if (!couponActive.getExpiryStatus()) {
			throw BusinessRuntimeException.getInstance("该发放优惠券已失效");
		}
		couponActive.setExpiryStatus(false);
		couponActive.setStatus(false);
		couponActiveMapper.updateById(couponActive);
		return GatewayResponse.SUCCESS.newBuilder().toResult("失效发放优惠券成功");
	}


	/**
	 * 推荐发放列表
	 */
	@GetMapping("/recommend/list")
	public Result<SearchResult<CouponRecommendView>> couponRecommendList(HttpServletRequest request) {
		SearchResult<CouponRecommendView> search = beanSearcher.search(CouponRecommendView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
		search.getDataList().forEach(data -> {
			Integer usedNum = couponUserMapper.selectCount(Wrappers.lambdaQuery(CouponUser.class)
					.eq(CouponUser::getRecommendId, data.getId()).eq(CouponUser::getStatus, CouponUser.Status.used));
			Integer receiptNum = couponUserMapper.selectCount(Wrappers.lambdaQuery(CouponUser.class)
					.eq(CouponUser::getRecommendId, data.getId()));
			data.setReceiptNum(receiptNum);
			data.setUsedNum(usedNum);

			List<GoodsDonSkuView> skuViewList = couponSkuMapper.selectGoodsSkuViewList(data.getCouponId());
			data.setSkuViewList(skuViewList);
			//重置优惠券推荐状态
			if (data.getStatus() && data.getDownTime() != null && DateTime.now().isAfter(data.getDownTime())) {
				data.setStatus(false);
				couponRecommendMapper.update(null, Wrappers.lambdaUpdate(CouponRecommend.class)
						.set(CouponRecommend::getStatus, false)
						.eq(CouponRecommend::getId, data.getId())
						.eq(CouponRecommend::getStatus, true));
			}
		});
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 推荐优惠券设置/取消推荐
	 */
	@PutMapping("/recommend/putStatus/{recommendId}")
	public Result<String> putRecommendStatusById(@PathVariable Long recommendId, @RequestBody CouponRecommend couponRecommend) {
		CouponRecommend dbRecommend = couponRecommendMapper.selectById(recommendId);
		if (dbRecommend == null || !dbRecommend.getDeleted()) {
			throw BusinessRuntimeException.getInstance("该推荐优惠券不存在");
		}
		if (couponRecommend.getUpTime() == null) {
			dbRecommend.setUpTime(null);
		}
		if (couponRecommend.getDownTime() == null) {
			dbRecommend.setDownTime(null);
		}
		dbRecommend.setStatus(!dbRecommend.getStatus());
		dbRecommend.setUpTime(couponRecommend.getUpTime());
		dbRecommend.setDownTime(couponRecommend.getDownTime());
		couponRecommendMapper.updateById(dbRecommend);
		return GatewayResponse.SUCCESS.newBuilder().toResult("操作成功");
	}

	/**
	 * 删除推荐优惠券
	 */
	@DeleteMapping("/recommend/del/{recommendId}")
	public Result<String> deleteRecommendById(@PathVariable Long recommendId) {
		CouponRecommend couponRecommend = couponRecommendMapper.selectById(recommendId);
		if (couponRecommend == null || !couponRecommend.getDeleted()) {
			throw BusinessRuntimeException.getInstance("该推荐优惠券不存在");
		}
		if (couponRecommend.getStatus()) {
			throw BusinessRuntimeException.getInstance("取消推荐优惠券，才可删除");
		}
		couponRecommendMapper.deleteById(recommendId);
		Coupon coupon = couponMapper.selectById(couponRecommend.getCouponId());
		if (coupon != null && coupon.getDeleted()) {
			coupon.setHotStatus(false);
			couponMapper.updateById(coupon);
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult("删除推荐优惠券成功");
	}

	/**
	 * 企业微信发放优惠券
	 */
	@PostMapping("/corp/send")
	public Result<String> corpSendCoupon(@RequestBody @Validated CorpCouponSendReq corpCouponSendReq) throws Exception {
		String corpId = corpCouponSendReq.getCorpId();
		String externalUserId = corpCouponSendReq.getExternalUserId();
		String unionid = getUnionId(corpId, externalUserId);
		Long couponId = corpCouponSendReq.getCouponId();
		if (StrUtil.isEmpty(unionid)) {
			throw BusinessRuntimeException.getInstance("该用户不是微信用户");
		}
		couponCommonService.corpSendCoupon(unionid, couponId);
		return GatewayResponse.SUCCESS.newBuilder().toResult("发放优惠券成功");
	}

	/**
	 * 新增优惠券分类
	 */
	@PostMapping("/post/classification")
	public Result<String> saveClassification(@RequestBody @Validated CouponClassification classification) {
		try {
			couponClassificationMapper.insert(classification);
		} catch (DuplicateKeyException e) {
			throw BusinessRuntimeException.getInstance("优惠券名称重复");
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult("新增优惠券成功");
	}

	/**
	 * 删除优惠券分类
	 */
	@DeleteMapping("/delete/classification/{classificationId}")
	public Result<String> deletedClassificationById(@PathVariable Long classificationId) {
		Integer count = couponMapper.selectCount(Wrappers.lambdaQuery(Coupon.class)
				.eq(Coupon::getClassificationId, classificationId)
				.eq(Coupon::getDeleted, true));
		if (count > 0) {
			throw BusinessRuntimeException.getInstance("分类存在优惠券");
		}
		couponClassificationMapper.deleteById(classificationId);
		return GatewayResponse.SUCCESS.newBuilder().toResult("删除优惠券分类成功");
	}

	/**
	 * 优惠券转移分类
	 */
	@PutMapping("/update/coupon/classification")
	public Result<String> changeCouponClassificationByClassificationId(@RequestBody @Validated CouponClassificationReq req) {
		Long classificationId = req.getId();
		Long newClassificationId = req.getNewClassificationId();
		List<Coupon> coupons = couponMapper.selectList(Wrappers.lambdaQuery(Coupon.class)
				.eq(Coupon::getClassificationId, classificationId)
				.eq(Coupon::getDeleted, true)
				.select(Coupon::getId));
		if (coupons.isEmpty()) {
			throw BusinessRuntimeException.getInstance("该分类下无优惠券");
		}
		CouponClassification couponClassification = couponClassificationMapper.selectById(newClassificationId);
		if (couponClassification == null) {
			throw BusinessRuntimeException.getInstance("要转移分类不存在");
		}
		couponMapper.update(null, Wrappers.lambdaUpdate(Coupon.class)
				.set(Coupon::getClassificationId, newClassificationId)
				.in(Coupon::getId, coupons.stream().map(Coupon::getId).collect(Collectors.toList())));
		return GatewayResponse.SUCCESS.newBuilder().toResult("转移优惠券分类成功");
	}

	/**
	 * 编辑优惠券分类
	 */
	@PutMapping("/update/classification")
	public Result<String> updateClassification(@RequestBody @Validated CouponClassification classification) {
		Long classificationId = classification.getId();
		Assert.notNull(classificationId, "分类id为空");
		CouponClassification couponClassification = couponClassificationMapper.selectById(classificationId);
		if (couponClassification == null) {
			throw BusinessRuntimeException.getInstance("该分类不存在");
		}
		couponClassificationMapper.updateById(classification);
		return GatewayResponse.SUCCESS.newBuilder().toResult("编辑分类成功");
	}

	/**
	 * 优惠券分类列表
	 */
	@GetMapping("/get/classification")
	public Result<SearchResult<CouponClassificationView>> classificationView() {
		SearchResult<CouponClassificationView> search = beanSearcher.search(CouponClassificationView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 优惠券所有分类
	 */
	@GetMapping("/get/classificationList")
	public Result<List<CouponClassification>> getClassificationList() {
		List<CouponClassification> CouponClassifications = beanSearcher.searchAll(CouponClassification.class, MapUtils.flatBuilder(request.getParameterMap()).build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(CouponClassifications);
	}

	public String getUnionId(String corpId, String externalUserId) throws Exception {
		WxCorpApp wxCorpApp = WeChatCorpFactory.getCorpConfigStrategy(corpId);
		LambdaQueryWrapper<CorpUserAuth> corpUserAuthWrapper = Wrappers.lambdaQuery(CorpUserAuth.class)
				.eq(CorpUserAuth::getExternalUserid, externalUserId)
				.eq(CorpUserAuth::getWxCorpId, wxCorpApp.getId()).last("limit 1");
		CorpUserAuth corpUserAuth = corpUserAuthMapper.selectOne(corpUserAuthWrapper);
		CorpUser corpUser = null;
		if (corpUserAuth == null) {
			//尝试添加客户
			CorpXmlMessage message = new CorpXmlMessage();
			message.setToUserName(wxCorpApp.getCorpId());
			message.setExternalUserId(externalUserId);
			corpEventActionService.addExternalContact(message, null);
			corpUserAuth = corpUserAuthMapper.selectOne(corpUserAuthWrapper);
			if (corpUserAuth != null) {
				corpUser = corpUserMapper.selectOne(Wrappers.lambdaQuery(CorpUser.class).eq(CorpUser::getId, corpUserAuth.getCorpUserId()).last("limit 1"));
			}
		} else {
			corpUser = corpUserMapper.selectOne(Wrappers.lambdaQuery(CorpUser.class).eq(CorpUser::getId, corpUserAuth.getCorpUserId()).last("limit 1"));
		}
		if (corpUser == null) {
			log.info("该客户{}不存在", externalUserId);
			throw BusinessRuntimeException.getInstance("该企业微信用户不存在..");
		}
		return corpUser.getUnionid();
	}


	/**
	 * 设置 设备活动满减配置
	 */
	@PostMapping("/set/equipment/activity/reduce")
	public Result<String> setEquipmentAcReduceConfig(@RequestBody EquipmentActivityReduce equipmentActivityReduce) {
		equipmentActivityReduceService.saveOrUpdateEquipmentAcReduceConfig(equipmentActivityReduce);
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}

	/**
	 * 编辑 设备活动满减配置
	 */
	@PutMapping("/put/equipment/activity/reduce")
	public Result<String> updateEquipmentAcReduceConfig(@RequestBody EquipmentActivityReduce equipmentActivityReduce) {
		if (equipmentActivityReduce.getId() == null) {
			throw BusinessRuntimeException.getInstance("记录不存在..");
		}
		equipmentActivityReduceService.saveOrUpdateEquipmentAcReduceConfig(equipmentActivityReduce);
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}

	/**
	 * 设备活动满减列表
	 */
	@GetMapping("/get/equipment/activity/reduce")
	public Result<SearchResult<EquipmentActivityReduce>> getEquipmentAcReduceConfig() {
		SearchResult<EquipmentActivityReduce> search = beanSearcher.search(EquipmentActivityReduce.class, MapUtils.flatBuilder(request.getParameterMap())
				.field(EquipmentActivityReduce::getDeleted, true)
				.orderBy(EquipmentActivityReduce::getId).desc()
				.build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}


	/**
	 * 删除设备满减活动
	 */
	@DeleteMapping("/del/equipment/activity/reduce/{id}")
	public Result<String> getEquipmentAcReduceConfig(@PathVariable Long id) {
		Optional.ofNullable(equipmentActivityReduceService.getById(id)).ifPresent(e -> {
			e.setDeleted(false);
			equipmentActivityReduceService.updateById(e);
		});
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}

	/**
	 * 优惠券领取详情
	 */
	@GetMapping("/get/receipt/detail/{couponId}")
	public Result<SearchResult<CouponReceiptDetailView>> getReceiptDetail(@PathVariable Long couponId) {
		SearchResult<CouponReceiptDetailView> search = beanSearcher.search(CouponReceiptDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
				.put("cid",String.format("and id = %s", couponId))
				.build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 优惠券使用详情
	 */
	@GetMapping("/get/used/detail/{couponId}")
	public Result<SearchResult<CouponUsedDetailView>> getUsedDetail(@PathVariable Long couponId) {
		SearchResult<CouponUsedDetailView> search = beanSearcher.search(CouponUsedDetailView.class, MapUtils.flatBuilder(request.getParameterMap())
				.put("cid",String.format("and id = %s", couponId))
				.build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 使用优惠券订单金额
	 */
	@GetMapping("/get/used/money/{couponId}")
	public Result<BigDecimal> getUsedMoney(@PathVariable Long couponId) {
		BigDecimal money = Optional.ofNullable(orderDonMapper.getCouponUsedMoney(couponId)).orElse(BigDecimal.ZERO);
		return GatewayResponse.SUCCESS.newBuilder().toResult(money.divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN));
	}

	/**
	 * 优惠券级联列表
	 */
	@GetMapping("/get/cascade")
	public Result<List<CouponClassificationCascadeView>> getCouponClassificationCascade() {
		List<CouponClassificationCascadeView> couponClassificationCascadeViews = beanSearcher.searchAll(CouponClassificationCascadeView.class, MapUtils.flatBuilder(request.getParameterMap()).build());

		List<CouponClassificationCascadeView> views = new ArrayList<>();
		DateTime now = DateTime.now();
		couponClassificationCascadeViews.stream().filter(c -> {
			if (c.getIsValidTime() && c.getValidStartTime() != null) {
				Date validStartTime = c.getValidStartTime();
				Date validEndTime = c.getValidEndTime();
				if (validStartTime.compareTo(now) <= 0 && validEndTime.compareTo(now) >= 0) {
					return true;
				}
				return false;
			}
			return true;
		}).collect(Collectors.groupingBy(CouponClassificationCascadeView::getCategory)).forEach((category, coupons) -> {
			CouponClassificationCascadeView couponClassificationCascadeView = new CouponClassificationCascadeView();
			couponClassificationCascadeView.setLabel(category);
			couponClassificationCascadeView.setValue(category);
			List<CouponClassificationCascadeView.CouponChild> couponChildren = coupons.stream()
					.map(view -> convertToCouponChild(view))
					.collect(Collectors.toList());
			couponClassificationCascadeView.setChildren(couponChildren);
			views.add(couponClassificationCascadeView);
		});
		return GatewayResponse.SUCCESS.newBuilder().toResult(views);
	}

	private CouponClassificationCascadeView.CouponChild convertToCouponChild(CouponClassificationCascadeView view) {
		CouponClassificationCascadeView.CouponChild couponChild = new CouponClassificationCascadeView.CouponChild();
		couponChild.setLabel(view.getName());
		couponChild.setValue(view.getId());
		return couponChild;
	}

	//===================================================优惠券弹窗===========================================================================================

	/**
	 * 新增优惠弹窗
	 */
	@PostMapping("/post/popups")
	public Result<String> insertPopups(@RequestBody CouponUserPopups popups) {
		couponUserPopupsMapper.insert(popups);
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}

	/**
	 * 编辑优惠弹窗
	 */
	@PutMapping("/update/popups")
	public Result<String> updatePopups(@RequestBody CouponUserPopups popups) {
		couponUserPopupsMapper.updateById(popups);
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}

	/**
	 * 删除优惠弹窗
	 */
	@DeleteMapping("/delete/popups/{id}")
	public Result<String> updatePopups(@PathVariable Long id) {
		couponUserPopupsMapper.deleteById(id);
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}

	/**
	 * 上下架优惠弹窗
	 */
	@PutMapping("/update/popups/status/{id}")
	public Result<String> updatePopupsStatusById(@PathVariable Long id) {
		Optional.ofNullable(couponUserPopupsMapper.selectById(id)).ifPresent(en->{
			en.setStatus(!en.getStatus());
			couponUserPopupsMapper.updateById(en);
		});
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}

	/**
	 * 优惠弹窗列表
	 */
	@GetMapping("/get/popups")
	public Result<SearchResult<CouponUserPopups>> getPopups() {
		SearchResult<CouponUserPopups> search = beanSearcher.search(CouponUserPopups.class, MapUtils.flatBuilder(request.getParameterMap()).orderBy(CouponUserPopups::getUpdateTime).desc().build());
		search.getDataList().forEach(pop->{
			try {
				String couponNames = couponMapper.selectList(Wrappers.lambdaQuery(Coupon.class)
						.in(Coupon::getId, Jsons.parseList(pop.getCouponIds(), Long.class))).stream().map(Coupon::getName).collect(Collectors.joining("、"));
				pop.setCouponNames(couponNames);
				pop.setOrderNum(couponUserPopupsOrderRelateMapper.selectCountOrders(pop.getId()));
			} catch (Exception e) {

			}
		});
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}
}
