package com.greenorange.promotion.controller.userInfo;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.greenorange.promotion.annotation.RequiresPermission;
import com.greenorange.promotion.common.BaseResponse;
import com.greenorange.promotion.common.ResultUtils;
import com.greenorange.promotion.constant.CommonConstant;
import com.greenorange.promotion.constant.OrderStatusConstant;
import com.greenorange.promotion.constant.SystemConstant;
import com.greenorange.promotion.constant.UserConstant;
import com.greenorange.promotion.model.dto.userPerformanceSummary.*;
import com.greenorange.promotion.model.entity.*;
import com.greenorange.promotion.model.enums.CommissionStatusEnum;
import com.greenorange.promotion.model.enums.UserRoleEnum;
import com.greenorange.promotion.model.vo.courseOrder.CourseOrderDetailInfoVO;
import com.greenorange.promotion.model.vo.dashboard.WebQueryDashboardVO;
import com.greenorange.promotion.model.vo.userPerformanceSummary.SupervisorPerformanceSummaryVO;
import com.greenorange.promotion.model.vo.userPerformanceSummary.UserPerformanceSummaryDetailVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.course.CourseOrderService;
import com.greenorange.promotion.service.course.CoursePromotionCommissionPendingService;
import com.greenorange.promotion.service.userInfo.EmployeePromotionRecordsService;
import com.greenorange.promotion.service.userInfo.UserInfoService;
import com.greenorange.promotion.service.userInfo.UserPerformanceSummaryService;
import com.greenorange.promotion.utils.SqlUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 用户绩效汇总 控制器
 */
@RestController
@RequestMapping("perform")
@Slf4j
@Tag(name = "用户绩效汇总模块")
@Transactional
public class UserPerformanceSummaryController {

    @Resource
    private UserPerformanceSummaryService userPerformanceSummaryService;


    @Resource
    private CommonService commonService;


    @Resource
    private UserInfoService userInfoService;


    @Resource
    private CourseOrderService courseOrderService;


    @Resource
    private EmployeePromotionRecordsService employeePromotionRecordsService;


    @Resource
    private CoursePromotionCommissionPendingService coursePromotionCommissionPendingService;



    /**
     * Web端仪表盘
     * @return 用户绩效汇总
     */
    @PostMapping("query/dashboard")
    @Operation(summary = "Web端仪表盘", description = "参数：无，权限：管理员，方法名：webQueryDashboard")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<WebQueryDashboardVO> webQueryDashboard() {
        WebQueryDashboardVO webQueryDashboardVO = userPerformanceSummaryService.queryManagerDashboard();
        return ResultUtils.success(webQueryDashboardVO);
    }




    /**
     * Web端管理员分页查询主管绩效汇总
     * @param userPerformanceSummarySupervisorQueryRequest 主管绩效汇总查询请求体
     * @return 用户绩效汇总列表
     */
    @PostMapping("supervisor/page")
    @Operation(summary = "Web端管理员分页查询主管绩效汇总", description = "参数：主管绩效汇总查询请求体，权限：管理员，方法名：listSupervisorPerformanceSummaryByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<UserPerformanceSummaryDetailVO>> listSupervisorPerformanceSummaryByPage(@Valid @RequestBody UserPerformanceSummarySupervisorQueryRequest userPerformanceSummarySupervisorQueryRequest) {
        long current = userPerformanceSummarySupervisorQueryRequest.getCurrent();
        long pageSize = userPerformanceSummarySupervisorQueryRequest.getPageSize();
        String nickName = userPerformanceSummarySupervisorQueryRequest.getNickName();
        String phoneNumber = userPerformanceSummarySupervisorQueryRequest.getPhoneNumber();
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(nickName), UserInfo::getNickName, nickName);
        queryWrapper.eq(StringUtils.isNotBlank(phoneNumber), UserInfo::getPhoneNumber, phoneNumber);
        queryWrapper.eq(UserInfo::getUserRole, UserConstant.SUPERVISOR_ROLE);
        queryWrapper.select(UserInfo::getId, UserInfo::getNickName, UserInfo::getPhoneNumber);
        List<UserInfo> userInfoList = userInfoService.list(queryWrapper);
        List<Long> ids = userInfoList.stream().map(UserInfo::getId).collect(Collectors.toList());
        if (ids.isEmpty()) ids.add(-10L);

        QueryWrapper<UserPerformanceSummary> userPerformanceSummaryQueryWrapper = userPerformanceSummaryService.getQueryWrapper(userPerformanceSummarySupervisorQueryRequest);
        userPerformanceSummaryQueryWrapper.in("userId", ids);
        Page<UserPerformanceSummary> page = userPerformanceSummaryService.page(new Page<>(current, pageSize), userPerformanceSummaryQueryWrapper);
        List<UserPerformanceSummary> userPerformanceSummaryList = page.getRecords();
        List<UserPerformanceSummaryDetailVO> userPerformanceSummaryDetailVOS = commonService.convertList(userPerformanceSummaryList, UserPerformanceSummaryDetailVO.class);

        // 查询抽成比例
        RakeRewardsQueryRequest rakeRewardsQueryRequest = new RakeRewardsQueryRequest();
        rakeRewardsQueryRequest.setLevel("first");
        BigDecimal rewardsRate = userPerformanceSummaryService.queryRakeRewardsRateByLevel(rakeRewardsQueryRequest);

