package com.cyksj.web.controller.manage.goods.shop;

import cn.dev33.satoken.stp.StpUtil;
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.annotation.NoSubmit;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.util.StringUtil;
import com.cyksj.dto.Result;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.GoodsDonSkuMapper;
import com.cyksj.mapper.UserMapper;
import com.cyksj.mapper.manage.cms.CmsUserMapper;
import com.cyksj.mapper.shop.YhShopMapper;
import com.cyksj.model.entity.*;
import com.cyksj.model.request.DistributeApplyMoneyReq;
import com.cyksj.model.request.GoodsDonShopRateReq;
import com.cyksj.model.request.YhShopUserPlatDistributeRateReq;
import com.cyksj.model.request.YhShopVerifyReq;
import com.cyksj.model.views.*;
import com.cyksj.service.mange.CmsGoodsDonSkuService;
import com.cyksj.service.mange.CmsYhShopCommonService;
import com.cyksj.service.mange.CmsYhShopGoodsRateService;
import com.cyksj.service.mange.RefreshCacheService;
import com.cyksj.service.mange.business.UserBusinessRateService;
import com.cyksj.service.mange.statistics.StatisticsDataService;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;


/**
 * admin/小店店铺/银河后台/商务管理
 * @author zwhui
 * @date 2023/9/14 16:42
 */
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/manage/shop")
public class CmsYhShopGoodsController {

    private final BeanSearcher beanSearcher;

    private final CmsYhShopGoodsRateService yhShopGoodsRateService;

    private final CmsYhShopCommonService cmsYhShopCommonService;

    private final HttpServletRequest request;

    private final UserBusinessRateService userBusinessRateService;

    private final UserMapper userMapper;

    private final CmsUserMapper cmsUserMapper;

    private final YhShopMapper yhShopMapper;

    private final StatisticsDataService statisticsDataService;

    private final GoodsDonSkuMapper skuMapper;

    private final CmsGoodsDonSkuService goodsDonSkuService;

    private final RefreshCacheService refreshCacheService;


