package com.cyksj.web.controller.user;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.EnvCommonService;
import com.cyksj.common.annotation.NoSubmit;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.ValidatorUtil;
import com.cyksj.config.wxlogin.WxOpenPlatYHLXLoginConfig;
import com.cyksj.dto.Result;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.GoodsDonMapper;
import com.cyksj.mapper.GoodsDonSkuMapper;
import com.cyksj.mapper.OrderDonMapper;
import com.cyksj.mapper.UserMapper;
import com.cyksj.mapper.manage.coupon.CouponDistributePopularizeMapper;
import com.cyksj.mapper.manage.coupon.CouponMapper;
import com.cyksj.mapper.manage.distribute.DistributeMoneyApplyMapper;
import com.cyksj.mapper.manage.distribute.DistributePointsExchangeMoneyMapper;
import com.cyksj.mapper.manage.distribute.DistributeWaitingSendPointsMapper;
import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
import com.cyksj.model.entity.*;
import com.cyksj.model.request.ApplyMoneyReq;
import com.cyksj.model.views.*;
import com.cyksj.service.distribute.DistributeService;
import com.cyksj.service.pay.TransferFuncService;
import com.cyksj.service.user.UserCommonService;
import com.cyksj.web.util.StpCpsManageUser;
import com.cyksj.web.util.StpUserUtil;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.SearchResult;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

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

/*
 *项目名: netflix
 *文件名: DistributePopularizeController
 *创建者: JavaZou
 *创建时间:2022/11/15 13:59
 * 服务端-》我的分发推广controller
 */
@RestController
@RequestMapping("/distribute/popularize")
@RequiredArgsConstructor
public class DistributePopularizeController {
	private final EnvCommonService envCommonService;

	private final UserMapper userMapper;

	private final UserCommonService userCommonService;

	private final BeanSearcher beanSearcher;

	private final GoodsDonMapper goodsDonMapper;

	private final GoodsDonSkuMapper goodsDonSkuMapper;

	private final DistributePointsExchangeMoneyMapper distributePointsExchangeMoneyMapper;

	private final DistributeMoneyApplyMapper distributeMoneyApplyMapper;

	private final UserDistributeMapper userDistributeMapper;

	private final DistributeWaitingSendPointsMapper distributeWaitingSendPointsMapper;

	private final OrderDonMapper orderDonMapper;

	private final TransferFuncService transferFuncService;

	private final DistributeService distributeService;

	private final CouponDistributePopularizeMapper couponDistributePopularizeMapper;

	private final CouponMapper couponMapper;

	private final WxOpenPlatYHLXLoginConfig wxOpenPlatYHLXLoginConfig;