        // 封装Map集合（键:用户id, 值：用户信息）
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) userInfoMap.put(userInfo.getId(), userInfo);
        for (UserPerformanceSummaryDetailVO userPerformanceSummaryDetailVO : userPerformanceSummaryDetailVOS) {
            UserInfo userInfo = userInfoMap.get(userPerformanceSummaryDetailVO.getUserId());
            userPerformanceSummaryDetailVO.setNickName(userInfo.getNickName());
            userPerformanceSummaryDetailVO.setPhoneNumber(userInfo.getPhoneNumber());
            userPerformanceSummaryDetailVO.setRakeRewardsRate(rewardsRate);
        }

        Page<UserPerformanceSummaryDetailVO> voPage = new Page<>(current, pageSize);
        voPage.setRecords(userPerformanceSummaryDetailVOS);
        voPage.setPages(page.getPages());
        voPage.setTotal(page.getTotal());
        return ResultUtils.success(voPage);
    }



    /**
     * Web端管理员根据主管id分页查询员工绩效汇总
     * @param userPerformanceSummaryQueryRequest 员工绩效汇总查询请求体
     * @return 用户绩效汇总列表
     */
    @PostMapping("staff/page")
    @Operation(summary = "Web端管理员根据主管id分页查询员工绩效汇总", description = "参数：员工绩效汇总查询请求体，权限：管理员，方法名：listStaffPerformanceSummaryByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<UserPerformanceSummaryDetailVO>> listStaffPerformanceSummaryByPage(@Valid @RequestBody UserPerformanceSummaryStaffQueryRequest userPerformanceSummaryQueryRequest) {
        long current = userPerformanceSummaryQueryRequest.getCurrent();
        long pageSize = userPerformanceSummaryQueryRequest.getPageSize();
        String nickName = userPerformanceSummaryQueryRequest.getNickName();
        String phoneNumber = userPerformanceSummaryQueryRequest.getPhoneNumber();
        Long supervisorUserId = userPerformanceSummaryQueryRequest.getSupervisorUserId();

        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(nickName), UserInfo::getNickName, nickName);
        queryWrapper.eq(StringUtils.isNotBlank(phoneNumber), UserInfo::getPhoneNumber, phoneNumber);
        queryWrapper.eq(UserInfo::getParentUserId, supervisorUserId);
        queryWrapper.select(UserInfo::getId, UserInfo::getNickName, UserInfo::getPhoneNumber);
        List<UserInfo> userInfoList = userInfoService.list(queryWrapper);
        List<Long> ids = userInfoList.stream().map(UserInfo::getId).collect(Collectors.toList());
        if (ids.isEmpty()) ids.add(-10L);

        QueryWrapper<UserPerformanceSummary> userPerformanceSummaryQueryWrapper = userPerformanceSummaryService.getQueryWrapper(userPerformanceSummaryQueryRequest);
        userPerformanceSummaryQueryWrapper.in("userId", ids);
        Page<UserPerformanceSummary> page = userPerformanceSummaryService.page(new Page<>(current, pageSize), userPerformanceSummaryQueryWrapper);
        List<UserPerformanceSummary> userPerformanceSummaryList = page.getRecords();
        List<UserPerformanceSummaryDetailVO> userPerformanceSummaryDetailVOS = commonService.convertList(userPerformanceSummaryList, UserPerformanceSummaryDetailVO.class);

        // 查询抽成比例
        RakeRewardsQueryRequest rakeRewardsQueryRequest = new RakeRewardsQueryRequest();
        rakeRewardsQueryRequest.setLevel("second");
        BigDecimal rewardsRate = userPerformanceSummaryService.queryRakeRewardsRateByLevel(rakeRewardsQueryRequest);

        // 封装Map集合（键:用户id, 值：用户信息）
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) userInfoMap.put(userInfo.getId(), userInfo);
        for (UserPerformanceSummaryDetailVO userPerformanceSummaryDetailVO : userPerformanceSummaryDetailVOS) {
            UserInfo userInfo = userInfoMap.get(userPerformanceSummaryDetailVO.getUserId());
            userPerformanceSummaryDetailVO.setNickName(userInfo.getNickName());
            userPerformanceSummaryDetailVO.setPhoneNumber(userInfo.getPhoneNumber());
            userPerformanceSummaryDetailVO.setRakeRewardsRate(rewardsRate);
        }

        Page<UserPerformanceSummaryDetailVO> voPage = new Page<>(current, pageSize);
        voPage.setRecords(userPerformanceSummaryDetailVOS);
        voPage.setPages(page.getPages());
        voPage.setTotal(page.getTotal());
        return ResultUtils.success(voPage);
    }


    /**
     * Web端管理员根据员工id分页查询客户订单汇总
     * @param userPerformanceSummaryQueryRequest 员工绩效汇总查询请求体
     * @return 用户绩效汇总列表
     */
    @PostMapping("user/page")
    @Operation(summary = "Web端管理员根据员工id分页查询客户订单汇总", description = "参数：用户绩效汇总查询请求体，权限：管理员，方法名：listUserPerformanceSummaryByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<CourseOrderDetailInfoVO>> listUserPerformanceSummaryByPage(@Valid @RequestBody UserCourseOrderQueryRequest userPerformanceSummaryQueryRequest) {
        long current = userPerformanceSummaryQueryRequest.getCurrent();
        long pageSize = userPerformanceSummaryQueryRequest.getPageSize();
        Long staffUserId = userPerformanceSummaryQueryRequest.getStaffUserId();

        QueryWrapper<CourseOrder> courseOrderQueryWrapper = userPerformanceSummaryService.getCourseOrderQueryWrapper(userPerformanceSummaryQueryRequest);
        courseOrderQueryWrapper.in("orderStatus", OrderStatusConstant.SUCCESS, OrderStatusConstant.REFUNDED);

        List<Long> ids = userInfoService.findAllSubUser(staffUserId);

        List<UserInfo> userInfoList = commonService.findByFieldInTargetFieldWithSpecificFields(ids, userInfoService, Function.identity(), UserInfo::getId,
                List.of(UserInfo::getId, UserInfo::getNickName, UserInfo::getPhoneNumber));

        courseOrderQueryWrapper.in("userId", ids);
        Page<CourseOrder> page = courseOrderService.page(new Page<>(current, pageSize), courseOrderQueryWrapper);
        List<CourseOrder> courseOrderList = page.getRecords();
        List<CourseOrderDetailInfoVO> courseOrderDetailInfoVOS = commonService.convertList(courseOrderList, CourseOrderDetailInfoVO.class);

        // 封装Map集合（键:用户id, 值：用户信息）
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) userInfoMap.put(userInfo.getId(), userInfo);
        for (CourseOrderDetailInfoVO courseOrderBaseInfoVOS : courseOrderDetailInfoVOS) {
            UserInfo userInfo = userInfoMap.get(courseOrderBaseInfoVOS.getUserId());
            courseOrderBaseInfoVOS.setNickName(userInfo.getNickName());
            courseOrderBaseInfoVOS.setPhoneNumber(userInfo.getPhoneNumber());
        }

        List<CoursePromotionCommissionPending> coursePromotionCommissionPendingList = commonService.findByFieldInTargetFieldWithSpecificFields(
                courseOrderList, coursePromotionCommissionPendingService, CourseOrder::getId, CoursePromotionCommissionPending::getOrderId,
                List.of(CoursePromotionCommissionPending::getFirstRate, CoursePromotionCommissionPending::getSecondRate, CoursePromotionCommissionPending::getFirstReward,
                        CoursePromotionCommissionPending::getSecondReward, CoursePromotionCommissionPending::getCommissionStatus, CoursePromotionCommissionPending::getOrderId));

        // 封装Map集合（键：用户id, 值：课程推广待提成记录）
        Map<Long, CoursePromotionCommissionPending> coursePromotionCommissionPendingMap = new HashMap<>();
        for (CoursePromotionCommissionPending coursePromotionCommissionPending : coursePromotionCommissionPendingList) coursePromotionCommissionPendingMap.put(coursePromotionCommissionPending.getOrderId(), coursePromotionCommissionPending);
        for (CourseOrderDetailInfoVO courseOrderDetailInfoVO : courseOrderDetailInfoVOS) {
            Long orderId = courseOrderDetailInfoVO.getId();
            CoursePromotionCommissionPending coursePromotionCommissionPending = coursePromotionCommissionPendingMap.get(orderId);
            courseOrderDetailInfoVO.setFirstRate(coursePromotionCommissionPending.getFirstRate());
            courseOrderDetailInfoVO.setSecondRate(coursePromotionCommissionPending.getSecondRate());
            courseOrderDetailInfoVO.setFirstReward(coursePromotionCommissionPending.getFirstReward());
            courseOrderDetailInfoVO.setSecondReward(coursePromotionCommissionPending.getSecondReward());
            courseOrderDetailInfoVO.setCommissionStatus(coursePromotionCommissionPending.getCommissionStatus());
        }

        Page<CourseOrderDetailInfoVO> voPage = new Page<>(current, pageSize);
        voPage.setRecords(courseOrderDetailInfoVOS);
        voPage.setPages(page.getPages());
        voPage.setTotal(page.getTotal());
        return ResultUtils.success(voPage);
    }



    /**
     * Web端管理员分页查询主管绩效排名
     * @param userPerformanceSummaryRankQueryRequest 绩效排名查询请求体
     * @return 用户绩效汇总列表
     */
    @PostMapping("rank/supervisor/page")
    @Operation(summary = "Web端管理员分页查询主管绩效排名", description = "参数：绩效排名查询请求体，权限：管理员，方法名：listSupervisorPerformanceSummaryRankingsByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<SupervisorPerformanceSummaryVO>> listSupervisorPerformanceSummaryRankingsByPage(@Valid @RequestBody UserPerformanceSummaryRankQueryRequest userPerformanceSummaryRankQueryRequest) {
        String startTimeStr = userPerformanceSummaryRankQueryRequest.getStartDate();
        String endTimeStr = userPerformanceSummaryRankQueryRequest.getEndDate();
        String nickName = userPerformanceSummaryRankQueryRequest.getNickName();
        String phoneNumber = userPerformanceSummaryRankQueryRequest.getPhoneNumber();
        DateTime startDate = null;
        DateTime endDate = null;
        boolean isAddDate = true;
        try {
            startDate = DateUtil.parse(startTimeStr, "yyyy-MM-dd HH:mm:ss");
            endDate = DateUtil.parse(endTimeStr, "yyyy-MM-dd HH:mm:ss");
        } catch (Exception e) {
            isAddDate = false;
        }

        LambdaQueryWrapper<EmployeePromotionRecords> empQueryWrapper = new LambdaQueryWrapper<>();
        if (isAddDate) {
            empQueryWrapper.ge(StringUtils.isNotBlank(startTimeStr), EmployeePromotionRecords::getCreateTime, startDate);
            empQueryWrapper.le(StringUtils.isNotBlank(endTimeStr), EmployeePromotionRecords::getCreateTime, endDate);
        }
        empQueryWrapper.select(EmployeePromotionRecords::getFirstUserId);
        List<EmployeePromotionRecords> employeePromotionRecordsList = employeePromotionRecordsService.list(empQueryWrapper);
        // 封装Map集合（键：主管id, 值：推广数量）
        Map<Long, Integer> supervisorCntMap = new HashMap<>();
        for (EmployeePromotionRecords employeePromotionRecords : employeePromotionRecordsList) {
            Long firstUserId = employeePromotionRecords.getFirstUserId();
            supervisorCntMap.merge(firstUserId, 1, Integer::sum);
        }

        // 封装Map集合（键：主管id, 值：下单数量）
        Map<Long, Integer> supervisorOrderCntMap = new HashMap<>();
        // 封装Map集合（键：主管id, 值：下单金额）
        Map<Long, BigDecimal> supervisorOrderAmountMap = new HashMap<>();
        // 封装Map集合（键：主管id, 值：净成交金额）
        Map<Long, BigDecimal> supervisorNetSalesAmountMap = new HashMap<>();
        LambdaQueryWrapper<CoursePromotionCommissionPending> coursePromotionQueryWrapper = new LambdaQueryWrapper<>();
        coursePromotionQueryWrapper.ge(StringUtils.isNotBlank(startTimeStr), CoursePromotionCommissionPending::getOrderCreateTime, startDate);
        coursePromotionQueryWrapper.le(StringUtils.isNotBlank(endTimeStr), CoursePromotionCommissionPending::getOrderCreateTime, endDate);
        coursePromotionQueryWrapper.select(CoursePromotionCommissionPending::getFirstUserId, CoursePromotionCommissionPending::getTotalAmount,
                CoursePromotionCommissionPending::getUpdateTime, CoursePromotionCommissionPending::getCommissionStatus);
        List<CoursePromotionCommissionPending> coursePromotionCommissionPendingList = coursePromotionCommissionPendingService.list(coursePromotionQueryWrapper);
        for (CoursePromotionCommissionPending coursePromotionCommissionPending : coursePromotionCommissionPendingList) {
            Long firstUserId = coursePromotionCommissionPending.getFirstUserId();
            BigDecimal totalAmount = coursePromotionCommissionPending.getTotalAmount();
            DateTime updateDate  = DateUtil.date(coursePromotionCommissionPending.getUpdateTime());
            String commissionStatus = coursePromotionCommissionPending.getCommissionStatus();
            CommissionStatusEnum commissionStatusEnum = CommissionStatusEnum.getEnumByValue(commissionStatus);
            supervisorOrderCntMap.merge(firstUserId, 1, Integer::sum);
            BigDecimal totalAmountTemp = totalAmount;
            if (CommissionStatusEnum.EXPIRED.equals(commissionStatusEnum)) {
                totalAmountTemp = totalAmount.multiply(SystemConstant.FEE_RATE);
            }
            supervisorOrderAmountMap.merge(firstUserId, totalAmountTemp, BigDecimal::add);

            if (startDate != null && endDate != null) {
                if (!(CommissionStatusEnum.COMPLETED.equals(commissionStatusEnum) && updateDate.isAfterOrEquals(startDate) && updateDate.isBeforeOrEquals(endDate))) {
                    totalAmount = totalAmount.multiply(SystemConstant.FEE_RATE);
                }
            } else {
                if (!CommissionStatusEnum.COMPLETED.equals(commissionStatusEnum)) {
                    totalAmount = totalAmount.multiply(SystemConstant.FEE_RATE);
                }
            }
            supervisorNetSalesAmountMap.merge(firstUserId, totalAmount, BigDecimal::add);
        }
        LambdaQueryWrapper<UserInfo> userInfoQueryWrapper = new LambdaQueryWrapper<>();
        userInfoQueryWrapper.eq(StringUtils.isNotBlank(nickName), UserInfo::getNickName, nickName)
                            .eq(StringUtils.isNotBlank(phoneNumber), UserInfo::getPhoneNumber, phoneNumber)
                            .eq(UserInfo::getUserRole, UserConstant.SUPERVISOR_ROLE);
        userInfoQueryWrapper.select(UserInfo::getId, UserInfo::getNickName, UserInfo::getPhoneNumber);
        List<UserInfo> userInfoList = userInfoService.list(userInfoQueryWrapper);
        List<UserPerformanceSummary> userPerformanceSummaryList = commonService.findByFieldInTargetFieldWithSpecificFields(
                userInfoList, userPerformanceSummaryService, UserInfo::getId, UserPerformanceSummary::getUserId,
                List.of(UserPerformanceSummary::getUserId, UserPerformanceSummary::getEmpCount));

        // 封装Map集合（键：主管id, 用户信息）
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) {
            userInfoMap.put(userInfo.getId(), userInfo);
        }

        // 封装主管绩效排名列表
        List<SupervisorPerformanceSummaryVO> supervisorPerformanceSummaryVOS = new ArrayList<>();
        for (UserPerformanceSummary userPerformanceSummary : userPerformanceSummaryList) {
            Long userId = userPerformanceSummary.getUserId();
            UserInfo userInfo = userInfoMap.get(userId);
            SupervisorPerformanceSummaryVO supervisorPerformanceSummaryVO = SupervisorPerformanceSummaryVO.builder()
                    .nickName(userInfo.getNickName())
                    .phoneNumber(userInfo.getPhoneNumber())
                    .empCount(userPerformanceSummary.getEmpCount())
                    .orderCount(supervisorOrderCntMap.get(userId) == null ? 0 : supervisorOrderCntMap.get(userId))
                    .totalAmount(supervisorOrderAmountMap.get(userId) == null ? BigDecimal.ZERO : supervisorOrderAmountMap.get(userId))
                    .netAmount(supervisorNetSalesAmountMap.get(userId) == null ? BigDecimal.ZERO : supervisorNetSalesAmountMap.get(userId))
                    .promoCount(supervisorCntMap.get(userId) == null ? 0 : supervisorCntMap.get(userId))
                    .build();
            supervisorPerformanceSummaryVOS.add(supervisorPerformanceSummaryVO);
        }
        Page<SupervisorPerformanceSummaryVO> supervisorPerformanceSummaryVOPage = userPerformanceSummaryService.queryPage(userPerformanceSummaryRankQueryRequest, supervisorPerformanceSummaryVOS);
        return ResultUtils.success(supervisorPerformanceSummaryVOPage);
    }



    /**
     * Web端管理员分页查询员工绩效排名
     * @param userPerformanceSummaryRankQueryRequest 绩效排名查询请求体
     * @return 用户绩效汇总列表
     */
    @PostMapping("rank/staff/page")
    @Operation(summary = "Web端管理员分页查询员工绩效排名", description = "参数：绩效排名查询请求体，权限：管理员，方法名：listStaffUserPerformanceSummaryRankingsByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<SupervisorPerformanceSummaryVO>> listStaffUserPerformanceSummaryRankingsByPage(@Valid @RequestBody UserPerformanceSummaryRankQueryRequest userPerformanceSummaryRankQueryRequest) {
        String startTimeStr = userPerformanceSummaryRankQueryRequest.getStartDate();
        String endTimeStr = userPerformanceSummaryRankQueryRequest.getEndDate();
        String nickName = userPerformanceSummaryRankQueryRequest.getNickName();
        String phoneNumber = userPerformanceSummaryRankQueryRequest.getPhoneNumber();
        DateTime startDate = null;
        DateTime endDate = null;
        boolean isAddDate = true;
        try {
            startDate = DateUtil.parse(startTimeStr, "yyyy-MM-dd HH:mm:ss");
            endDate = DateUtil.parse(endTimeStr, "yyyy-MM-dd HH:mm:ss");
        } catch (Exception e) {
            isAddDate = false;
        }
        LambdaQueryWrapper<EmployeePromotionRecords> empQueryWrapper = new LambdaQueryWrapper<>();
        if (isAddDate) {
            empQueryWrapper.ge(StringUtils.isNotBlank(startTimeStr), EmployeePromotionRecords::getCreateTime, startDate);
            empQueryWrapper.le(StringUtils.isNotBlank(endTimeStr), EmployeePromotionRecords::getCreateTime, endDate);
        }
        empQueryWrapper.select(EmployeePromotionRecords::getSecondUserId);
        List<EmployeePromotionRecords> employeePromotionRecordsList = employeePromotionRecordsService.list(empQueryWrapper);
        // 封装Map集合（键：员工id, 值：推广数量）
        Map<Long, Integer> staffCntMap = new HashMap<>();
        for (EmployeePromotionRecords employeePromotionRecords : employeePromotionRecordsList) {
            Long secondUserId = employeePromotionRecords.getSecondUserId();
            staffCntMap.merge(secondUserId, 1, Integer::sum);
        }

        // 封装Map集合（键：员工id, 值：下单数量）
        Map<Long, Integer> staffOrderCntMap = new HashMap<>();
        // 封装Map集合（键：员工id, 值：下单金额）
        Map<Long, BigDecimal> staffOrderAmountMap = new HashMap<>();
        // 封装Map集合（键：员工id, 值：净成交金额）
        Map<Long, BigDecimal> staffNetSalesAmountMap = new HashMap<>();
        LambdaQueryWrapper<CoursePromotionCommissionPending> coursePromotionQueryWrapper = new LambdaQueryWrapper<>();
        coursePromotionQueryWrapper.ge(StringUtils.isNotBlank(startTimeStr), CoursePromotionCommissionPending::getOrderCreateTime, startDate);
        coursePromotionQueryWrapper.le(StringUtils.isNotBlank(endTimeStr), CoursePromotionCommissionPending::getCreateTime, endDate);
        coursePromotionQueryWrapper.select(CoursePromotionCommissionPending::getSecondUserId, CoursePromotionCommissionPending::getTotalAmount,
                CoursePromotionCommissionPending::getUpdateTime, CoursePromotionCommissionPending::getCommissionStatus);
        List<CoursePromotionCommissionPending> coursePromotionCommissionPendingList = coursePromotionCommissionPendingService.list(coursePromotionQueryWrapper);
        for (CoursePromotionCommissionPending coursePromotionCommissionPending : coursePromotionCommissionPendingList) {
            Long secondUserId = coursePromotionCommissionPending.getSecondUserId();
            BigDecimal totalAmount = coursePromotionCommissionPending.getTotalAmount();
            DateTime updateDate  = DateUtil.date(coursePromotionCommissionPending.getUpdateTime());
            String commissionStatus = coursePromotionCommissionPending.getCommissionStatus();
            CommissionStatusEnum commissionStatusEnum = CommissionStatusEnum.getEnumByValue(commissionStatus);
            staffOrderCntMap.merge(secondUserId, 1, Integer::sum);
            BigDecimal totalAmountTemp = totalAmount;
            if (CommissionStatusEnum.EXPIRED.equals(commissionStatusEnum)) {
                totalAmountTemp = totalAmount.multiply(SystemConstant.FEE_RATE);
            }
            staffOrderAmountMap.merge(secondUserId, totalAmountTemp, BigDecimal::add);

            if (startDate != null && endDate != null) {
                if (!(CommissionStatusEnum.COMPLETED.equals(commissionStatusEnum) && updateDate.isAfterOrEquals(startDate) && updateDate.isBeforeOrEquals(endDate))) {
                    totalAmount = totalAmount.multiply(SystemConstant.FEE_RATE);
                }
            } else {
                if (!CommissionStatusEnum.COMPLETED.equals(commissionStatusEnum)) {
                    totalAmount = totalAmount.multiply(SystemConstant.FEE_RATE);
                }
            }
            staffNetSalesAmountMap.merge(secondUserId, totalAmount, BigDecimal::add);
        }
        LambdaQueryWrapper<UserInfo> userInfoQueryWrapper = new LambdaQueryWrapper<>();
        userInfoQueryWrapper.eq(StringUtils.isNotBlank(nickName), UserInfo::getNickName, nickName)
                .eq(StringUtils.isNotBlank(phoneNumber), UserInfo::getPhoneNumber, phoneNumber)
                .eq(UserInfo::getUserRole, UserConstant.STAFF_ROLE);
        userInfoQueryWrapper.select(UserInfo::getId, UserInfo::getNickName, UserInfo::getPhoneNumber);
        List<UserInfo> userInfoList = userInfoService.list(userInfoQueryWrapper);
        List<UserPerformanceSummary> userPerformanceSummaryList = commonService.findByFieldInTargetFieldWithSpecificFields(
                userInfoList, userPerformanceSummaryService, UserInfo::getId, UserPerformanceSummary::getUserId,
                List.of(UserPerformanceSummary::getUserId, UserPerformanceSummary::getEmpCount));
        // 封装Map集合（键：主管id, 用户信息）
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) {
            userInfoMap.put(userInfo.getId(), userInfo);
        }

        // 封装主管绩效排名列表
        List<SupervisorPerformanceSummaryVO> supervisorPerformanceSummaryVOS = new ArrayList<>();
        for (UserPerformanceSummary userPerformanceSummary : userPerformanceSummaryList) {
            Long userId = userPerformanceSummary.getUserId();
            UserInfo userInfo = userInfoMap.get(userId);
            SupervisorPerformanceSummaryVO supervisorPerformanceSummaryVO = SupervisorPerformanceSummaryVO.builder()
                    .nickName(userInfo.getNickName())
                    .phoneNumber(userInfo.getPhoneNumber())
                    .empCount(userPerformanceSummary.getEmpCount())
                    .orderCount(staffOrderCntMap.get(userId) == null ? 0 : staffOrderCntMap.get(userId))
                    .totalAmount(staffOrderAmountMap.get(userId) == null ? BigDecimal.ZERO : staffOrderAmountMap.get(userId))
                    .netAmount(staffNetSalesAmountMap.get(userId) == null ? BigDecimal.ZERO : staffNetSalesAmountMap.get(userId))
                    .promoCount(staffCntMap.get(userId) == null ? 0 : staffCntMap.get(userId))
                    .build();
            supervisorPerformanceSummaryVOS.add(supervisorPerformanceSummaryVO);
        }
        Page<SupervisorPerformanceSummaryVO> supervisorPerformanceSummaryVOPage = userPerformanceSummaryService.queryPage(userPerformanceSummaryRankQueryRequest, supervisorPerformanceSummaryVOS);
        return ResultUtils.success(supervisorPerformanceSummaryVOPage);
    }



    /**
     * Web端管理员一键结算
     * @return 是否更新成功
     */
    @PostMapping("unite/settle")
    @Operation(summary = "Web端管理员一键结算", description = "参数：无，权限：管理员，方法名：oneClickBilling")
    @RequiresPermission(mustRole = UserConstant.BOSS_ROLE)
    public BaseResponse<Boolean> oneClickBilling() {
        List<UserPerformanceSummary> userPerformanceSummaryList = userPerformanceSummaryService.list();
        for (UserPerformanceSummary userPerformanceSummary : userPerformanceSummaryList) {
            userPerformanceSummary.setSettled(userPerformanceSummary.getSettled().add(userPerformanceSummary.getToSettle()));
            userPerformanceSummary.setToSettle(BigDecimal.ZERO);
        }
        userPerformanceSummaryService.updateBatchById(userPerformanceSummaryList);
        return ResultUtils.success(true);
    }



    /**
     * 轮询课程推广待提成记录表
     * cron 表达式：秒 分 时 日 月 周
     * 0 0 0 * * ?” = 每天 00:00:00 执行一次
     * @return 是否更新成功
     */
