package com.cyksj.web.controller.cps;

import cn.hutool.core.collection.CollUtil;
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.constant.Constant;
import com.cyksj.common.util.Jsons;
import com.cyksj.dto.Result;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.GoodsDonMapper;
import com.cyksj.mapper.manage.distribute.UserDistributeMapper;
import com.cyksj.mapper.sys.SysConfigMapper;
import com.cyksj.model.entity.*;
import com.cyksj.model.views.*;
import com.cyksj.service.cps.CpsManageService;
import com.cyksj.web.util.StpCpsManageUser;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.SearchResult;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapBuilder;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 项目名: yhlxj2
 * 文件名: CpsDistribtueDataController
 * 创建者: JavaZou
 * 创建时间:2024/3/19 11:42
 * 分销数据控制层
 */
@RestController
@RequestMapping("/cps/manage")
@RequiredArgsConstructor
public class CpsDistribtueDataController {

	private final BeanSearcher beanSearcher;

	private final HttpServletRequest request;

	private final GoodsDonMapper goodsDonMapper;

	private final CpsManageService cpsManageService;

	private final UserDistributeMapper userDistributeMapper;

	private final SysConfigMapper sysConfigMapper;

	/**
	 * 个人分销平台数据详情
	 */
	@GetMapping("/get/distribute/detail")
	public Result<CpsUserDistributeDetailView> getDistributeDetail() {
		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
		User user = beanSearcher.searchFirst(User.class, MapUtils.builder().field(User::getId, cpsUserId).onlySelect(User::getPoints).build());
		BigDecimal thresholdPoints = BigDecimal.valueOf(1000);
		BigDecimal wApplyMoney = user.getPoints().divide(thresholdPoints, 2, RoundingMode.DOWN);
		//已提现
		Number gotApplyMoney = beanSearcher.searchSum(DistributeMoneyApply.class, MapUtils.builder()
				.field(DistributeMoneyApply::getUserId, cpsUserId)
				.field(DistributeMoneyApply::getVerifyStatus, DistributeMoneyApply.Status.success.name())
				.field(DistributeMoneyApply::getMType, DistributeMoneyApply.MType.ds.name())
				.build(), "money");
		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
				.eq(UserDistribute::getUserId, cpsUserId)
				.eq(UserDistribute::getDeleted, 1)
				.last("limit 1"));
		Number reMoneyPoints = beanSearcher.searchSum(DistributeWaitingSendPoints.class, MapUtils.builder().field(DistributeWaitingSendPoints::getSharedId, cpsUserId).field(DistributeWaitingSendPoints::getSendStatus, DistributeWaitingSendPoints.Status.success.name()).build(), "points");
		Number wMoneyPoints = beanSearcher.searchSum(DistributeWaitingSendPoints.class, MapUtils.builder().field(DistributeWaitingSendPoints::getSharedId, cpsUserId).field(DistributeWaitingSendPoints::getSendStatus, DistributeWaitingSendPoints.Status.waiting.name()).build(), "points");
		List<UserDistributeRateView> rateViews = beanSearcher.searchAll(UserDistributeRateView.class, MapUtils.builder()
				.put("distribute_id", String.format("and distribute_id = (select id from user_distribute where user_id = %s and deleted is true limit 1)", cpsUserId))
				.field(UserSkuDistributeView::getRate).op(Operator.NotNull)
				.orderBy(UserDistributeRateView::getRate).desc()
				.build());
		CpsUserDistributeDetailView detailView = new CpsUserDistributeDetailView();
		Map<String, List<UserDistributeRateView>> collect = rateViews.stream().filter(ct -> StrUtil.isNotBlank(ct.getCategoryName())).collect(Collectors.groupingBy(UserDistributeRateView::getCategoryName));

		List<UserSkuDistributeView> skuRates = beanSearcher.searchAll(UserSkuDistributeView.class, MapUtils.builder()
				.put("dis_id", String.format(" and up.distribute_id = %s", userDistribute.getId()))
				.field(UserSkuDistributeView::getRate).op(Operator.NotNull)
				.orderBy(UserSkuDistributeView::getGoodsId).asc()
				.build());
		//规格分销
		detailView.setSkuRates(skuRates);