	/**
	 * 推广订单明细
	 */
	@GetMapping("/orders/detail")
	public Result<SearchResult<DistributePopularizeOrdersView>> getOrdersView(HttpServletRequest request) {
		Long userId = StpUserUtil.getLoginIdAsLong();
		SearchResult<DistributePopularizeOrdersView> search = beanSearcher.search(DistributePopularizeOrdersView.class,
				MapUtils.flatBuilder(request.getParameterMap())
						.field(DistributePopularizeOrdersView::getSharedId, userId)
						.build());
		DistributePointsExchangeMoney distributePointsExchangeMoney = distributePointsExchangeMoneyMapper.selectOne(Wrappers.lambdaQuery(DistributePointsExchangeMoney.class).orderByDesc(DistributePointsExchangeMoney::getPoints).last("limit 1"));
		BigDecimal points = BigDecimal.valueOf(distributePointsExchangeMoney.getPoints());
		BigDecimal money = distributePointsExchangeMoney.getMoney();
		BigDecimal oneHundred = BigDecimal.valueOf(100);
		search.getDataList().forEach(data -> {
			GoodsDon goodsDon = goodsDonMapper.selectById(data.getGoodsId());
			data.setGoodsTitle(goodsDon.getTitle());
			if (data.getSkuId() != null) {
				GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(data.getSkuId());
				if (goodsDonSku != null) {
					data.setSpecVal(goodsDonSku.getSpecVal());
				}
			}
			data.setWaitGetMoney(data.getPoints().divide(points).multiply(money).divide(oneHundred, 2, RoundingMode.DOWN));
			//原先奖励
			data.setOriGetMoney(data.getOriPoints().divide(points).multiply(money).divide(oneHundred, 2, RoundingMode.DOWN));
		});
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 提现明细
	 */
	@GetMapping("/applyMoney/detail")
	public Result<SearchResult<DistributeMoneyApplyView>> getApplyMoneyView(HttpServletRequest request) {
		Long userId = StpUserUtil.getLoginIdAsLong();
		SearchResult<DistributeMoneyApplyView> search = beanSearcher.search(DistributeMoneyApplyView.class,
				MapUtils.flatBuilder(request.getParameterMap())
						.field(DistributeMoneyApplyView::getUserId, userId).op(Operator.Equal)
						.build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 个人推广详情
	 */
	@GetMapping("/get/detail")
	public Result<DistributePopularizeView> getDetail() {
		Long userId = StpUserUtil.getLoginIdAsLong();
		User user = userMapper.selectById(userId);
		if (StrUtil.isEmpty(user.getShowId())) {
			user.setShowId(userCommonService.getUserShowId(userId));
		}
		DistributePopularizeView distributePopularizeView = new DistributePopularizeView();
		String dsUrl = String.format(envCommonService.DISTRIBUTE_DEFAULT_URL_PREFIX, user.getShowId());
		distributePopularizeView.setUrl(dsUrl);
//		distributePopularizeView.setUrlCode(QrCodeUtil.generateAsBase64(distributePopularizeView.getUrl(), QrConfig.create(), "png"));
		distributePopularizeView.setGotPoints(user.getPoints());
		Integer orders = userDistributeMapper.count(userId);
		distributePopularizeView.setDistributeOrders(orders);
		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, userId).eq(UserDistribute::getDeleted, 1).select(UserDistribute::getId).last("limit 1"));
		if (userDistribute != null) {
			//是否是固定推广者
			UserDistributeView userDistributeView = beanSearcher.searchFirst(UserDistributeView.class, MapUtils.builder()
					.put("dis_id", String.format(" and up.distribute_id = %s", userDistribute.getId()))
					.orderBy(UserDistributeView::getRate).desc()
					.build());
			//最高平台比例
			distributePopularizeView.setHighestRate(userDistributeView.getRate());
		} else {
			GoodsDon goodsDon = goodsDonMapper.selectOne(Wrappers.lambdaQuery(GoodsDon.class).eq(GoodsDon::getDeleted, true).eq(GoodsDon::getStatus, true).orderByDesc(GoodsDon::getRate).select(GoodsDon::getRate).last("limit 1"));
			distributePopularizeView.setIsGeneral(true);
			distributePopularizeView.setHighestRate(goodsDon.getRate());
			Optional.ofNullable(couponDistributePopularizeMapper.selectOne(Wrappers.lambdaQuery(CouponDistributePopularize.class)
							.eq(CouponDistributePopularize::getUserId, userId)
							.eq(CouponDistributePopularize::getIsGeneral, true)
							.eq(CouponDistributePopularize::getDeleted, 1)
							.last("limit 1")))
					.ifPresent(couponPopularize -> {
						Coupon coupon = couponMapper.getCouponById(couponPopularize.getCouponId());
						distributePopularizeView.setGeneralCode(couponPopularize.getExCode());
						BigDecimal discount = coupon.getDiscount();
						String discountStr = String.format("%s折", discount.multiply(BigDecimal.valueOf(100)).intValue());
						distributePopularizeView.setGeneralDiscount(discountStr);
					});
		}
		List<DistributeWaitingSendPoints> distributeWaitingSendPoints = distributeWaitingSendPointsMapper.selectList(Wrappers.lambdaQuery(DistributeWaitingSendPoints.class).eq(DistributeWaitingSendPoints::getSendStatus, DistributeWaitingSendPoints.Status.waiting).eq(DistributeWaitingSendPoints::getSharedId, userId).select(DistributeWaitingSendPoints::getPoints));
		BigDecimal waitingPoints = BigDecimal.ZERO;
		if (!distributeWaitingSendPoints.isEmpty()) {
			Optional<BigDecimal> points = distributeWaitingSendPoints.stream().map(DistributeWaitingSendPoints::getPoints).reduce(BigDecimal::add);
			if (points.isPresent()) {
				waitingPoints = points.get();
			}
		}
		distributePopularizeView.setWaitingSendPoints(waitingPoints);
		if (user.getPoints().compareTo(BigDecimal.ZERO) <= 0 && waitingPoints.compareTo(BigDecimal.ZERO) <= 0) {
			distributePopularizeView.setGotMoney(BigDecimal.ZERO);
			distributePopularizeView.setWaitingMoney(BigDecimal.ZERO);
		}else {
			DistributePointsExchangeMoney distributePointsExchangeMoney = distributePointsExchangeMoneyMapper.selectOne(Wrappers.lambdaQuery(DistributePointsExchangeMoney.class).orderByDesc(DistributePointsExchangeMoney::getPoints).last("limit 1"));
			BigDecimal points = BigDecimal.valueOf(distributePointsExchangeMoney.getPoints());
			BigDecimal money = distributePointsExchangeMoney.getMoney();
			BigDecimal oneHundred = BigDecimal.valueOf(100);
			if (user.getPoints().compareTo(BigDecimal.ZERO) >= 0) {
				distributePopularizeView.setGotMoney(user.getPoints().divide(points).multiply(money).divide(oneHundred, 2, RoundingMode.HALF_DOWN));
			}
			if (user.getPoints().compareTo(BigDecimal.ZERO) >= 0) {
				distributePopularizeView.setWaitingMoney(waitingPoints.divide(points).multiply(money).divide(oneHundred, 2, RoundingMode.DOWN));
			}
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(distributePopularizeView);
	}

	/**
	 * 个人推广用户每日订单情况折线图
	 */
	@GetMapping("/get/order/brokenLine")
	public Result<BrokenLineObjView> getPersonDistributeBrokenLineView(Long firstDate, Long lastDate) {
		Long userId = StpUserUtil.getLoginIdAsLong();
		String first = null;
		String end = null;
		if (firstDate != null) {
			first = DateUtil.format(DateTime.of(firstDate), "yyyy-MM-dd");
		}
		if (lastDate != null) {
			end = DateUtil.format(DateTime.of(lastDate), "yyyy-MM-dd");
		}
		BrokenLineObjView brokenLineObjView = Optional.ofNullable(orderDonMapper.selectPersonDistributeBrokenLine(userId, first, end))
				.orElse(new BrokenLineObjView());

		if (brokenLineObjView != null) {
			List<PersonDistributeBrokenLineView> views = beanSearcher.searchAll(PersonDistributeBrokenLineView.class, MapUtils.builder()
					.field(PersonDistributeBrokenLineView::getDate, first, end).op(Operator.Between)
					.put("userId", String.format("dw.shared_id = %s", userId))
					.orderBy(PersonDistributeBrokenLineView::getDate).asc()
					.build());
			Map<Long, List<PersonDistributeBrokenLineView>> distributeMap = views.stream().collect(Collectors.groupingBy(PersonDistributeBrokenLineView::getGoodsId));
			brokenLineObjView.setDistributeData(distributeMap);
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(brokenLineObjView);
	}


	/**
	 * 提现
	 */
	@NoSubmit
	@PostMapping("/post/applyMoney")
	@Transactional(rollbackFor = Throwable.class)
	public Result<DistributeMoneyApply> applyMoney(@RequestBody ApplyMoneyReq applyMoneyReq) throws Exception {
		Long userId = StpUserUtil.getLoginIdAsLong();
		applyMoneyReq.setUserId(userId);
		return transferFuncService.distributeApply(applyMoneyReq);
	}

	/**
	 * 获取积分兑换门槛
	 */
	@GetMapping("/applyMoney/threshold")
	public Result<DistributePointsExchangeMoney> getThreshold() {
		Long userId = StpUserUtil.getLoginIdAsLong();
		return GatewayResponse.SUCCESS.newBuilder().toResult(distributePointsExchangeMoneyMapper.selectOne(Wrappers.lambdaQuery(DistributePointsExchangeMoney.class).last("limit 1")));
	}

	/**
	 * 提现缓存数据
	 */
	@GetMapping("/get/applyMoney/detail")
	public Result<DistributeMoneyApply> getLastApplyDetail() {
		Long userId = StpUserUtil.getLoginIdAsLong();
		DistributeMoneyApply apply = distributeMoneyApplyMapper.selectOne(Wrappers.lambdaQuery(DistributeMoneyApply.class).eq(DistributeMoneyApply::getUserId, userId).orderByDesc(DistributeMoneyApply::getId).last("limit 1"));
		return GatewayResponse.SUCCESS.newBuilder().toResult(apply);
	}

	/**
	 * 是否是普通分销者
	 */
	@GetMapping("/get/isGeneral/distribute")
	public Result<Boolean> isGeneralDistribute() {
		Long userId = StpUserUtil.getLoginIdAsLong();
		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
				.eq(UserDistribute::getDeleted, 1)
				.eq(UserDistribute::getUserId, userId));
		if (userDistribute != null) {
			return GatewayResponse.SUCCESS.newBuilder().toResult(false);
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(true);
	}

	/**
	 * 普通分销者弹窗
	 */
	@GetMapping("/get/general/distribute/detail")
	public Result<DistributePopularizeView> getGeneralDistributeDetail() {
		Long userId = StpUserUtil.getLoginIdAsLong();
		List<GoodsDon> goodsDons = goodsDonMapper.selectList(Wrappers.lambdaQuery(GoodsDon.class).eq(GoodsDon::getDeleted, true).eq(GoodsDon::getStatus, true).eq(GoodsDon::getType, 1).orderByAsc(GoodsDon::getRate).select(GoodsDon::getRate, GoodsDon::getTitle));
		if (goodsDons.isEmpty()) {
			return GatewayResponse.SUCCESS.newBuilder().toResult();
		}
		DistributePopularizeView distributePopularizeView = new DistributePopularizeView();
		GoodsDon highestRateGoods = goodsDons.get(goodsDons.size() - 1);
		distributePopularizeView.setHighestRate(highestRateGoods.getRate());
		Map<Integer, List<GoodsDon>> rateMap = goodsDons.stream().filter(gd -> !gd.getRate().equals(highestRateGoods.getRate())).collect(Collectors.groupingBy(GoodsDon::getRate));
		List<DistributeGoodsGeneralRateView> generalDistributes = new ArrayList<>();
		rateMap.forEach((rate, v) -> {
			DistributeGoodsGeneralRateView rateView = new DistributeGoodsGeneralRateView();
			rateView.setRate(rate);
			String goodsInfo = v.stream().map(GoodsDon::getTitle).collect(Collectors.joining("/"));
			rateView.setGoodsInfo(goodsInfo);
			generalDistributes.add(rateView);
		});
		generalDistributes.sort(Comparator.comparing(DistributeGoodsGeneralRateView::getRate).reversed());
		distributePopularizeView.setGeneralDistributes(generalDistributes);

		//普通规格分销
		List<GoodsDonGeneralSkuFrontView> goodsDonGeneralSkuFrontViews = beanSearcher.searchAll(GoodsDonGeneralSkuFrontView.class, MapUtils.builder().field(GoodsDonGeneralSkuFrontView::getRate, 0).op(Operator.GreaterEqual).build());
		distributePopularizeView.setSkuRates(goodsDonGeneralSkuFrontViews);
		return GatewayResponse.SUCCESS.newBuilder().toResult(distributePopularizeView);
	}

	/**
	 * 设置普通推广码
	 * 绑定个人专属码
	 */
	@PostMapping("/general/code/{code}")
	public Result<String> setGeneralCode(@PathVariable("code") String code) {
		long userId = StpUserUtil.getLoginIdAsLong();
		if (StrUtil.isBlank(code)) {
			throw BusinessRuntimeException.getInstance("专属推广优惠码不能为空");
		}
		if (!ValidatorUtil.isEnNum(code) || code.length() > 20) {
			throw BusinessRuntimeException.getInstance("请输入英文数字组合的专属推广优惠码");
		}
		code = code.trim();
		distributeService.bindPopularizeCode(userId, code);
		return GatewayResponse.SUCCESS.newBuilder().toResult("设置成功");
	}

	/**
	 * 固定推广登录信息
	 */
	@GetMapping("/get/ds/detail")
	public Result<String> getDistributeDetail() {
		long userId = StpUserUtil.getLoginIdAsLong();
		User user = userMapper.selectById(userId);
		if (user == null) throw BusinessRuntimeException.getInstance("用户信息不存在");
		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, user.getId()).eq(UserDistribute::getDeleted, 1).select(UserDistribute::getId).last("limit 1"));
		if (userDistribute == null) throw BusinessRuntimeException.getInstance("只支持渠道分销用户登录");
		StpCpsManageUser.login(user.getId());
		String cpsToken = StpCpsManageUser.getTokenValue();
		return GatewayResponse.SUCCESS.newBuilder().toResult(wxOpenPlatYHLXLoginConfig.getCpsWebRedirectUri() + "?t=" + cpsToken);
	}
}