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.projectCommission.ProjectCommissionAddRequest;
import com.greenorange.promotion.model.dto.projectDetail.ProjectDetailAddRequest;
import com.greenorange.promotion.model.dto.projectDetail.ProjectDetailUpdateRequest;
import com.greenorange.promotion.model.dto.subUserProjectCommission.SubUserProjectCommissionAddRequest;
import com.greenorange.promotion.model.entity.*;
import com.greenorange.promotion.model.enums.UserRoleEnum;
import com.greenorange.promotion.model.vo.projectDetail.ProjectDetailVO;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import com.greenorange.promotion.model.dto.CommonRequest;
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.stream.Collectors;


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

    @Resource
    private ProjectDetailService projectDetailService;

    @Resource
    private CommonService commonService;

    @Resource
    private ProjectCommissionService projectCommissionService;

    @Resource
    private SubUserProjectCommissionService subUserProjectCommissionService;

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private ProjectService projectService;

    @Resource
    private UserMainInfoService userMainInfoService;

    /**
     * web端管理员添加项目明细
     * @param projectDetailAddRequest 项目明细添加请求体
     * @return 是否添加成功
     */
    @PostMapping("add")
    @Operation(summary = "web端管理员添加项目明细", description = "参数：项目明细添加请求体，权限：管理员，方法名：addProjectDetail")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目明细管理", content = "web端管理员添加项目明细")
    public BaseResponse<Boolean> addProjectDetail(@Valid @RequestBody ProjectDetailAddRequest projectDetailAddRequest) {
        Long proId = projectDetailAddRequest.getProjectId();
        Project pro = projectService.getById(proId);
        ThrowUtils.throwIf(pro == null, ErrorCode.OPERATION_ERROR, "项目不存在");
        ProjectDetail projectDetail = commonService.copyProperties(projectDetailAddRequest, ProjectDetail.class);
        projectDetailService.save(projectDetail);

        // 修改项目价格
        Long pId = projectDetail.getProjectId();
        Project project = projectService.getById(pId);
        project.setProjectPrice(project.getProjectPrice().add(projectDetail.getProjectSettlementPrice()));
        projectService.updateById(project);

        // 获取所有的小程序用户
        LambdaQueryWrapper<UserInfo> miniUserInfoQueryWrapper = userInfoService.getMiniUserInfoQueryWrapper();
        miniUserInfoQueryWrapper.select(UserInfo::getId, UserInfo::getParentUserId);
        List<UserInfo> userInfoList = userInfoService.list(miniUserInfoQueryWrapper);

        List<UserMainInfo> userMainInfoList = commonService.findByFieldInTargetFieldWithSpecificFields(userInfoList, userMainInfoService, UserInfo::getId, UserMainInfo::getUserId,
                List.of(UserMainInfo::getUserId, UserMainInfo::getUniteRate));
        // 封装Map(键：用户id, 值：抽佣比例）
        Map<Long, BigDecimal> userCommissionRateMap = new HashMap<>();
        for (UserMainInfo userMainInfo : userMainInfoList) {
            userCommissionRateMap.put(userMainInfo.getUserId(), userMainInfo.getUniteRate());
        }

        // 获取参数信息
        List<ProjectCommissionAddRequest> projectCommissionAddRequestList = new ArrayList<>();
        Long projectDetailId = projectDetail.getId();
        BigDecimal projectSettlementPrice = projectDetail.getProjectSettlementPrice();
        Long projectId = projectDetail.getProjectId();

        // 给所有用户添加一条项目明细
        for (UserInfo userInfo : userInfoList) {
            ProjectCommissionAddRequest projectCommissionAddRequest = ProjectCommissionAddRequest.builder()
                    .projectDetailId(projectDetailId)
                    .myUnitPrice(projectSettlementPrice)
                    .projectId(projectId)
                    .userId(userInfo.getId())
                    .build();
            projectCommissionAddRequestList.add(projectCommissionAddRequest);
        }
        List<ProjectCommission> projectCommissions = commonService.convertList(projectCommissionAddRequestList, ProjectCommission.class);
        List<SubUserProjectCommission> userProjectCommissions = commonService.convertList(projectCommissions, SubUserProjectCommission.class);
        for (SubUserProjectCommission userProjectCommission : userProjectCommissions) {
            userProjectCommission.setSubUserId(-1L);
        }
//        projectCommissionService.saveBatch(projectCommissions);

        // 给所有用户添加一条下级项目明细抽佣表
        List<SubUserProjectCommissionAddRequest> subUserProjectCommissionAddRequestList = new ArrayList<>();
        for (UserInfo userInfo : userInfoList) {
            if (userInfo.getParentUserId() == 0) continue;
            SubUserProjectCommissionAddRequest subUserProjectCommissionAddRequest = SubUserProjectCommissionAddRequest.builder()
                    .projectDetailId(projectDetailId)
                    .myUnitPrice(projectSettlementPrice)
                    .projectId(projectId)
                    .subUserId(userInfo.getId())
                    .userId(userInfo.getParentUserId())
                    .build();
            subUserProjectCommissionAddRequestList.add(subUserProjectCommissionAddRequest);
        }
        List<SubUserProjectCommission> subUserProjectCommissions = commonService.convertList(subUserProjectCommissionAddRequestList, SubUserProjectCommission.class);
//        subUserProjectCommissionService.saveBatch(subUserProjectCommissions);
        subUserProjectCommissions.addAll(userProjectCommissions);
        // 对抽佣记录进行排序
        projectCommissionService.sortSubProjectCommissions(subUserProjectCommissions);
        // 设置抽佣比例和单价
        // 封装Map集合（键：下级用户id，值：下级用户单价）
        Map<Long, BigDecimal> subUserProjectCommissionMap = new HashMap<>();
        for (SubUserProjectCommission subUserProjectCommission : subUserProjectCommissions) {
            Long userId = subUserProjectCommission.getUserId();
            Long subUserId = subUserProjectCommission.getSubUserId();
            // 设置抽佣比例
            BigDecimal uniteRate = userCommissionRateMap.get(userId);
            subUserProjectCommission.setCurrentCommissionRate(uniteRate);
            // 设置单价
            BigDecimal myUnitPrice = subUserProjectCommissionMap.get(userId);
            if (myUnitPrice == null) myUnitPrice = subUserProjectCommission.getMyUnitPrice();
            subUserProjectCommission.setMyUnitPrice(myUnitPrice);
            BigDecimal subUserUnitPrice = projectCommissionService.calculateFinalPrice(myUnitPrice, uniteRate);
            if (subUserId != -1L) subUserProjectCommissionMap.put(subUserId, subUserUnitPrice);
        }

        long startTime = System.currentTimeMillis();

        // 批量更新下级用户项目明细抽佣记录
        List<SubUserProjectCommission> subProjectCommissions = subUserProjectCommissions.stream()
                .filter(subUserProjectCommission -> subUserProjectCommission.getSubUserId() != -1L).toList();
        subUserProjectCommissionService.saveBatch(subProjectCommissions);
        // 批量更新用户项目明细抽佣记录

        List<SubUserProjectCommission> projectCommissionList = subUserProjectCommissions.stream()
                .filter(subUserProjectCommission -> subUserProjectCommission.getSubUserId() == -1L).toList();
        List<ProjectCommission> commissionList = commonService.convertList(projectCommissionList, ProjectCommission.class);
        projectCommissionService.saveBatch(commissionList);

        // 获取结束时间戳
        long endTime = System.currentTimeMillis();
        // 计算执行时间
        long executionTime = endTime - startTime;
        System.out.println("程序执行时间: " + executionTime + " 毫秒");


        return ResultUtils.success(true);
    }