		detailView.setRateViews(collect);
		detailView.setWMoney(BigDecimal.valueOf(wMoneyPoints.doubleValue()).divide(thresholdPoints, 2, RoundingMode.DOWN));
		detailView.setReMoney(BigDecimal.valueOf(reMoneyPoints.doubleValue()).divide(thresholdPoints, 2, RoundingMode.DOWN));

		detailView.setWApplyMoney(wApplyMoney);
		detailView.setGotApplyMoney(BigDecimal.valueOf(gotApplyMoney.doubleValue()).divide(BigDecimal.valueOf(100), 2, RoundingMode.DOWN));
		return GatewayResponse.SUCCESS.newBuilder().toResult(detailView);
	}

	/**
	 * 待入账数据统计
	 */
	@GetMapping("/get/wMoney/statisticsData")
	public Result<BrokenLineCpsUserWMoneyView> getWMoneyStatisticsDataView(Long firstDate, Long lastDate) {
		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
		DateTime first = null;
		DateTime end = null;
		if (firstDate != null) {
			first = DateUtil.date(firstDate);
		}
		if (lastDate != null) {
			end = DateUtil.date(lastDate);
		}
		BrokenLineCpsUserWMoneyView brokenLineCpsUserWMoneyView = Optional.ofNullable(cpsManageService.getWMoneyStatisticsDate(cpsUserId, first, end)).orElse(new BrokenLineCpsUserWMoneyView());
		List<CpsUserWMoneyStatisticsDataView> dataView = cpsManageService.getWMoneyStatisticsDataView(cpsUserId, first, end);
		brokenLineCpsUserWMoneyView.setDataView(dataView);
		return GatewayResponse.SUCCESS.newBuilder().toResult(brokenLineCpsUserWMoneyView);
	}

	/**
	 * 分销订单收入统计
	 */
	@GetMapping("/get/distribute/orders/statistics")
	public Result<SearchResult<UserDistributeOrdersStatisticsView>> getUserDistributeOrdersStatisticsView(Long firstDate, Long lastDate) {
		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
		String first = null;
		String end = null;
		String timeSql = StrUtil.EMPTY;
		if (firstDate != null) {
			first = DateUtil.format(DateTime.of(firstDate), "yyyy-MM-dd HH:mm:ss");
			timeSql += String.format(" and created_time >= '%s'", first);
		}
		if (lastDate != null) {
			end = DateUtil.format(DateTime.of(lastDate), "yyyy-MM-dd HH:mm:ss");
			timeSql += String.format(" and created_time < '%s'", end);
		}
		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
		builder.put("sharedId", String.format("shared_id = %s", cpsUserId));
		if (StrUtil.isNotEmpty(timeSql)) {
			builder.put("time", timeSql);
		}
		SearchResult<UserDistributeOrdersStatisticsView> search = beanSearcher.search(UserDistributeOrdersStatisticsView.class, builder.build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 分销订单收入详细
	 */
	@GetMapping("/get/distribute/orders/detail")
	public Result<SearchResult<UserDistributeOrdersDetailView>> getUserDistributeOrdersDetailView(Long firstDate, Long lastDate) {
		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
		String first = null;
		String end = null;
		String timeSql = StrUtil.EMPTY;
		if (firstDate != null) {
			first = DateUtil.format(DateTime.of(firstDate), "yyyy-MM-dd HH:mm:ss");
			timeSql += String.format(" and created_time >= '%s'", first);
		}
		if (lastDate != null) {
			end = DateUtil.format(DateTime.of(lastDate), "yyyy-MM-dd HH:mm:ss");
			timeSql += String.format(" and created_time < '%s'", end);
		}
		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
		builder.put("sharedId", String.format("shared_id = %s", cpsUserId));
		if (StrUtil.isNotEmpty(timeSql)) {
			builder.put("time", timeSql);
		}
		SearchResult<UserDistributeOrdersDetailView> search = beanSearcher.search(UserDistributeOrdersDetailView.class, builder.build());
		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
	}

	/**
	 * 分销商品列表
	 */
	@GetMapping("/get/goods")
	public Result<List<GoodsDon>> getGoodsList() {
		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
		List<GoodsDon> goodsDons = goodsDonMapper.getDistributeGoodsDetail(cpsUserId);
		return GatewayResponse.SUCCESS.newBuilder().toResult(goodsDons);
	}

	/**
	 * 数据中心折线图
	 */
	@GetMapping("/get/data/brokenLine")
	public Result<CpsOrderDataStatisticsView> getDataBrokenLine(Long firstDate, Long lastDate) {
		long cpsUserId = StpCpsManageUser.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");
		}
		CpsOrderDataStatisticsView brokenLineObjView = Optional.ofNullable(userDistributeMapper.selectOrderBrokenLineMoney(cpsUserId, first, end))
				.orElse(new CpsOrderDataStatisticsView());

		if (brokenLineObjView != null) {
			MapBuilder builder = MapUtils.builder();
			if (firstDate != null) {
				first = DateUtil.format(DateTime.of(firstDate), "yyyy-MM-dd HH:mm:ss");
			}
			if (lastDate != null) {
				end = DateUtil.format(DateTime.of(lastDate), "yyyy-MM-dd HH:mm:ss");
			}
			if (first != null && end != null) {
				builder.field(CpsOrderView::getDate, first, end).op(Operator.Between);
			}
			List<CpsOrderView> views = beanSearcher.searchAll(CpsOrderView.class, builder
					.put("userId", String.format("dw.shared_id = %s", cpsUserId))
					.orderBy(CpsOrderView::getDate).asc()
					.build());
			Map<Long, List<CpsOrderView>> goodsMap = views.stream().collect(Collectors.groupingBy(CpsOrderView::getGoodsId));
			brokenLineObjView.setGoodsData(goodsMap);
		}
		return GatewayResponse.SUCCESS.newBuilder().toResult(brokenLineObjView);
	}

	/**
	 * 渠道推广优惠码列表
	 */
	@GetMapping("/get/coupon/code/list")
	public Result<List<CouponDistributePopularizeDetailView>> getCouponCodeList() throws Exception {
		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
		UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class)
				.eq(UserDistribute::getUserId, cpsUserId)
				.eq(UserDistribute::getDeleted, true)
				.last("limit 1"));
		SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.COUPON_DISTRIBUTE_RELATE_COUPON_KEY)
				.last("limit 1"));
		List<Long> show_coupon_ids = null;
		if (sysConfig != null && StrUtil.isNotBlank(sysConfig.getSysValue())) {
			show_coupon_ids = Jsons.parseList(sysConfig.getSysValue(), Long.class);
		}
		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
		if (CollUtil.isEmpty(show_coupon_ids)) {
			show_coupon_ids = List.of(0l);
		}
		builder.field(CouponDistributePopularizeDetailView::getCouponId, show_coupon_ids).op(Operator.InList);
		DateTime now = DateTime.now();
		List<CouponDistributePopularizeDetailView> couponDistributePopularizeDetailViews = beanSearcher.searchAll(CouponDistributePopularizeDetailView.class, builder.field(CouponDistributePopularizeDetailView::getDistributeId, userDistribute.getId()).build());
		couponDistributePopularizeDetailViews = couponDistributePopularizeDetailViews.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.toList());
		return GatewayResponse.SUCCESS.newBuilder().toResult(couponDistributePopularizeDetailViews);
	}

	/**
	 * 设置渠道 推广优惠码
	 */
	@PostMapping("/set/coupon/code")
	public Result<String> setCouponCode(@RequestBody List<CouponDistributePopularize> couponRelates) throws Exception {
		long cpsUserId = StpCpsManageUser.getLoginIdAsLong();
		cpsManageService.setCouponCode(cpsUserId, couponRelates);
		return GatewayResponse.SUCCESS.newBuilder().toResult();
	}
}