    /**
     * 获取店铺平台价格
     */
    @GetMapping("/get/goods")
    public Result<SearchResult<YhShopGoodsRateView>> shopGoodsList(){
        SearchResult<YhShopGoodsRateView> search = beanSearcher.search(YhShopGoodsRateView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
        search.getDataList().forEach(e -> e.setList(beanSearcher.searchList(YhShopGoodsRateView.YhShopGoodsSkuRateView.class,MapUtils.builder().field(YhShopGoodsRateView.YhShopGoodsSkuRateView::getGoodsId,e.getGoodsId()).build())));
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 设置店铺平台价格浮动比例
     */
    @PutMapping("/put/goods/rate")
    @Transactional(rollbackFor = Throwable.class)
    public Result<Void> updShopGoodsRate(@RequestBody GoodsDonShopRateReq req) {
        req.getList().forEach(e -> {
            if (e.getRate() == null) {
                e.setRate(0);
            }
            Integer rate = e.getRate();
            if (rate < 0 && rate > 100) {
                throw BusinessRuntimeException.getInstance("请输入正确的比例");
            }
            YhShopGoodsRate one = yhShopGoodsRateService.getOne(Wrappers.lambdaQuery(YhShopGoodsRate.class)
                    .eq(YhShopGoodsRate::getSkuId, e.getSkuId()).last("limit 1"));
            if (one == null) {
                one = new YhShopGoodsRate();
                one.setRate(e.getRate());
                one.setGoodsId(e.getGoodsId());
                one.setSkuId(e.getSkuId());
            } else {
                one.setRate(e.getRate());
            }
            yhShopGoodsRateService.saveOrUpdate(one);

            GoodsDonSku sku = skuMapper.selectById(one.getSkuId());
            //下架店铺低于这个规格价格的品
            goodsDonSkuService.setBelowPriceShopSkuDown(e.getSkuId(), sku.getPrice());
        });
        refreshCacheService.refreshYhHomePageCache();
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 一键设置 店铺平台通用浮动比例
     */
    @PutMapping("/oneKey/set/goods/rate")
    @Transactional(rollbackFor = Throwable.class)
    public Result<Void> setShopGoodsGeneralRate(@RequestBody GoodsDonShopRateReq req) {
        Integer rate = Optional.ofNullable(req.getRate()).orElse(0);
        if (rate < 0 && rate > 100) {
            throw BusinessRuntimeException.getInstance("请输入正确的比例");
        }
        List<Long> goodsIds = req.getGoodsIds();
        goodsIds.forEach(goodsId -> {
            List<YhShopGoodsRate> yhShopGoodsRates = beanSearcher.searchList(YhShopGoodsRate.class, MapUtils.builder().field(YhShopGoodsRate::getGoodsId, goodsId).build());
            yhShopGoodsRates.forEach(data -> {
                data.setRate(rate);
            });
            yhShopGoodsRateService.saveOrUpdateBatch(yhShopGoodsRates);

            List<GoodsDonSku> goodsDonSkus = goodsDonSkuService.list(Wrappers.lambdaQuery(GoodsDonSku.class)
                    .eq(GoodsDonSku::getGoodsId, goodsId));
            goodsDonSkus.forEach(sku -> {
                //下架店铺低于这个规格价格的品
                goodsDonSkuService.setBelowPriceShopSkuDown(sku.getId(), sku.getPrice());
            });
        });
        refreshCacheService.refreshYhHomePageCache();
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 店铺管理列表
     */
    @GetMapping("/get")
    public Result<SearchResult<YhShopDistributeView>> getYhShopDistributeView(String showId, String nickname, String startTime, String endTime) {
        long adminId = StpUtil.getLoginIdAsLong();
        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
        //是否是商务人员
        if (userBusinessRateService.isBusiness(adminId)) {
            builder.field(YhShopDistributeView::getBusinessId, adminId);
        }
        if (StrUtil.isNotBlank(showId)) {
            builder.field(YhShopDistributeView::getUserId, userMapper.getUserIdByShowId(showId));
        }
        if (StrUtil.isNotBlank(nickname)) {
            List<Long> userIds = userMapper.selectListByNickname(nickname);
            builder.field(YhShopDistributeView::getUserId, userIds).op(Operator.InList);
        }
        String timeSql = StrUtil.EMPTY;
        if (StrUtil.isNotBlank(startTime)) {
            timeSql += String.format("and od.created_time >= '%s'", startTime);
        }
        if (StrUtil.isNotBlank(endTime)) {
            timeSql += String.format("and od.created_time < '%s'", endTime);
        }
        if (StrUtil.isNotBlank(timeSql)) {
            builder.put("time", timeSql);
            //按时间筛选 固定推广人分销情况 倒序
            builder.orderBy(YhShopDistributeView::getDistributeOrdersMoney).desc();
        }
        Map<Long, String> businessNameMap = new ConcurrentHashMap<>();
        SearchResult<YhShopDistributeView> search = beanSearcher.search(YhShopDistributeView.class, builder.build());
        search.getDataList().forEach(view -> {
            if (view.getDistributeOrdersMoney().compareTo(BigDecimal.ZERO) > 0) {
                Optional.ofNullable(yhShopMapper.selectSoldMaxGoods(view.getUserId())).ifPresent(title -> view.setGoodsTitle(title));
            }
            String businessName = businessNameMap.get(view.getBusinessId());
            view.setBusinessName(businessName);
            if (StrUtil.isEmpty(businessName)) {
                Optional.ofNullable(cmsUserMapper.selectById(view.getBusinessId())).ifPresent(cmsUser -> {
                    businessNameMap.putIfAbsent(view.getBusinessId(), cmsUser.getNickname());
                    view.setBusinessName(cmsUser.getNickname());
                });
            }
            Optional.ofNullable(userMapper.selectById(view.getUserId())).ifPresent(user -> view.setNickname(user.getNickname()));
        });
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 店铺关闭
     */
    @PutMapping("/update/status")
    public Result<String> updateShopStatus(@RequestBody YhShop yhShop) {
        Long id = yhShop.getId();
        YhShop dbShop = yhShopMapper.selectById(id);
        if (dbShop != null) {
            dbShop.setStatus(!dbShop.getStatus());
            dbShop.setRemark(yhShop.getRemark());
            yhShopMapper.updateById(dbShop);
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 设置店铺对应商务
     */
    @PutMapping("/set/business")
    public Result<String> setYhShopBusiness(@RequestBody YhShop yhShop) {
        cmsYhShopCommonService.setYhShopBusiness(yhShop);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 店铺提现记录详情
     */
    @GetMapping("/get/apply/detail/{shopUserId}")
    public Result<YhShopDistributeView> getYhShopApplyDetail(@PathVariable Long shopUserId) {
        YhShopDistributeView yhShopDistributeOrderView = yhShopMapper.getApplyDetailByUserId(shopUserId);
        return GatewayResponse.SUCCESS.newBuilder().toResult(yhShopDistributeOrderView);
    }

    /**
     * 设置店铺提成比例
     */
    @PutMapping("/set/rate")
    public Result<String> setYhShopGoodsRate(@RequestBody @Validated YhShopUserPlatDistributeRateReq req) {
        Long businessId = req.getBusinessId();
        YhShop yhShop = new YhShop();
        yhShop.setId(req.getId());
        yhShop.setBusinessId(businessId);
        yhShop.setRemark(req.getRemark());
        cmsYhShopCommonService.setYhShopBusiness(yhShop);
        List<YhShopUserPlatDistributeRate> yhShopUserPlatDistributeRates = req.getRates();
        if (CollUtil.isEmpty(yhShopUserPlatDistributeRates)) {
            throw BusinessRuntimeException.getInstance("请选择店铺用户对应平台比例");
        }
        cmsYhShopCommonService.setYhShopGoodsRate(yhShopUserPlatDistributeRates,yhShop.getBusinessId(), yhShop.getUserId());
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 店铺提成比例详情
     */
    @GetMapping("/get/detail/{userId}")
    public Result<List<YhShopUserPlatDistributeRate>> getDetailById(@PathVariable Long userId) {
        return GatewayResponse.SUCCESS.newBuilder().toResult(beanSearcher.searchAll(YhShopUserPlatDistributeRate.class, MapUtils.builder()
                .put("uid", String.format("and ydr.user_id = %s", userId))
                .orderBy(YhShopUserPlatDistributeRate::getGoodsId).asc()
                .build()));
    }

    /**
     * 店铺注册人数列表
     */
    @GetMapping("/get/register/detail/{shopUserId}")
    public Result<SearchResult<YhShopRegisterDetail>> getRegisterDetail(@PathVariable Long shopUserId) {
        SearchResult<YhShopRegisterDetail> search = beanSearcher.search(YhShopRegisterDetail.class, MapUtils.flatBuilder(request.getParameterMap())
                .field(YhShopRegisterDetail::getShopUserId, shopUserId)
                .build());
        search.getDataList().forEach(data -> {
            List<YhShopRegisterDistributeOrdersDetailView> ordersDetailViewList = beanSearcher.searchAll(YhShopRegisterDistributeOrdersDetailView.class, MapUtils.builder()
                    .field(YhShopRegisterDistributeOrdersDetailView::getShopUserId, shopUserId)
                    .field(YhShopRegisterDistributeOrdersDetailView::getUserId, data.getUserId())
                    .build());
            data.setOrderNums(ordersDetailViewList.size());
            Optional<BigDecimal> money = ordersDetailViewList.stream().filter(order -> {
                if (!Constant.noOrderAllStatus.contains(order.getStatus().name())) {
                    return true;
                }
                return false;
            }).map(YhShopRegisterDistributeOrdersDetailView::getMoney).reduce(BigDecimal::add);
            data.setMoney(money.isPresent() ? money.get() : BigDecimal.ZERO);
        });
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 店铺注册人数 订单详情
     */
    @GetMapping("/get/register/order/detail/{shopUserId}/{userId}")
    public Result<SearchResult<YhShopRegisterOrderDetail>> getRegisterOrderDetail(@PathVariable Long shopUserId, @PathVariable Long userId) {
        String condition = String.format("where ys.user_id = %s and o.user_id = %s", shopUserId, userId);
        SearchResult<YhShopRegisterOrderDetail> search = beanSearcher.search(YhShopRegisterOrderDetail.class, MapUtils.flatBuilder(request.getParameterMap())
                .put("condition", condition)
                .build());
        String nickname = StrUtil.EMPTY;
        for (YhShopRegisterOrderDetail data : search.getDataList()) {
            if (StrUtil.isEmpty(nickname)) {
                User user = userMapper.selectById(data.getUserId());
                nickname = user.getNickname();
                data.setNickname(nickname);
                continue;
            }
            data.setNickname(nickname);
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 店铺订单详情
     */
    @GetMapping("/get/order/detail/{shopUserId}")
    public Result<SearchResult<YhShopDistributeOrderView>> getOrderDetail(@PathVariable Long shopUserId) {
        SearchResult<YhShopDistributeOrderView> search = beanSearcher.search(YhShopDistributeOrderView.class, MapUtils.flatBuilder(request.getParameterMap())
                .put("suId", String.format("where shop_user_id = %s", shopUserId))
                .build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 商务人员列表 详情
     */
    @GetMapping("/get/business/list")
    public Result<SearchResult<YhShopDistributeBusinessView>> getDistributeBusinessView() {
        long adminId = StpUtil.getLoginIdAsLong();
        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
        DateTime beginOfMonth = DateUtil.beginOfMonth(DateTime.now());
        String thisMonth = beginOfMonth.toString("yyyy-MM");
        //是否是商务人员
        if (userBusinessRateService.isBusiness(adminId)) {
            builder.field(YhShopDistributeBusinessView::getBusinessId, adminId);
        }
        builder.put("time", String.format("date_format(ubr.order_created_time,'%%Y-%%m') = '%s'", thisMonth));
        SearchResult<YhShopDistributeBusinessView> search = beanSearcher.search(YhShopDistributeBusinessView.class, builder.build());
        search.getDataList().forEach(data -> {
            Number numOfRelation = beanSearcher.searchCount(YhShop.class, MapUtils.builder().field(YhShop::getBusinessId, data.getBusinessId()).build());
            data.setNumOfRelation(numOfRelation.intValue());
        });
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 商务人员提成详情
     */
    @GetMapping("/get/takeMoney/detail")
    public Result<SearchResult<YhShopBusinessTakeMoneyDetail>> getTakeMoneyDetail(String firstMonthDate, String secondMonthDate) {
        long adminId = StpUtil.getLoginIdAsLong();
        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
        //是否是商务人员
        if (userBusinessRateService.isBusiness(adminId)) {
            builder.field(YhShopBusinessTakeMoneyDetail::getBusinessId, adminId);
        }
        String timeSql = StringUtil.EMPTY;
        if (StrUtil.isNotBlank(firstMonthDate)) {
            timeSql += String.format("date_format(ubr.order_created_time,'%%Y-%%m') >= '%s'", firstMonthDate);
        }
        if (StrUtil.isNotBlank(secondMonthDate)) {
            timeSql += String.format("and date_format(ubr.order_created_time,'%%Y-%%m') <= '%s'", secondMonthDate);
        }
        if (StrUtil.isNotBlank(timeSql)) {
            builder.put("time", timeSql);
        }
        SearchResult<YhShopBusinessTakeMoneyDetail> search = beanSearcher.search(YhShopBusinessTakeMoneyDetail.class, builder.build());
        search.getDataList().forEach(data -> {
            User user = userMapper.selectById(data.getUserId());
            Optional.ofNullable(user).ifPresent(u -> {
                data.setNickname(u.getNickname());
                data.setCreatedTime(u.getCreatedTime());
            });
            CmsUser business = cmsUserMapper.selectById(data.getBusinessId());
            Optional.ofNullable(business).ifPresent(bs -> data.setBusinessName(bs.getNickname()));
        });
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 商务提成head
     */
    @GetMapping("/get/business/headData")
    public Result<YhShopBusinessTakeMoneyHeadView> getTakeMoneyHeadDetail(String firstMonthDate, String secondMonthDate) {
        long adminId = StpUtil.getLoginIdAsLong();
        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
        //是否是商务人员
        if (userBusinessRateService.isBusiness(adminId)) {
            builder.field(YhShopBusinessTakeMoneyHeadView::getBusinessId, adminId);
        }
        String timeSql = StringUtil.EMPTY;
        if (StrUtil.isNotBlank(firstMonthDate)) {
            timeSql += String.format("date_format(ubr.order_created_time,'%%Y-%%m') >= '%s'", firstMonthDate);
        }
        if (StrUtil.isNotBlank(secondMonthDate)) {
            timeSql += String.format("and date_format(ubr.order_created_time,'%%Y-%%m') <= '%s'", secondMonthDate);
        }
        if (StrUtil.isNotBlank(timeSql)) {
            builder.put("time", timeSql);
        }
        YhShopBusinessTakeMoneyHeadView headView = beanSearcher.searchFirst(YhShopBusinessTakeMoneyHeadView.class, builder.build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(headView);
    }

    /**
     * 店铺商务 数据列表
     */
    @GetMapping("/get/business/data")
    public Result<SearchResult<YhShopBusinessDistributesDataView>> getBusinessDistributesData(String startTime, String endTime) {
        long adminId = StpUtil.getLoginIdAsLong();
        MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
        String time1Sql = StrUtil.EMPTY;
        String time2Sql = StrUtil.EMPTY;
        String time3Sql = StrUtil.EMPTY;
        if (StrUtil.isNotBlank(startTime)) {
            time1Sql += String.format(" and ys.business_bind_time >= '%s'", startTime);
            time2Sql += String.format(" and us.created_time >= '%s'", startTime);
            time3Sql += String.format(" and od.created_time >= '%s'", startTime);
        }
        if (StrUtil.isNotBlank(endTime)) {
            time1Sql += String.format(" and ys.business_bind_time < '%s'", endTime);
            time2Sql += String.format(" and us.created_time < '%s'", endTime);
            time3Sql += String.format(" and od.created_time < '%s'", endTime);
        }
        if (StrUtil.isNotBlank(time1Sql)) {
            builder.put("time1", time1Sql);
        }
        if (StrUtil.isNotBlank(time2Sql)) {
            builder.put("time2", time2Sql);
        }
        if (StrUtil.isNotBlank(time3Sql)) {
            builder.put("time3", time3Sql);
        }
        //是否是商务人员
        if (userBusinessRateService.isBusiness(adminId)) {
            builder.field(YhShopBusinessDistributesDataView::getBusinessId, adminId);
        }
        SearchResult<YhShopBusinessDistributesDataView> search = beanSearcher.search(YhShopBusinessDistributesDataView.class, builder.build());
        search.getDataList().forEach(data -> {
            Optional.ofNullable(cmsUserMapper.selectById(data.getBusinessId()))
                    .ifPresent(cmsUser -> data.setBusinessName(cmsUser.getNickname()));

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

    /**
     * 店铺提现 列表
     */
    @GetMapping("/get/applyMoney")
    public Result<SearchResult<YhShopDistributeMoneyApplyView>> applyMoneyList() {
        SearchResult<YhShopDistributeMoneyApplyView> search = beanSearcher.search(YhShopDistributeMoneyApplyView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 店铺提现 审核
     */
    @PutMapping("/verify/applyMoney")
    @NoSubmit
    public Result<String> verifyApplyMoney(@RequestBody @Validated DistributeApplyMoneyReq distributeApplyMoneyReq) {
        cmsYhShopCommonService.verifyYhShopApplyMoney(distributeApplyMoneyReq);
        return GatewayResponse.SUCCESS.newBuilder().toResult("审核操作成功");
    }

    /**
     * 修改审核图片
     */
    @PutMapping("/verify/applyMoney/img")
    public Result<String> updateVerifyImg(@RequestBody DistributeApplyMoneyReq distributeApplyMoneyReq) {
        cmsYhShopCommonService.updateVerifyImg(distributeApplyMoneyReq);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }


    /**
     * 开店审核列表
     */
    @GetMapping("/get/apply")
    public Result<SearchResult<YhShopView>> getUserShopApply() {
        SearchResult<YhShopView> search = beanSearcher.search(YhShopView.class, MapUtils.flatBuilder(request.getParameterMap())
                .build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 一键审核
     */
    @PutMapping("/batch/verify")
    public Result<String> batchVerify(@RequestBody YhShopVerifyReq verifyReq) {
	    List<Long> ids = verifyReq.getIds();
	    if (CollUtil.isEmpty(ids)) {
		    throw BusinessRuntimeException.getInstance("请选择对应的审核记录");
	    }
	    ids.forEach(id -> {
		    verifyReq.setId(id);
		    cmsYhShopCommonService.verifyYhShopApply(verifyReq);
	    });
	    return GatewayResponse.SUCCESS.newBuilder().toResult();
    }


    /**
     * 店铺审核
     */
    @PutMapping("/verify")
    public Result<String> verifyYhShopApply(@RequestBody YhShopVerifyReq verifyReq) {
        cmsYhShopCommonService.verifyYhShopApply(verifyReq);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 店铺头部数据
     */
    @GetMapping("/get/head/data")
    public Result<BackgroundDataView> getHeadData(Long startTime, Long endTime) {
        BackgroundDataView backgroundDataView = new BackgroundDataView();
        Date startDate = null;
        Date endDate = null;
        if (startTime != null) {
            startDate = DateUtil.date(startTime);
        }
        if (endTime != null) {
            endDate = DateUtil.date(endTime);
        }
        //分销金额数据统计
        statisticsDataService.yhShopDistribute(backgroundDataView, startDate, endDate);
        return GatewayResponse.SUCCESS.newBuilder().toResult(backgroundDataView);
    }
}
