package com.greenorange.promotion.controller.project;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.greenorange.promotion.annotation.RequiresPermission;
import com.greenorange.promotion.annotation.SysLog;
import com.greenorange.promotion.common.BaseResponse;
import com.greenorange.promotion.common.ErrorCode;
import com.greenorange.promotion.common.ResultUtils;
import com.greenorange.promotion.constant.UserConstant;
import com.greenorange.promotion.exception.ThrowUtils;
import com.greenorange.promotion.model.dto.CommonRequest;
import com.greenorange.promotion.model.dto.projectCommission.ProjectCommissionUniteUpdateRequest;
import com.greenorange.promotion.model.dto.projectCommission.ProjectCommissionUpdateRequest;
import com.greenorange.promotion.model.dto.subUserProjectCommission.SubUserProjectCommissionUpdateRequest;
import com.greenorange.promotion.model.entity.*;
import com.greenorange.promotion.model.vo.projectCommission.ProjectCommissionVO;
import com.greenorange.promotion.model.vo.projectCommission.ProjectDetailCommissionVO;
import com.greenorange.promotion.model.vo.subUserProjectCommission.SubUserProjectCommissionVO;
import com.greenorange.promotion.model.vo.subUserProjectCommission.SubUserProjectDetailCommissionVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.project.ProjectCommissionService;
import com.greenorange.promotion.service.project.ProjectDetailService;
import com.greenorange.promotion.service.project.ProjectService;
import com.greenorange.promotion.service.project.SubUserProjectCommissionService;
import com.greenorange.promotion.service.userInfo.UserInfoService;
import com.greenorange.promotion.service.userInfo.UserMainInfoService;
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 jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.GenericDeclaration;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 项目明细抽佣 控制器
 */
@RestController
@RequestMapping("projectCommission")
@Slf4j
@Tag(name = "项目明细抽佣管理")
@Transactional
public class ProjectCommissionController {

    @Resource
    private ProjectCommissionService projectCommissionService;

    @Resource
    private SubUserProjectCommissionService subUserProjectCommissionService;

    @Resource
    private CommonService commonService;

    @Resource
    private ProjectService projectService;

    @Resource
    private ProjectDetailService projectDetailService;

    @Resource
    private UserInfoService userInfoService;


    /**
     * 小程序用户查看查询项目的抽佣情况
     * @return 项目抽佣列表
     */
    @PostMapping("query/commission")
    @Operation(summary = "小程序用户查看查询项目的抽佣情况", description = "参数：无，权限：管理员，方法名：queryProjectCommission")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "项目明细抽佣管理", content = "小程序用户查看查询项目的抽佣情况")
    public BaseResponse<List<ProjectCommissionVO>> queryProjectCommission(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        List<ProjectCommission> projectCommissionList = commonService.findByFieldEqTargetField(ProjectCommission::getUserId, userId, projectCommissionService);
        List<ProjectDetail> projectDetailList = commonService.findByFieldInTargetField(projectCommissionList, projectDetailService, ProjectCommission::getProjectDetailId, ProjectDetail::getId);
        // 封装Map集合（键：项目明细id，值：项目明细名称）
        Map<Long, String> projectDetailMap = new HashMap<>();
        // 封装Map集合（键：项目明细id，值：项目明细最大抽佣比例）
        Map<Long, BigDecimal> rateMap = new HashMap<>();
        for (ProjectDetail projectDetail : projectDetailList) {
            projectDetailMap.put(projectDetail.getId(), projectDetail.getProjectDetailName());
            rateMap.put(projectDetail.getId(), projectDetail.getMaxCommissionRate());
        }
        // 封装项目明细抽佣列表
        List<ProjectDetailCommissionVO> projectDetailCommissionVOList = new ArrayList<>();
        for (ProjectCommission projectCommission : projectCommissionList) {
            Long projectDetailId = projectCommission.getProjectDetailId();
            BigDecimal myUnitPrice = projectCommission.getMyUnitPrice();
            BigDecimal currentCommissionRate = projectCommission.getCurrentCommissionRate();
            String projectDetailName = projectDetailMap.get(projectDetailId);
            BigDecimal maxCommissionRate = rateMap.get(projectDetailId);
            ProjectDetailCommissionVO projectDetailCommissionVO = commonService.copyProperties(projectCommission, ProjectDetailCommissionVO.class);
            projectDetailCommissionVO.setCurrentCommissionRate(currentCommissionRate);
            projectDetailCommissionVO.setProjectDetailName(projectDetailName);
            projectDetailCommissionVO.setMaxCommissionRate(maxCommissionRate);
            BigDecimal agentUnitPrice = myUnitPrice
                    .multiply(BigDecimal.ONE.subtract(currentCommissionRate.divide(BigDecimal.valueOf(100))))
                    .setScale(2, RoundingMode.HALF_UP);
            projectDetailCommissionVO.setAgentUnitPrice(agentUnitPrice);
            projectDetailCommissionVOList.add(projectDetailCommissionVO);
        }
        // 封装Map集合（键：项目id，值：项目明细抽佣列表）
        Map<Long, List<ProjectDetailCommissionVO>> pdcMap = new HashMap<>();
        for (ProjectDetailCommissionVO projectDetailCommissionVO : projectDetailCommissionVOList) {
            Long projectId = projectDetailCommissionVO.getProjectId();
            List<ProjectDetailCommissionVO> pdcList = pdcMap.get(projectId);
            if (pdcList == null) {
                pdcList = new ArrayList<>();
            }
            pdcList.add(projectDetailCommissionVO);
            pdcMap.put(projectId, pdcList);
        }
        // 封装项目抽佣列表
        List<Project> projectList = commonService.findByFieldInTargetField(projectCommissionList, projectService, ProjectCommission::getProjectId, Project::getId);
        List<ProjectCommissionVO> projectCommissionVOList = new ArrayList<>();
        for (Project project : projectList) {
            ProjectCommissionVO projectCommissionVO = commonService.copyProperties(project, ProjectCommissionVO.class);
            Long projectId = project.getId();
            List<ProjectDetailCommissionVO> projectDetailCommissionVOS = pdcMap.get(projectId);
            projectCommissionVO.setProjectId(projectId);
            projectCommissionVO.setProjectDetailCommissionVOList(projectDetailCommissionVOS);
            projectCommissionVOList.add(projectCommissionVO);
        }
        return ResultUtils.success(projectCommissionVOList);
    }