//
//    /**
//     * web端管理员根据id修改项目明细信息
//     * @param projectDetailUpdateRequest 项目明细更新请求体
//     * @return 是否更新成功
//     */
//    @PostMapping("update")
//    @Operation(summary = "web端管理员更新项目明细", description = "参数：项目明细更新请求体，权限：管理员，方法名：updateProjectDetail")
//    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目明细管理", content = "web端管理员根据id修改项目明细信息")
//    public BaseResponse<Boolean> updateProjectDetail(@Valid @RequestBody ProjectDetailUpdateRequest projectDetailUpdateRequest) {
//
//        // 更新项目明细的结算价格
//        Long projectDetailId = projectDetailUpdateRequest.getId();
//        ProjectDetail sourceProjectDetail = projectDetailService.getById(projectDetailId);
//        ProjectDetail projectDetail = commonService.copyProperties(projectDetailUpdateRequest, ProjectDetail.class);
//        // 1.更新项目明细的结算价格
//        projectDetailService.updateById(projectDetail);
//        // 更新项目的价格
//        Long projectId = projectDetail.getProjectId();
//        Project project = projectService.getById(projectId);
//        project.setProjectPrice(project.getProjectPrice().subtract(sourceProjectDetail.getProjectSettlementPrice()).add(projectDetail.getProjectSettlementPrice()));
//        projectService.updateById(project);
//        // 2.更新抽佣比例（如果抽佣比例比原来小）
//        List<SubUserProjectCommission> subUserProjectCommissionList = commonService.findByFieldEqTargetField(SubUserProjectCommission::getProjectDetailId, projectDetail.getId(), subUserProjectCommissionService);
//        for (SubUserProjectCommission subUserProjectCommission : subUserProjectCommissionList) {
//            BigDecimal currentCommissionRate = subUserProjectCommission.getCurrentCommissionRate();
//            BigDecimal maxCommissionRate = projectDetail.getMaxCommissionRate();
//            if (currentCommissionRate.compareTo(maxCommissionRate) > 0) subUserProjectCommission.setCurrentCommissionRate(maxCommissionRate);
//        }
//        // 将下级用户项目明细抽佣列表根据父级用户id进行排序（升序）
//        subUserProjectCommissionList.sort(Comparator.comparing(SubUserProjectCommission::getUserId));
//        // 更新下级用户项目明细抽佣表记录
//        BigDecimal projectSettlementPrice = projectDetail.getProjectSettlementPrice();
//        BigDecimal projectMinSettlementPrice = projectDetail.getProjectMinSettlementPrice();
//        // 封装Map集合（键：下级用户id，值：下级用户单价）
//        Map<Long, BigDecimal> subUserUnitPriceMap = new HashMap<>();
//        // 获取小程序用户的根用户
//        List<UserInfo> userInfoList = commonService.findByFieldEqTargetField(UserInfo::getUserRole, UserConstant.DEFAULT_ROLE, userInfoService);
//        UserInfo rootUserInfo = userInfoList.get(0);
//        // 存储根用户的单价
//        subUserUnitPriceMap.put(rootUserInfo.getId(), projectSettlementPrice);
//        for (SubUserProjectCommission subUserProjectCommission : subUserProjectCommissionList) {
//            // 记录上级用户的对下级用户的抽佣比例
//            BigDecimal currentCommissionRate = subUserProjectCommission.getCurrentCommissionRate();
//            Long userId = subUserProjectCommission.getUserId();
//            Long subUserId = subUserProjectCommission.getSubUserId();
//            // 获取当前用户的单价，并将当前记录修改为当前用户的单价
//            BigDecimal userUnitPrice = subUserUnitPriceMap.get(userId);
//            subUserProjectCommission.setMyUnitPrice(userUnitPrice);
//            // 计算下级用户的单价
//            BigDecimal subUserUnitPrice = userUnitPrice.multiply(BigDecimal.ONE.subtract(currentCommissionRate));
//            // 如果下级用户的单价小于项目明细最小结算价格，则设置下级用户的单价为项目明细最小结算价格
//            if (subUserUnitPrice.compareTo(projectMinSettlementPrice) < 0) subUserUnitPrice = projectMinSettlementPrice;
//            // 存储下级用户的单价
//            subUserUnitPriceMap.put(subUserId, subUserUnitPrice);
//        }
//        // 更新下级用户项目明细抽佣表记录
//        subUserProjectCommissionService.updateBatchById(subUserProjectCommissionList);
//        // 更新用户项目明细抽佣表记录
//        List<ProjectCommission> projectCommissionList = commonService.findByFieldEqTargetField(ProjectCommission::getProjectDetailId, projectDetail.getId(), projectCommissionService);
//        for (ProjectCommission projectCommission : projectCommissionList) {
//            Long userId = projectCommission.getUserId();
//            BigDecimal userUnitPrice = subUserUnitPriceMap.get(userId);
//            projectCommission.setMyUnitPrice(userUnitPrice);
//        }
//        projectCommissionService.updateBatchById(projectCommissionList);
//
//        return ResultUtils.success(true);
//    }

    /**
     * web端管理员根据id删除项目明细
     * @param commonRequest 项目明细删除请求体
     * @return 是否删除成功
     */
    @PostMapping("delete")
    @Operation(summary = "web端管理员根据id删除项目明细", description = "参数：项目明细删除请求体，权限：管理员，方法名：delProjectDetail")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目明细管理", content = "web端管理员根据id删除项目明细")
    public BaseResponse<Boolean> delProjectDetail(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        // 更新项目价格
        ProjectDetail projectDetail = projectDetailService.getById(id);
        Long projectId = projectDetail.getProjectId();
        Project project = projectService.getById(projectId);
        project.setProjectPrice(project.getProjectPrice().subtract(projectDetail.getProjectSettlementPrice()));
        projectService.updateById(project);

        // 删除对应的项目明细
        projectDetailService.removeById(id);
        // 删除对应的项目明细抽佣记录
        LambdaQueryWrapper<ProjectCommission> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ProjectCommission::getProjectDetailId, id);
        projectCommissionService.remove(lambdaQueryWrapper);

        // 删除对应的下级用户的项目明细抽佣记录
        LambdaQueryWrapper<SubUserProjectCommission> subUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        subUserLambdaQueryWrapper.eq(SubUserProjectCommission::getProjectDetailId, id);
        subUserProjectCommissionService.remove(subUserLambdaQueryWrapper);
        return ResultUtils.success(true);
    }


    /**
     * web端管理员根据id查询项目明细
     * @param commonRequest 项目明细查询请求体
     * @return 项目明细信息
     */
    @PostMapping("queryById")
    @Operation(summary = "web端管理员根据id查询项目明细", description = "参数：项目明细查询请求体，权限：管理员，方法名：queryProjectDetailById")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目明细管理", content = "web端管理员根据id查询项目明细")
    public BaseResponse<ProjectDetailVO> queryProjectDetailById(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        ProjectDetail projectDetail = projectDetailService.getById(id);
        ProjectDetailVO projectDetailVO = commonService.copyProperties(projectDetail, ProjectDetailVO.class);
        return ResultUtils.success(projectDetailVO);
    }


    /**
     * web端管理员根据项目id查询项目明细
     * @param commonRequest 项目id
     * @return 项目明细列表
     */
    @PostMapping("query/pid")
    @Operation(summary = "web端管理员根据项目id查询项目明细", description = "参数：项目id，权限：管理员，方法名：queryProjectDetailByPid")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目明细管理", content = "web端管理员根据项目id查询项目明细")
    public BaseResponse<List<ProjectDetailVO>> queryProjectDetailByPid(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        List<ProjectDetail> projectDetailList = commonService.findByFieldEqTargetField(ProjectDetail::getProjectId, id, projectDetailService);
        List<ProjectDetailVO> projectDetailVOS = commonService.convertList(projectDetailList, ProjectDetailVO.class);
        return ResultUtils.success(projectDetailVOS);
    }

}