//    @Scheduled(cron = "0 0 0 * * ?")
    @Scheduled(cron = "00 16 20 * * ?")
    @Operation(summary = "轮询课程推广待提成记录表", description = "参数：无，权限：管理员，方法名：pollCourseOrder")
    public void pollCourseOrder() {
        // 找出下单时间超过7天的订单，分别统计主管和员工的可结算金额
        Map<Long, BigDecimal> toSettleMap  = new HashMap<>();
        Map<Long, BigDecimal> totalAmountMap = new HashMap<>();
        List<CoursePromotionCommissionPending> coursePromotionCommissionPendingList = commonService.findByFieldEqTargetField(CoursePromotionCommissionPending::getCommissionStatus, CommissionStatusEnum.PENDING.getValue(), coursePromotionCommissionPendingService);
        for (CoursePromotionCommissionPending coursePromotionCommissionPending : coursePromotionCommissionPendingList) {
            Date orderCreateTime = coursePromotionCommissionPending.getOrderCreateTime();
            Date now = DateUtil.date();
            // 计算两个时间相隔多少天（向下取整）
            long days = DateUtil.between(orderCreateTime, now, DateUnit.DAY);
            if (days >= 7) {
                coursePromotionCommissionPending.setCommissionStatus(CommissionStatusEnum.COMPLETED.getValue());
                toSettleMap.merge(coursePromotionCommissionPending.getFirstUserId(), coursePromotionCommissionPending.getFirstReward().multiply(SystemConstant.REFUND_RATE), BigDecimal::add);
                toSettleMap.merge(coursePromotionCommissionPending.getSecondUserId(), coursePromotionCommissionPending.getSecondReward().multiply(SystemConstant.REFUND_RATE), BigDecimal::add);
                totalAmountMap.merge(coursePromotionCommissionPending.getFirstUserId(), coursePromotionCommissionPending.getTotalAmount().multiply(SystemConstant.REFUND_RATE), BigDecimal::add);
                totalAmountMap.merge(coursePromotionCommissionPending.getSecondUserId(), coursePromotionCommissionPending.getTotalAmount().multiply(SystemConstant.REFUND_RATE), BigDecimal::add);
            }
        }
        coursePromotionCommissionPendingService.updateBatchById(coursePromotionCommissionPendingList);
        // 修改用户绩效汇总表
        List<UserPerformanceSummary> userPerformanceSummaryList = userPerformanceSummaryService.list();
        for (UserPerformanceSummary userPerformanceSummary : userPerformanceSummaryList) {
            Long userId = userPerformanceSummary.getUserId();
            BigDecimal toSettleAmount = toSettleMap.get(userId);
            BigDecimal totalAmount = totalAmountMap.get(userId);
            if (toSettleAmount != null) {
                userPerformanceSummary.setNetAmount(userPerformanceSummary.getNetAmount().add(totalAmount));
                userPerformanceSummary.setToRelease(userPerformanceSummary.getToRelease().subtract(toSettleAmount));
                userPerformanceSummary.setToSettle(userPerformanceSummary.getToSettle().add(toSettleAmount));
            }
        }
        userPerformanceSummaryService.updateBatchById(userPerformanceSummaryList);
    }







    /**
     * Web端管理员修改一、二级抽成比例
     * @param rakeRewardsUpdateRequest 抽成比例更新请求体
     * @return 是否更新成功
     */
    @PostMapping("update/rate")
    @Operation(summary = "Web端管理员修改一、二级抽成比例", description = "参数：抽成比例更新请求体，权限：管理员，方法名：updateRakeRewardsRate")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateRakeRewardsRate(@Valid @RequestBody RakeRewardsUpdateRequest rakeRewardsUpdateRequest) {
        userPerformanceSummaryService.updateRakeRewards(rakeRewardsUpdateRequest);
        return ResultUtils.success(true);
    }


    /**
     * Web端管理员查询一、二级抽成比例
     * @return 抽成比例对象
     */
    @PostMapping("query/rate")
    @Operation(summary = "Web端管理员查询一、二级抽成比例", description = "参数：无，权限：管理员，方法名：queryRakeRewardsRate")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Map<String, BigDecimal>> queryRakeRewardsRate() {
        Map<String, BigDecimal> rateMap = userPerformanceSummaryService.queryRakeRewardsRate();
        return ResultUtils.success(rateMap);
    }


    /**
     * Web端管理员根据级别查询抽佣比例
     * @param rakeRewardsQueryRequest 级别
     * @return 抽成比例
     */
    @PostMapping("query/level/rate")
    @Operation(summary = "Web端管理员根据级别查询抽佣比例", description = "参数：无，权限：管理员，方法名：queryRakeRewardsRateByLevel")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<BigDecimal> queryRakeRewardsRateByLevel(@Valid @RequestBody RakeRewardsQueryRequest rakeRewardsQueryRequest) {
        BigDecimal rate = userPerformanceSummaryService.queryRakeRewardsRateByLevel(rakeRewardsQueryRequest);
        return ResultUtils.success(rate);
    }








    /**
     * 小程序端经理查询主管绩效汇总
     * @param miniUserPerformanceSummaryQueryRequest 主管绩效汇总查询请求体
     * @return 用户绩效汇总列表
     */
    @PostMapping("query/supervisor")
    @Operation(summary = "小程序端经理查询主管绩效汇总", description = "参数：主管绩效汇总查询请求体，权限：管理员，方法名：miniListPerformanceSummary")
    @RequiresPermission(mustRole = UserConstant.MANAGER_ROLE)
    public BaseResponse<List<UserPerformanceSummaryDetailVO>> miniListPerformanceSummary(@Valid @RequestBody MiniUserPerformanceSummaryQueryRequest miniUserPerformanceSummaryQueryRequest) {
        String nickName = miniUserPerformanceSummaryQueryRequest.getNickName();
        String phoneNumber = miniUserPerformanceSummaryQueryRequest.getPhoneNumber();

        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(nickName), UserInfo::getNickName, nickName);
        queryWrapper.eq(StringUtils.isNotBlank(phoneNumber), UserInfo::getPhoneNumber, phoneNumber);
        queryWrapper.eq(UserInfo::getUserRole, UserConstant.SUPERVISOR_ROLE);
        queryWrapper.select(UserInfo::getId, UserInfo::getNickName, UserInfo::getPhoneNumber);
        List<UserInfo> userInfoList = userInfoService.list(queryWrapper);
        List<Long> ids = userInfoList.stream().map(UserInfo::getId).collect(Collectors.toList());
        if (ids.isEmpty()) ids.add(-10L);

        LambdaQueryWrapper<UserPerformanceSummary> userPerformanceSummaryQueryWrapper = new LambdaQueryWrapper<>();
        userPerformanceSummaryQueryWrapper.in(UserPerformanceSummary::getUserId, ids);
        List<UserPerformanceSummary> userPerformanceSummaryList = userPerformanceSummaryService.list(userPerformanceSummaryQueryWrapper);
        List<UserPerformanceSummaryDetailVO> userPerformanceSummaryDetailVOS = commonService.convertList(userPerformanceSummaryList, UserPerformanceSummaryDetailVO.class);

        // 查询抽成比例
        RakeRewardsQueryRequest rakeRewardsQueryRequest = new RakeRewardsQueryRequest();
        rakeRewardsQueryRequest.setLevel("first");
        BigDecimal rewardsRate = userPerformanceSummaryService.queryRakeRewardsRateByLevel(rakeRewardsQueryRequest);

        // 封装Map集合（键:用户id, 值：用户信息）
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) userInfoMap.put(userInfo.getId(), userInfo);
        for (UserPerformanceSummaryDetailVO userPerformanceSummaryDetailVO : userPerformanceSummaryDetailVOS) {
            UserInfo userInfo = userInfoMap.get(userPerformanceSummaryDetailVO.getUserId());
            userPerformanceSummaryDetailVO.setNickName(userInfo.getNickName());
            userPerformanceSummaryDetailVO.setPhoneNumber(userInfo.getPhoneNumber());
            userPerformanceSummaryDetailVO.setRakeRewardsRate(rewardsRate);
        }
        return ResultUtils.success(userPerformanceSummaryDetailVOS);
    }


    /**
     * 小程序端主管查询员工绩效汇总
     * @param miniUserPerformanceSummaryStaffQueryRequest 员工绩效汇总查询请求体
     * @return 用户绩效汇总列表
     */
    @PostMapping("query/staff")
    @Operation(summary = "小程序端主管查询员工绩效汇总", description = "参数：员工绩效汇总查询请求体，权限：管理员，方法名：miniListStaffPerformanceSummary")
    @RequiresPermission(mustRole = UserConstant.SUPERVISOR_ROLE)
    public BaseResponse<List<UserPerformanceSummaryDetailVO>> miniListStaffPerformanceSummary(@Valid @RequestBody MiniUserPerformanceSummaryStaffQueryRequest miniUserPerformanceSummaryStaffQueryRequest) {
        String nickName = miniUserPerformanceSummaryStaffQueryRequest.getNickName();
        String phoneNumber = miniUserPerformanceSummaryStaffQueryRequest.getPhoneNumber();
        Long supervisorUserId = miniUserPerformanceSummaryStaffQueryRequest.getSupervisorUserId();

        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(nickName), UserInfo::getNickName, nickName);
        queryWrapper.eq(StringUtils.isNotBlank(phoneNumber), UserInfo::getPhoneNumber, phoneNumber);
        queryWrapper.eq(UserInfo::getParentUserId, supervisorUserId);
        queryWrapper.select(UserInfo::getId, UserInfo::getNickName, UserInfo::getPhoneNumber);
        List<UserInfo> userInfoList = userInfoService.list(queryWrapper);
        List<Long> ids = userInfoList.stream().map(UserInfo::getId).collect(Collectors.toList());
        if (ids.isEmpty()) ids.add(-10L);

        LambdaQueryWrapper<UserPerformanceSummary> userPerformanceSummaryQueryWrapper = new LambdaQueryWrapper<>();
        userPerformanceSummaryQueryWrapper.in(UserPerformanceSummary::getUserId, ids);
        List<UserPerformanceSummary> userPerformanceSummaryList = userPerformanceSummaryService.list(userPerformanceSummaryQueryWrapper);
        List<UserPerformanceSummaryDetailVO> userPerformanceSummaryDetailVOS = commonService.convertList(userPerformanceSummaryList, UserPerformanceSummaryDetailVO.class);

        // 查询抽成比例
        RakeRewardsQueryRequest rakeRewardsQueryRequest = new RakeRewardsQueryRequest();
        rakeRewardsQueryRequest.setLevel("second");
        BigDecimal rewardsRate = userPerformanceSummaryService.queryRakeRewardsRateByLevel(rakeRewardsQueryRequest);

        // 封装Map集合（键:用户id, 值：用户信息）
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) userInfoMap.put(userInfo.getId(), userInfo);
        for (UserPerformanceSummaryDetailVO userPerformanceSummaryDetailVO : userPerformanceSummaryDetailVOS) {
            UserInfo userInfo = userInfoMap.get(userPerformanceSummaryDetailVO.getUserId());
            userPerformanceSummaryDetailVO.setNickName(userInfo.getNickName());
            userPerformanceSummaryDetailVO.setPhoneNumber(userInfo.getPhoneNumber());
            userPerformanceSummaryDetailVO.setRakeRewardsRate(rewardsRate);
        }
        return ResultUtils.success(userPerformanceSummaryDetailVOS);
    }


    /**
     * 小程序端员工查询客户下单汇总
     * @param miniUserCourseOrderQueryRequest 员工绩效汇总查询请求体
     * @return 用户绩效汇总列表
     */
    @PostMapping("query/user")
    @Operation(summary = "小程序端员工查询客户下单汇总", description = "参数：员工绩效汇总查询请求体，权限：管理员，方法名：miniListUserPerformanceSummary")
    @RequiresPermission(mustRole = UserConstant.STAFF_ROLE)
    public BaseResponse<List<CourseOrderDetailInfoVO>> miniListUserPerformanceSummary(@Valid @RequestBody MiniUserCourseOrderQueryRequest miniUserCourseOrderQueryRequest) {
        String orderNumber = miniUserCourseOrderQueryRequest.getOrderNumber();
        Long staffUserId = miniUserCourseOrderQueryRequest.getStaffUserId();
        LambdaQueryWrapper<CourseOrder> courseOrderQueryWrapper = new LambdaQueryWrapper<>();
        courseOrderQueryWrapper.eq(StringUtils.isNotBlank(orderNumber), CourseOrder::getOrderNumber, orderNumber);
        courseOrderQueryWrapper.in(CourseOrder::getOrderStatus, OrderStatusConstant.SUCCESS, OrderStatusConstant.REFUNDED);

        List<Long> ids = userInfoService.findAllSubUser(staffUserId);
        List<UserInfo> userInfoList = commonService.findByFieldInTargetFieldWithSpecificFields(ids, userInfoService, Function.identity(), UserInfo::getId,
                List.of(UserInfo::getId, UserInfo::getNickName, UserInfo::getPhoneNumber));
        courseOrderQueryWrapper.in(CourseOrder::getUserId, ids);

        courseOrderQueryWrapper.select(CourseOrder::getId, CourseOrder::getUserId, CourseOrder::getOrderNumber, CourseOrder::getTotalAmount, CourseOrder::getOrderStatus, CourseOrder::getCreateTime);
        List<CourseOrder> courseOrderList = courseOrderService.list(courseOrderQueryWrapper);
        List<CourseOrderDetailInfoVO> courseOrderDetailInfoVOS = commonService.convertList(courseOrderList, CourseOrderDetailInfoVO.class);

        // 封装Map集合（键:用户id, 值：用户信息）
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) userInfoMap.put(userInfo.getId(), userInfo);
        for (CourseOrderDetailInfoVO courseOrderBaseInfoVOS : courseOrderDetailInfoVOS) {
            UserInfo userInfo = userInfoMap.get(courseOrderBaseInfoVOS.getUserId());
            courseOrderBaseInfoVOS.setNickName(userInfo.getNickName());
            courseOrderBaseInfoVOS.setPhoneNumber(userInfo.getPhoneNumber());
        }

        List<CoursePromotionCommissionPending> coursePromotionCommissionPendingList = commonService.findByFieldInTargetFieldWithSpecificFields(
                courseOrderList, coursePromotionCommissionPendingService, CourseOrder::getId, CoursePromotionCommissionPending::getOrderId,
                List.of(CoursePromotionCommissionPending::getFirstRate, CoursePromotionCommissionPending::getSecondRate, CoursePromotionCommissionPending::getFirstReward,
                        CoursePromotionCommissionPending::getSecondReward, CoursePromotionCommissionPending::getCommissionStatus, CoursePromotionCommissionPending::getOrderId));
        // 封装Map集合（键：用户id, 值：课程推广待提成记录）
        Map<Long, CoursePromotionCommissionPending> coursePromotionCommissionPendingMap = new HashMap<>();
        for (CoursePromotionCommissionPending coursePromotionCommissionPending : coursePromotionCommissionPendingList) coursePromotionCommissionPendingMap.put(coursePromotionCommissionPending.getOrderId(), coursePromotionCommissionPending);
        for (CourseOrderDetailInfoVO courseOrderDetailInfoVO : courseOrderDetailInfoVOS) {
            Long orderId = courseOrderDetailInfoVO.getId();
            CoursePromotionCommissionPending coursePromotionCommissionPending = coursePromotionCommissionPendingMap.get(orderId);
            courseOrderDetailInfoVO.setFirstRate(coursePromotionCommissionPending.getFirstRate());
            courseOrderDetailInfoVO.setSecondRate(coursePromotionCommissionPending.getSecondRate());
            courseOrderDetailInfoVO.setFirstReward(coursePromotionCommissionPending.getFirstReward());
            courseOrderDetailInfoVO.setSecondReward(coursePromotionCommissionPending.getSecondReward());
            courseOrderDetailInfoVO.setCommissionStatus(coursePromotionCommissionPending.getCommissionStatus());
        }

        return ResultUtils.success(courseOrderDetailInfoVOS);
    }




    /**
     * 小程序端经理查询主管绩效排名
     * @param miniUserPerformanceSummaryRankQueryRequest 小程序端绩效排名查询请求体
     * @return 用户绩效汇总列表
     */
    @PostMapping("rank/supervisor")
    @Operation(summary = "小程序端经理查询主管绩效排名", description = "参数：小程序端绩效排名查询请求体，权限：管理员，方法名：miniListSupervisorPerformanceSummaryRankingsByPage")
    @RequiresPermission(mustRole = UserConstant.SUPERVISOR_ROLE)
    public BaseResponse<List<SupervisorPerformanceSummaryVO>> miniListSupervisorPerformanceSummaryRankingsByPage(@Valid @RequestBody MiniUserPerformanceSummaryRankQueryRequest miniUserPerformanceSummaryRankQueryRequest) {
        String startTimeStr = miniUserPerformanceSummaryRankQueryRequest.getStartDate();
        String endTimeStr = miniUserPerformanceSummaryRankQueryRequest.getEndDate();
        String nickName = miniUserPerformanceSummaryRankQueryRequest.getNickName();
        String phoneNumber = miniUserPerformanceSummaryRankQueryRequest.getPhoneNumber();

        DateTime startDate = null;
        DateTime endDate = null;
        boolean isAddDate = true;
        try {
            startDate = DateUtil.parse(startTimeStr, "yyyy-MM-dd HH:mm:ss");
            endDate = DateUtil.parse(endTimeStr, "yyyy-MM-dd HH:mm:ss");
        } catch (Exception e) {
            isAddDate = false;
        }

        LambdaQueryWrapper<EmployeePromotionRecords> empQueryWrapper = new LambdaQueryWrapper<>();
        if (isAddDate) {
            empQueryWrapper.ge(StringUtils.isNotBlank(startTimeStr), EmployeePromotionRecords::getCreateTime, startDate);
            empQueryWrapper.le(StringUtils.isNotBlank(endTimeStr), EmployeePromotionRecords::getCreateTime, endDate);
        }
        empQueryWrapper.select(EmployeePromotionRecords::getFirstUserId);
        List<EmployeePromotionRecords> employeePromotionRecordsList = employeePromotionRecordsService.list(empQueryWrapper);
        // 封装Map集合（键：主管id, 值：推广数量）
        Map<Long, Integer> supervisorCntMap = new HashMap<>();
        for (EmployeePromotionRecords employeePromotionRecords : employeePromotionRecordsList) {
            Long firstUserId = employeePromotionRecords.getFirstUserId();
            supervisorCntMap.merge(firstUserId, 1, Integer::sum);
        }

        // 封装Map集合（键：主管id, 值：下单数量）
        Map<Long, Integer> supervisorOrderCntMap = new HashMap<>();
        // 封装Map集合（键：主管id, 值：下单金额）
        Map<Long, BigDecimal> supervisorOrderAmountMap = new HashMap<>();
        // 封装Map集合（键：主管id, 值：净成交金额）
        Map<Long, BigDecimal> supervisorNetSalesAmountMap = new HashMap<>();
        LambdaQueryWrapper<CoursePromotionCommissionPending> coursePromotionQueryWrapper = new LambdaQueryWrapper<>();
        coursePromotionQueryWrapper.ge(StringUtils.isNotBlank(startTimeStr), CoursePromotionCommissionPending::getOrderCreateTime, startDate);
        coursePromotionQueryWrapper.le(StringUtils.isNotBlank(endTimeStr), CoursePromotionCommissionPending::getOrderCreateTime, endDate);
        coursePromotionQueryWrapper.select(CoursePromotionCommissionPending::getFirstUserId, CoursePromotionCommissionPending::getTotalAmount,
                CoursePromotionCommissionPending::getUpdateTime, CoursePromotionCommissionPending::getCommissionStatus);
        List<CoursePromotionCommissionPending> coursePromotionCommissionPendingList = coursePromotionCommissionPendingService.list(coursePromotionQueryWrapper);
        for (CoursePromotionCommissionPending coursePromotionCommissionPending : coursePromotionCommissionPendingList) {
            Long firstUserId = coursePromotionCommissionPending.getFirstUserId();
            BigDecimal totalAmount = coursePromotionCommissionPending.getTotalAmount();
            DateTime updateDate  = DateUtil.date(coursePromotionCommissionPending.getUpdateTime());
            String commissionStatus = coursePromotionCommissionPending.getCommissionStatus();
            CommissionStatusEnum commissionStatusEnum = CommissionStatusEnum.getEnumByValue(commissionStatus);
            supervisorOrderCntMap.merge(firstUserId, 1, Integer::sum);
            BigDecimal totalAmountTemp = totalAmount;
            if (CommissionStatusEnum.EXPIRED.equals(commissionStatusEnum)) {
                totalAmountTemp = totalAmount.multiply(SystemConstant.FEE_RATE);
            }
            supervisorOrderAmountMap.merge(firstUserId, totalAmountTemp, BigDecimal::add);

            if (startDate != null && endDate != null) {
                if (!(CommissionStatusEnum.COMPLETED.equals(commissionStatusEnum) && updateDate.isAfterOrEquals(startDate) && updateDate.isBeforeOrEquals(endDate))) {
                    totalAmount = totalAmount.multiply(SystemConstant.FEE_RATE);
                }
            } else {
                if (!CommissionStatusEnum.COMPLETED.equals(commissionStatusEnum)) {
                    totalAmount = totalAmount.multiply(SystemConstant.FEE_RATE);
                }
            }
            supervisorNetSalesAmountMap.merge(firstUserId, totalAmount, BigDecimal::add);
        }
        LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userInfoLambdaQueryWrapper.eq(StringUtils.isNotBlank(nickName), UserInfo::getNickName, nickName)
                .eq(StringUtils.isNotBlank(phoneNumber), UserInfo::getPhoneNumber, phoneNumber)
                .eq(UserInfo::getUserRole, UserConstant.SUPERVISOR_ROLE);
        userInfoLambdaQueryWrapper.select(UserInfo::getId, UserInfo::getNickName, UserInfo::getPhoneNumber);

        List<UserInfo> userInfoList = userInfoService.list(userInfoLambdaQueryWrapper);
        List<UserPerformanceSummary> userPerformanceSummaryList = commonService.findByFieldInTargetFieldWithSpecificFields(userInfoList, userPerformanceSummaryService, UserInfo::getId, UserPerformanceSummary::getUserId,
                List.of(UserPerformanceSummary::getUserId, UserPerformanceSummary::getEmpCount));

        // 封装Map集合（键：主管id, 用户信息）
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) {
            userInfoMap.put(userInfo.getId(), userInfo);
        }

        // 封装主管绩效排名列表
        List<SupervisorPerformanceSummaryVO> supervisorPerformanceSummaryVOS = new ArrayList<>();
        for (UserPerformanceSummary userPerformanceSummary : userPerformanceSummaryList) {
            Long userId = userPerformanceSummary.getUserId();
            UserInfo userInfo = userInfoMap.get(userId);
            SupervisorPerformanceSummaryVO supervisorPerformanceSummaryVO = SupervisorPerformanceSummaryVO.builder()
                    .nickName(userInfo.getNickName())
                    .phoneNumber(userInfo.getPhoneNumber())
                    .empCount(userPerformanceSummary.getEmpCount())
                    .orderCount(supervisorOrderCntMap.get(userId) == null ? 0 : supervisorOrderCntMap.get(userId))
                    .totalAmount(supervisorOrderAmountMap.get(userId) == null ? BigDecimal.ZERO : supervisorOrderAmountMap.get(userId))
                    .netAmount(supervisorNetSalesAmountMap.get(userId) == null ? BigDecimal.ZERO : supervisorNetSalesAmountMap.get(userId))
                    .promoCount(supervisorCntMap.get(userId) == null ? 0 : supervisorCntMap.get(userId))
                    .build();
            supervisorPerformanceSummaryVOS.add(supervisorPerformanceSummaryVO);
        }
        userPerformanceSummaryService.sortPerformanceRankingList(supervisorPerformanceSummaryVOS, miniUserPerformanceSummaryRankQueryRequest);

        return ResultUtils.success(supervisorPerformanceSummaryVOS);
    }



    /**
     * 小程序端主管(经理）查询员工绩效排名
     * @param miniUserPerformanceSummaryRankQueryRequest 绩效排名查询请求体
     * @return 用户绩效汇总列表
     */
    @PostMapping("rank/staff")
    @Operation(summary = "小程序端主管(经理）查询员工绩效排名", description = "参数：绩效排名查询请求体，权限：管理员，方法名：miniListStaffUserPerformanceSummaryRankingsByPage")
    @RequiresPermission(mustRole = UserConstant.STAFF_ROLE)
    public BaseResponse<List<SupervisorPerformanceSummaryVO>> miniListStaffUserPerformanceSummaryRankingsByPage(@Valid @RequestBody MiniUserPerformanceSummaryRankQueryRequest miniUserPerformanceSummaryRankQueryRequest, HttpServletRequest request) {
        Long currentUserId = (Long) request.getAttribute("userId");
        UserInfo currentUserInfo = userInfoService.getById(currentUserId);
        UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(currentUserInfo.getUserRole());
        if (UserRoleEnum.STAFF.equals(userRoleEnum)) currentUserId = currentUserInfo.getParentUserId();

        String startTimeStr = miniUserPerformanceSummaryRankQueryRequest.getStartDate();
        String endTimeStr = miniUserPerformanceSummaryRankQueryRequest.getEndDate();
        String nickName = miniUserPerformanceSummaryRankQueryRequest.getNickName();
        String phoneNumber = miniUserPerformanceSummaryRankQueryRequest.getPhoneNumber();
        DateTime startDate = null;
        DateTime endDate = null;
        boolean isAddDate = true;
        try {
            startDate = DateUtil.parse(startTimeStr, "yyyy-MM-dd HH:mm:ss");
            endDate = DateUtil.parse(endTimeStr, "yyyy-MM-dd HH:mm:ss");
        } catch (Exception e) {
            isAddDate = false;
        }

        LambdaQueryWrapper<EmployeePromotionRecords> empQueryWrapper = new LambdaQueryWrapper<>();
        if (isAddDate) {
            empQueryWrapper.ge(StringUtils.isNotBlank(startTimeStr), EmployeePromotionRecords::getCreateTime, startDate);
            empQueryWrapper.le(StringUtils.isNotBlank(endTimeStr), EmployeePromotionRecords::getCreateTime, endDate);
        }
        if (!UserRoleEnum.MANAGER.equals(userRoleEnum)) empQueryWrapper.eq(EmployeePromotionRecords::getFirstUserId, currentUserId);
        empQueryWrapper.select(EmployeePromotionRecords::getSecondUserId);
        List<EmployeePromotionRecords> employeePromotionRecordsList = employeePromotionRecordsService.list(empQueryWrapper);
        // 封装Map集合（键：员工id, 值：推广数量）
        Map<Long, Integer> staffCntMap = new HashMap<>();
        for (EmployeePromotionRecords employeePromotionRecords : employeePromotionRecordsList) {
            Long secondUserId = employeePromotionRecords.getSecondUserId();
            staffCntMap.merge(secondUserId, 1, Integer::sum);
        }

        // 封装Map集合（键：员工id, 值：下单数量）
        Map<Long, Integer> staffOrderCntMap = new HashMap<>();
        // 封装Map集合（键：员工id, 值：下单金额）
        Map<Long, BigDecimal> staffOrderAmountMap = new HashMap<>();
        // 封装Map集合（键：员工id, 值：净成交金额）
        Map<Long, BigDecimal> staffNetSalesAmountMap = new HashMap<>();
        LambdaQueryWrapper<CoursePromotionCommissionPending> coursePromotionQueryWrapper = new LambdaQueryWrapper<>();
        coursePromotionQueryWrapper.ge(StringUtils.isNotBlank(startTimeStr), CoursePromotionCommissionPending::getOrderCreateTime, startDate);
        coursePromotionQueryWrapper.le(StringUtils.isNotBlank(endTimeStr), CoursePromotionCommissionPending::getOrderCreateTime, endDate);
        if (!UserRoleEnum.MANAGER.equals(userRoleEnum)) coursePromotionQueryWrapper.eq(CoursePromotionCommissionPending::getFirstUserId, currentUserId);
        coursePromotionQueryWrapper.select(CoursePromotionCommissionPending::getSecondUserId, CoursePromotionCommissionPending::getTotalAmount,
                CoursePromotionCommissionPending::getUpdateTime, CoursePromotionCommissionPending::getCommissionStatus);
        List<CoursePromotionCommissionPending> coursePromotionCommissionPendingList = coursePromotionCommissionPendingService.list(coursePromotionQueryWrapper);
        for (CoursePromotionCommissionPending coursePromotionCommissionPending : coursePromotionCommissionPendingList) {
            Long secondUserId = coursePromotionCommissionPending.getSecondUserId();
            BigDecimal totalAmount = coursePromotionCommissionPending.getTotalAmount();
            DateTime updateDate  = DateUtil.date(coursePromotionCommissionPending.getUpdateTime());
            String commissionStatus = coursePromotionCommissionPending.getCommissionStatus();
            CommissionStatusEnum commissionStatusEnum = CommissionStatusEnum.getEnumByValue(commissionStatus);
            staffOrderCntMap.merge(secondUserId, 1, Integer::sum);
            BigDecimal totalAmountTemp = totalAmount;
            if (CommissionStatusEnum.EXPIRED.equals(commissionStatusEnum)) {
                totalAmountTemp = totalAmount.multiply(SystemConstant.FEE_RATE);
            }
            staffOrderAmountMap.merge(secondUserId, totalAmountTemp, BigDecimal::add);

            if (startDate != null && endDate != null) {
                if (!(CommissionStatusEnum.COMPLETED.equals(commissionStatusEnum) && updateDate.isAfterOrEquals(startDate) && updateDate.isBeforeOrEquals(endDate))) {
                    totalAmount = totalAmount.multiply(SystemConstant.FEE_RATE);
                }
            } else {
                if (!CommissionStatusEnum.COMPLETED.equals(commissionStatusEnum)) {
                    totalAmount = totalAmount.multiply(SystemConstant.FEE_RATE);
                }
            }
            staffNetSalesAmountMap.merge(secondUserId, totalAmount, BigDecimal::add);
        }
        LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userInfoLambdaQueryWrapper.eq(StringUtils.isNotBlank(nickName), UserInfo::getNickName, nickName)
                .eq(StringUtils.isNotBlank(phoneNumber), UserInfo::getPhoneNumber, phoneNumber).eq(UserInfo::getUserRole, UserConstant.STAFF_ROLE);
        if (!UserRoleEnum.MANAGER.equals(userRoleEnum)) userInfoLambdaQueryWrapper.eq(UserInfo::getParentUserId, currentUserId);
        userInfoLambdaQueryWrapper.select(UserInfo::getId, UserInfo::getNickName, UserInfo::getPhoneNumber);
        List<UserInfo> userInfoList = userInfoService.list(userInfoLambdaQueryWrapper);
        List<UserPerformanceSummary> userPerformanceSummaryList = commonService.findByFieldInTargetField(userInfoList, userPerformanceSummaryService, UserInfo::getId, UserPerformanceSummary::getUserId);

        // 封装Map集合（键：主管id, 用户信息）
        Map<Long, UserInfo> userInfoMap = new HashMap<>();
        for (UserInfo userInfo : userInfoList) {
            userInfoMap.put(userInfo.getId(), userInfo);
        }

        // 封装员工绩效排名列表
        List<SupervisorPerformanceSummaryVO> supervisorPerformanceSummaryVOS = new ArrayList<>();
        for (UserPerformanceSummary userPerformanceSummary : userPerformanceSummaryList) {
            Long userId = userPerformanceSummary.getUserId();
            UserInfo userInfo = userInfoMap.get(userId);
            SupervisorPerformanceSummaryVO supervisorPerformanceSummaryVO = SupervisorPerformanceSummaryVO.builder()
                    .nickName(userInfo.getNickName())
                    .phoneNumber(userInfo.getPhoneNumber())
                    .empCount(userPerformanceSummary.getEmpCount())
                    .orderCount(staffOrderCntMap.get(userId) == null ? 0 : staffOrderCntMap.get(userId))
                    .totalAmount(staffOrderAmountMap.get(userId) == null ? BigDecimal.ZERO : staffOrderAmountMap.get(userId))
                    .netAmount(staffNetSalesAmountMap.get(userId) == null ? BigDecimal.ZERO : staffNetSalesAmountMap.get(userId))
                    .promoCount(staffCntMap.get(userId) == null ? 0 : staffCntMap.get(userId))
                    .build();
            supervisorPerformanceSummaryVOS.add(supervisorPerformanceSummaryVO);
        }
        userPerformanceSummaryService.sortPerformanceRankingList(supervisorPerformanceSummaryVOS, miniUserPerformanceSummaryRankQueryRequest);

        return ResultUtils.success(supervisorPerformanceSummaryVOS);
    }


    /**
     * 小程序端仪表盘
     * @return 用户绩效汇总
     */
    @PostMapping("mini/query/dashboard")
    @Operation(summary = "小程序端仪表盘", description = "参数：无，权限：管理员，方法名：miniQueryDashboard")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
    public BaseResponse<WebQueryDashboardVO> miniQueryDashboard(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        UserInfo userInfo = userInfoService.getById(userId);
        String userRole = userInfo.getUserRole();
        UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(userRole);
        WebQueryDashboardVO webQueryDashboardVO;
        if (UserRoleEnum.MANAGER.equals(userRoleEnum)) {
            webQueryDashboardVO = userPerformanceSummaryService.queryManagerDashboard();
        } else {
            webQueryDashboardVO = userPerformanceSummaryService.querySupervisorOrStaffDashboard(userRoleEnum, userId);
        }
        return ResultUtils.success(webQueryDashboardVO);
    }









}