//    public static void main(String[] args) {
//        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
//        String encode = passwordEncoder.encode("123456");
//        System.out.println(encode);
//        boolean matches = passwordEncoder.matches("123456", "$2a$10$/yBGQqsHK78vlEtuMGTVY.bU/TamHQbr4wQIzj1B1H1ud/ZKPGICC");
//        System.out.println(matches);
//    }


//
//    /**
//     * 小程序用户修改项目的抽佣比例
//     * @param projectCommissionUpdateRequest 项目明细抽佣更新请求体
//     * @return 是否添加成功
//     */
//    @PostMapping("update/rate")
//    @Operation(summary = "小程序用户修改项目的抽佣比例", description = "参数：项目明细抽佣更新请求体，权限：管理员，方法名：updateProjectCommissionRate")
//    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
////    @SysLog(title = "项目明细抽佣管理", content = "小程序用户修改项目的抽佣比例")
//    public BaseResponse<Boolean> updateProjectCommissionRate(@Valid @RequestBody ProjectCommissionUpdateRequest projectCommissionUpdateRequest, HttpServletRequest request) {
//        Long id = projectCommissionUpdateRequest.getId();
//        BigDecimal currentCommissionRate = projectCommissionUpdateRequest.getCurrentCommissionRate();
//        // 校验当前抽佣比例不能大于最大抽佣比例
//        ProjectCommission projectCommission = projectCommissionService.getById(id);
//        Long projectDetailId = projectCommission.getProjectDetailId();
//        ProjectDetail projectDetail = projectDetailService.getById(projectDetailId);
//        BigDecimal maxCommissionRate = projectDetail.getMaxCommissionRate();
//        ThrowUtils.throwIf(currentCommissionRate.compareTo(maxCommissionRate) > 0, ErrorCode.OPERATION_ERROR, "当前抽佣比例不能大于最大抽佣比例");
//        projectCommission.setCurrentCommissionRate(currentCommissionRate);
//        projectCommissionService.updateById(projectCommission);
//
//        // 批量更新下级用户的项目明细抽佣比例
//        Long userId = (Long) request.getAttribute("userId");
//        Map<SFunction<SubUserProjectCommission, ?>, Object> fieldConditions = Map.of(SubUserProjectCommission::getProjectDetailId, projectDetailId, SubUserProjectCommission::getUserId, userId);
//        List<SubUserProjectCommission> subUserProjectCommissionList = commonService.findByFieldEqTargetFields(fieldConditions, subUserProjectCommissionService);
//        for (SubUserProjectCommission subUserProjectCommission : subUserProjectCommissionList) {
//            subUserProjectCommission.setCurrentCommissionRate(currentCommissionRate);
//        }
//        subUserProjectCommissionService.updateBatchById(subUserProjectCommissionList);
//        return ResultUtils.success(true);
//    }


    /**
     * 小程序用户修改项目的抽佣比例
     * @param projectCommissionUpdateRequest 项目明细抽佣更新请求体
     * @return 是否添加成功
     */
    @PostMapping("update/rate")
    @Operation(summary = "小程序用户修改项目的抽佣比例", description = "参数：项目明细抽佣更新请求体，权限：管理员，方法名：updateProjectCommissionRate")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "项目明细抽佣管理", content = "小程序用户修改项目的抽佣比例")
    public BaseResponse<Boolean> updateProjectCommissionRate(@Valid @RequestBody ProjectCommissionUpdateRequest projectCommissionUpdateRequest, HttpServletRequest request) {
        projectCommissionService.updateProjectCommissionRate(projectCommissionUpdateRequest);
        return ResultUtils.success(true);
    }


    /**
     * 小程序用户查看下级用户的项目明细抽佣情况
     * @param commonRequest 项目id
     * @return 下级用户的项目明细抽佣列表
     */
    @PostMapping("query/sub/commission")
    @Operation(summary = "小程序用户查看下级用户的项目明细抽佣情况", description = "参数：项目明细抽佣添加请求体，权限：管理员，方法名：querySubUserProjectCommission")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "项目明细抽佣管理", content = "小程序用户查看下级用户的项目明细抽佣情况")
    public BaseResponse<List<SubUserProjectCommissionVO>> querySubUserProjectCommission(@Valid @RequestBody CommonRequest commonRequest, HttpServletRequest request) {
        Long projectId = commonRequest.getId();
        Long userId = (Long) request.getAttribute("userId");
        LambdaQueryWrapper<SubUserProjectCommission> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SubUserProjectCommission::getProjectId, projectId);
        lambdaQueryWrapper.eq(SubUserProjectCommission::getUserId, userId);
        List<SubUserProjectCommission> subUserProjectCommissionList = subUserProjectCommissionService.list(lambdaQueryWrapper);

        List<ProjectDetail> projectDetailList = commonService.findByFieldInTargetField(subUserProjectCommissionList, projectDetailService, SubUserProjectCommission::getProjectDetailId, ProjectDetail::getId);
        // 封装Map集合（键：项目明细id，值：项目明细名称）
        Map<Long, String> projectDetailMap = new HashMap<>();
        // 封装Map集合（键：项目明细id，值：项目明细最大抽佣比例）
        Map<Long, BigDecimal> rateMap = new HashMap<>();
        for (ProjectDetail projectDetail : projectDetailList) {
            projectDetailMap.put(projectDetail.getId(), projectDetail.getProjectDetailName());
            rateMap.put(projectDetail.getId(), projectDetail.getMaxCommissionRate());
        }
        // 封装下级用户项目明细抽佣列表
        List<SubUserProjectDetailCommissionVO> subUserProjectDetailCommissionVOList = new ArrayList<>();
        for (SubUserProjectCommission subUserProjectCommission : subUserProjectCommissionList) {
            Long projectDetailId = subUserProjectCommission.getProjectDetailId();
            String projectDetailName = projectDetailMap.get(projectDetailId);
            BigDecimal maxCommissionRate = rateMap.get(projectDetailId);
            SubUserProjectDetailCommissionVO subUserProjectDetailCommissionVO = commonService.copyProperties(subUserProjectCommission, SubUserProjectDetailCommissionVO.class);
            subUserProjectDetailCommissionVO.setProjectDetailName(projectDetailName);
            subUserProjectDetailCommissionVO.setMaxCommissionRate(maxCommissionRate);
            BigDecimal myUnitPrice = subUserProjectCommission.getMyUnitPrice();
            BigDecimal currentCommissionRate = subUserProjectCommission.getCurrentCommissionRate();
            BigDecimal agentUnitPrice = myUnitPrice
                    .multiply(BigDecimal.ONE.subtract(currentCommissionRate.divide(BigDecimal.valueOf(100))))
                    .setScale(2, RoundingMode.HALF_UP);
            subUserProjectDetailCommissionVO.setAgentUnitPrice(agentUnitPrice);
            subUserProjectDetailCommissionVOList.add(subUserProjectDetailCommissionVO);
        }
        // 封装Map集合（键：下级用户id，值：项目明细抽佣列表）
        Map<Long, List<SubUserProjectDetailCommissionVO> > subPdcMap = new HashMap<>();
        for (SubUserProjectDetailCommissionVO subUserProjectDetailCommissionVO : subUserProjectDetailCommissionVOList) {
            Long subUserId = subUserProjectDetailCommissionVO.getSubUserId();
            List<SubUserProjectDetailCommissionVO> subUserProjectDetailCommissionVOS = subPdcMap.get(subUserId);
            if (subUserProjectDetailCommissionVOS == null) {
                subUserProjectDetailCommissionVOS = new ArrayList<>();
            }
            subUserProjectDetailCommissionVOS.add(subUserProjectDetailCommissionVO);
            subPdcMap.put(subUserId, subUserProjectDetailCommissionVOS);
        }
        // 封装下级用户项目抽佣列表
        LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userInfoLambdaQueryWrapper.eq(UserInfo::getParentUserId, userId);
        List<UserInfo> userInfoList = userInfoService.list(userInfoLambdaQueryWrapper);
        List<SubUserProjectCommissionVO> subUserProjectCommissionVOList = new ArrayList<>();
        for (UserInfo userInfo : userInfoList) {
            Long subUserId = userInfo.getId();
            String nickName = userInfo.getNickName();
            List<SubUserProjectDetailCommissionVO> subUserProjectDetailCommissionVOS = subPdcMap.get(subUserId);
            SubUserProjectCommissionVO subUserProjectCommissionVO = SubUserProjectCommissionVO.builder()
                    .subUserId(subUserId)
                    .subUserNickName(nickName)
                    .subUserProjectDetailCommissionVOList(subUserProjectDetailCommissionVOS)
                    .build();
            subUserProjectCommissionVOList.add(subUserProjectCommissionVO);
        }
        return ResultUtils.success(subUserProjectCommissionVOList);
    }


//    /**
//     * 小程序用户修改下级用户的项目明细抽佣比例
//     * @param subUserProjectCommissionUpdateRequest 下级用户项目明细抽佣更新请求体
//     * @return 是否添加成功
//     */
//    @PostMapping("update/sub/rate")
//    @Operation(summary = "小程序用户修改下级用户的项目明细抽佣比例", description = "参数：下级用户项目明细抽佣更新请求体，权限：管理员，方法名：updateSubUserProjectCommissionRate")
//    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
////    @SysLog(title = "项目明细抽佣管理", content = "小程序用户修改下级用户的项目明细抽佣比例")
//    public BaseResponse<Boolean> updateSubUserProjectCommissionRate(@Valid @RequestBody SubUserProjectCommissionUpdateRequest subUserProjectCommissionUpdateRequest) {
//        Long id = subUserProjectCommissionUpdateRequest.getId();
//        BigDecimal currentCommissionRate = subUserProjectCommissionUpdateRequest.getCurrentCommissionRate();
//        // 校验当前抽佣比例不能大于最大抽佣比例
//        SubUserProjectCommission subUserProjectCommission = subUserProjectCommissionService.getById(id);
//        Long projectDetailId = subUserProjectCommission.getProjectDetailId();
//        ProjectDetail projectDetail = projectDetailService.getById(projectDetailId);
//        BigDecimal maxCommissionRate = projectDetail.getMaxCommissionRate();
//        ThrowUtils.throwIf(currentCommissionRate.compareTo(maxCommissionRate) > 0, ErrorCode.OPERATION_ERROR, "当前抽佣比例不能大于最大抽佣比例");
//        subUserProjectCommission.setCurrentCommissionRate(currentCommissionRate);
//        subUserProjectCommissionService.updateById(subUserProjectCommission);
//        return ResultUtils.success(true);
//    }


    /**
     * 小程序用户修改下级用户的项目明细抽佣比例
     * @param subUserProjectCommissionUpdateRequest 下级用户项目明细抽佣更新请求体
     * @return 是否添加成功
     */
    @PostMapping("update/sub/rate")
    @Operation(summary = "小程序用户修改下级用户的项目明细抽佣比例", description = "参数：下级用户项目明细抽佣更新请求体，权限：管理员，方法名：updateSubUserProjectCommissionRate")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "项目明细抽佣管理", content = "小程序用户修改下级用户的项目明细抽佣比例")
    public BaseResponse<Boolean> updateSubUserProjectCommissionRate(@Valid @RequestBody SubUserProjectCommissionUpdateRequest subUserProjectCommissionUpdateRequest) {
        projectCommissionService.updateSubUserProjectCommissionRate(subUserProjectCommissionUpdateRequest);
        return ResultUtils.success(true);
    }


//    /**
//     * 小程序用户一键设置项目的的抽佣比例
//     * @param projectCommissionUniteUpdateRequest 统一抽佣比例
//     * @return 是否添加成功
//     */
//    @PostMapping("update/unite/rate")
//    @Operation(summary = "小程序用户一键设置项目的的抽佣比例", description = "参数：统一抽佣比例，权限：管理员，方法名：uniteProjectCommissionRate")
//    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
////    @SysLog(title = "项目明细抽佣管理", content = "小程序用户一键设置项目的的抽佣比例")
//    public BaseResponse<Boolean> uniteProjectCommissionRate(@Valid @RequestBody ProjectCommissionUniteUpdateRequest projectCommissionUniteUpdateRequest, HttpServletRequest request) {
//        Long userId = (Long) request.getAttribute("userId");
//        BigDecimal uniteCommissionRate = projectCommissionUniteUpdateRequest.getUniteCommissionRate();
//
//        // 修改项目的统一抽佣比例
//        LambdaUpdateWrapper<UserMainInfo> userMainInfoLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
//        userMainInfoLambdaUpdateWrapper.eq(UserMainInfo::getUserId, userId).set(UserMainInfo::getUniteRate, uniteCommissionRate);
//        userMainInfoService.update(userMainInfoLambdaUpdateWrapper);
//
//        LambdaQueryWrapper<ProjectCommission> projectCommissionLambdaQueryWrapper = new LambdaQueryWrapper<>();
//        projectCommissionLambdaQueryWrapper.eq(ProjectCommission::getUserId, userId);
//        List<ProjectCommission> projectCommissionList = projectCommissionService.list(projectCommissionLambdaQueryWrapper);
//
//        List<ProjectDetail> projectDetailList = commonService.findByFieldInTargetField(projectCommissionList, projectDetailService, ProjectCommission::getProjectDetailId, ProjectDetail::getId);
//        // 封装map集合（键：项目明细id, 值：项目明细最大抽佣比例）
//        Map<Long, BigDecimal> map = new HashMap<>();
//        for (ProjectDetail projectDetail : projectDetailList) {
//            map.put(projectDetail.getId(), projectDetail.getMaxCommissionRate());
//        }
//        for (ProjectCommission projectCommission : projectCommissionList) {
//            Long projectDetailId = projectCommission.getProjectDetailId();
//            BigDecimal maxCommissionRate = map.get(projectDetailId);
//            BigDecimal setCommissionRate = uniteCommissionRate.compareTo(maxCommissionRate) > 0 ? maxCommissionRate : uniteCommissionRate;
//            projectCommission.setCurrentCommissionRate(setCommissionRate);
//        }
//        projectCommissionService.updateBatchById(projectCommissionList);
//
//        // 修改下级用户的项目明细抽佣比例
//        LambdaQueryWrapper<SubUserProjectCommission> subUserProjectCommissionLambdaQueryWrapper = new LambdaQueryWrapper<>();
//        subUserProjectCommissionLambdaQueryWrapper.eq(SubUserProjectCommission::getUserId, userId);
//        List<SubUserProjectCommission> subUserProjectCommissionList = subUserProjectCommissionService.list(subUserProjectCommissionLambdaQueryWrapper);
//        for (SubUserProjectCommission subUserProjectCommission : subUserProjectCommissionList) {
//            Long projectDetailId = subUserProjectCommission.getProjectDetailId();
//            BigDecimal maxCommissionRate = map.get(projectDetailId);
//            BigDecimal setCommissionRate = uniteCommissionRate.compareTo(maxCommissionRate) > 0 ? maxCommissionRate : uniteCommissionRate;
//            subUserProjectCommission.setCurrentCommissionRate(setCommissionRate);
//        }
//        subUserProjectCommissionService.updateBatchById(subUserProjectCommissionList);
//        return ResultUtils.success(true);
//    }



    /**
     * 小程序用户一键设置项目的的抽佣比例
     * @param projectCommissionUniteUpdateRequest 统一抽佣比例
     * @return 是否添加成功
     */
    @PostMapping("update/unite/rate")
    @Operation(summary = "小程序用户一键设置项目的的抽佣比例", description = "参数：统一抽佣比例，权限：管理员，方法名：uniteProjectCommissionRate")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "项目明细抽佣管理", content = "小程序用户一键设置项目的的抽佣比例")
    public BaseResponse<Boolean> uniteProjectCommissionRate(@Valid @RequestBody ProjectCommissionUniteUpdateRequest projectCommissionUniteUpdateRequest, HttpServletRequest request) {
        projectCommissionService.uniteProjectCommissionRate(projectCommissionUniteUpdateRequest, request);
        return ResultUtils.success(true);
    }


}