package com.greenorange.promotion.controller.project;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.project.ProjectAddRequest;
import com.greenorange.promotion.model.dto.project.ProjectQueryRequest;
import com.greenorange.promotion.model.dto.project.ProjectUpdateRequest;
import com.greenorange.promotion.model.entity.*;
import com.greenorange.promotion.model.vo.project.ProjectCardVO;
import com.greenorange.promotion.model.vo.project.ProjectAllDetailVO;
import com.greenorange.promotion.model.vo.project.ProjectPageVO;
import com.greenorange.promotion.model.vo.project.ProjectVO;
import com.greenorange.promotion.model.vo.projectDetail.ProjectDetailVO;
import com.greenorange.promotion.model.vo.projectNotification.ProjectNotificationVO;
import com.greenorange.promotion.model.vo.promoCodeApply.PromoCodeApplyVO;
import com.greenorange.promotion.model.vo.userProject.UserProjectVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.project.*;
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.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 项目 控制器
 */
@RestController
@RequestMapping("project")
@Slf4j
@Tag(name = "项目管理")
@Transactional
public class ProjectController {

    @Resource
    private ProjectService projectService;

    @Resource
    private CommonService commonService;

    @Resource
    private ProjectDetailService projectDetailService;

    @Resource
    private ProjectNotificationService projectNotificationService;

    @Resource
    private PromoCodeService promoCodeService;

    @Resource
    private ProjectCommissionService projectCommissionService;

    @Resource
    private SubUserProjectCommissionService subUserProjectCommissionService;

    @Resource
    private UserProjectService userProjectService;

    @Resource
    private PromoCodeApplyService promoCodeApplyService;



    /**
     * 小程序用户查看项目列表
     * @return 项目列表
     */
    @PostMapping("query/card")
    @Operation(summary = "小程序用户查看项目列表", description = "参数：无，权限：管理员，方法名：queryProjectCardList")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "项目管理", content = "小程序用户查看项目列表")
    public BaseResponse<List<ProjectCardVO>> queryProjectCardList(HttpServletRequest request) {
        List<ProjectCardVO> projectCardVOS = projectService.queryProjectCardList(request);
        return ResultUtils.success(projectCardVOS);
    }

    /**
     * 小程序用户根据id查询项目详情
     * @param commonRequest 项目id
     * @return 项目详情
     */
    @PostMapping("query/id")
    @Operation(summary = "小程序用户根据id查询项目详情", description = "参数：无，权限：管理员，方法名：queryProjectDetailById")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "项目管理", content = "小程序用户根据id查询项目详情")
    public BaseResponse<ProjectAllDetailVO> queryProjectDetailById(@Valid @RequestBody CommonRequest commonRequest, HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        Long id = commonRequest.getId();
        Project project = projectService.getById(id);
        ProjectAllDetailVO projectAllDetailVO = commonService.copyProperties(project, ProjectAllDetailVO.class);
        // 获取项目通知列表
        List<ProjectNotification> projectNotificationList = commonService.findByFieldEqTargetField(ProjectNotification::getProjectId, id, projectNotificationService);
        List<ProjectNotificationVO> projectNotificationVOS = commonService.convertList(projectNotificationList, ProjectNotificationVO.class);
        // 获取项目明细列表
        List<ProjectDetail> projectDetailList = commonService.findByFieldEqTargetField(ProjectDetail::getProjectId, id, projectDetailService);
        List<ProjectDetailVO> projectDetailVOS = commonService.convertList(projectDetailList, ProjectDetailVO.class);
        // 将项目明细的价格修改为当前用户的单价
        Map<SFunction<ProjectCommission, ?>, Object> fieldConditions = Map.of(ProjectCommission::getUserId, userId, ProjectCommission::getProjectId, id);
        List<ProjectCommission> projectCommissionList = commonService.findByFieldEqTargetFieldsWithSpecificColumns(fieldConditions, projectCommissionService,
                List.of(ProjectCommission::getProjectDetailId, ProjectCommission::getMyUnitPrice));
        // 封装Map集合（键：项目明细id, 值：项目结算价格）
        Map<Long, BigDecimal> projectCommissionMap = new HashMap<>();
        for (ProjectCommission projectCommission : projectCommissionList) {
            Long projectDetailId = projectCommission.getProjectDetailId();
            BigDecimal projectSettlementPrice = projectCommission.getMyUnitPrice();
            projectCommissionMap.put(projectDetailId, projectSettlementPrice);
        }
        // 修改项目明细的结算价格
        BigDecimal projectPrice = BigDecimal.ZERO;
        for (ProjectDetailVO projectDetailVO : projectDetailVOS) {
            BigDecimal projectSettlementPrice = projectCommissionMap.get(projectDetailVO.getId());
            projectDetailVO.setProjectSettlementPrice(projectSettlementPrice);
            projectPrice = projectPrice.add(projectSettlementPrice == null ? BigDecimal.ZERO : projectSettlementPrice);
        }
        // 更新项目价格
        projectAllDetailVO.setProjectPrice(projectPrice);
        // 获取用户申请的推广码列表
        Map<SFunction<PromoCodeApply, ?>, Object> promoConditions = Map.of(PromoCodeApply::getUserId, userId, PromoCodeApply::getProjectId, id);
        List<PromoCodeApply> promoCodeApplyList = commonService.findByFieldEqTargetFields(promoConditions, promoCodeApplyService);
        List<PromoCodeApplyVO> promoCodeApplyVOList = commonService.convertList(promoCodeApplyList, PromoCodeApplyVO.class);
        // 填充项目详情VO
        projectAllDetailVO.setProjectNotificationVOList(projectNotificationVOS);
        projectAllDetailVO.setProjectAllDetailVOList(projectDetailVOS);
        projectAllDetailVO.setPromoCodeApplyVOList(promoCodeApplyVOList);

        return ResultUtils.success(projectAllDetailVO);
    }


    /**
     * 小程序用户查看正在推广的项目
     * @return 推广的项目列表
     */
    @PostMapping("get/running")
    @Operation(summary = "小程序用户查看正在推广的项目", description = "参数：无，权限：管理员，方法名：queryUserProjectList")
    @RequiresPermission(mustRole = UserConstant.DEFAULT_ROLE)
//    @SysLog(title = "项目管理", content = "小程序用户查看正在推广的项目")
    public BaseResponse<List<UserProjectVO>> queryUserProjectList(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        List<UserProject> userProjectList = commonService.findByFieldEqTargetField(UserProject::getUserId, userId, userProjectService);
        List<UserProjectVO> userProjectVOS = commonService.convertList(userProjectList, UserProjectVO.class);
        return ResultUtils.success(userProjectVOS);
    }



    /**
     * web端管理员添加项目
     * @param projectAddRequest 项目添加请求体
     * @return 是否添加成功
     */
    @PostMapping("add")
    @Operation(summary = "web端管理员添加项目", description = "参数：项目添加请求体，权限：管理员，方法名：addProject")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目管理", content = "web端管理员添加项目")
    public BaseResponse<Long> addProject(@Valid @RequestBody ProjectAddRequest projectAddRequest) {
        Project project = commonService.copyProperties(projectAddRequest, Project.class);
        projectService.save(project);
        return ResultUtils.success(project.getId());
    }

    /**
     * web端管理员根据id修改项目信息
     * @param projectUpdateRequest 项目更新请求体
     * @return 是否更新成功
     */
    @PostMapping("update")
    @Operation(summary = "web端管理员更新项目", description = "参数：项目更新请求体，权限：管理员，方法名：updateProject")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目管理", content = "web端管理员根据id修改项目信息")
    public BaseResponse<Boolean> updateProject(@Valid @RequestBody ProjectUpdateRequest projectUpdateRequest) {
        Project project = commonService.copyProperties(projectUpdateRequest, Project.class);
        projectService.updateById(project);
        // 批量修改用户项目记录
        List<UserProject> userProjectList = commonService.findByFieldEqTargetFieldWithSpecificFields(UserProject::getProjectId, project.getId(), userProjectService,
                List.of(UserProject::getId));
        for (UserProject userProject : userProjectList) {
            userProject.setProjectName(project.getProjectName());
            userProject.setProjectImage(project.getProjectImage());
            userProject.setProjectSettlementCycle(project.getProjectSettlementCycle());
        }
        userProjectService.updateBatchById(userProjectList);
        return ResultUtils.success(true);
    }

    /**
     * web端管理员根据id删除项目
     * @param commonRequest 项目删除请求体
     * @return 是否删除成功
     */
    @PostMapping("delete")
    @Operation(summary = "web端管理员根据id删除项目", description = "参数：项目删除请求体，权限：管理员，方法名：delProject")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目管理", content = "web端管理员根据id删除项目")
    public BaseResponse<Boolean> delProject(@Valid @RequestBody CommonRequest commonRequest) {
        Long id = commonRequest.getId();
        projectService.removeById(id);
        // 删除项目明细
        LambdaQueryWrapper<ProjectDetail> projectDetailLambdaQueryWrapper = commonService.buildQueryWrapperByField(ProjectDetail::getProjectId, id, projectDetailService);
        projectDetailService.remove(projectDetailLambdaQueryWrapper);
        // 删除项目通知
        LambdaQueryWrapper<ProjectNotification> projectNotificationLambdaQueryWrapper = commonService.buildQueryWrapperByField(ProjectNotification::getProjectId, id, projectNotificationService);
        projectNotificationService.remove(projectNotificationLambdaQueryWrapper);
        // 删除项目推广码
        LambdaQueryWrapper<PromoCode> promoCodeLambdaQueryWrapper = commonService.buildQueryWrapperByField(PromoCode::getProjectId, id, promoCodeService);
        promoCodeService.remove(promoCodeLambdaQueryWrapper);
        // 删除项目明细抽佣记录
        LambdaQueryWrapper<ProjectCommission> projectCommissionLambdaQueryWrapper = commonService.buildQueryWrapperByField(ProjectCommission::getProjectId, id, projectCommissionService);
        projectCommissionService.remove(projectCommissionLambdaQueryWrapper);
        // 删除下级用户项目明细抽佣记录
        LambdaQueryWrapper<SubUserProjectCommission> subUserProjectCommissionLambdaQueryWrapper = commonService.buildQueryWrapperByField(SubUserProjectCommission::getProjectId, id, subUserProjectCommissionService);
        subUserProjectCommissionService.remove(subUserProjectCommissionLambdaQueryWrapper);
        // 删除用户项目记录
        LambdaQueryWrapper<UserProject> userProjectLambdaQueryWrapper = commonService.buildQueryWrapperByField(UserProject::getUserId, id, userProjectService);
        userProjectService.remove(userProjectLambdaQueryWrapper);

        return ResultUtils.success(true);
    }

//    /**
//     * web端管理员批量删除项目
//     * @param commonBatchRequest 项目批量删除请求体
//     * @return 是否删除成功
//     */
//    @PostMapping("delBatch")
//    @Operation(summary = "web端管理员批量删除项目", description = "参数：项目批量删除请求体，权限：管理员，方法名：delBatchProject")
//    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目管理", content = "web端管理员批量删除项目")
//    public BaseResponse<Boolean> delBatchProject(@Valid @RequestBody CommonBatchRequest commonBatchRequest) {
//        List<Long> ids = commonBatchRequest.getIds();
//        projectService.removeByIds(ids);
//        return ResultUtils.success(true);
//    }

    /**
     * web端管理员根据id查询项目
     * @param commonRequest 项目查询请求体
     * @return 项目信息
     */
    @PostMapping("queryById")
    @Operation(summary = "web端管理员根据id查询项目", description = "参数：项目查询请求体，权限：管理员，方法名：queryProjectById")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目管理", content = "web端管理员根据id查询项目")
    public BaseResponse<ProjectVO> queryProjectById(@Valid @RequestBody CommonRequest commonRequest) {
        ProjectVO projectVO = projectService.queryProjectById(commonRequest);
        return ResultUtils.success(projectVO);
    }

    /**
     * Web端管理员分页查询项目
     * @param projectQueryRequest 项目查询请求体
     * @return 项目列表
     */
    @PostMapping("page")
    @Operation(summary = "Web端管理员分页查询项目", description = "参数：项目查询请求体，权限：管理员，方法名：listProjectByPage")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目管理", content = "Web端管理员分页查询项目")
    public BaseResponse<Page<ProjectPageVO>> listProjectByPage(@Valid @RequestBody ProjectQueryRequest projectQueryRequest) {
        long current = projectQueryRequest.getCurrent();
        long pageSize = projectQueryRequest.getPageSize();
        QueryWrapper<Project> queryWrapper = projectService.getQueryWrapper(projectQueryRequest);
        Page<Project> page = projectService.page(new Page<>(current, pageSize), queryWrapper);
        List<Project> projectList = page.getRecords();
        List<ProjectPageVO> projectPageVOS = commonService.convertList(projectList, ProjectPageVO.class);
        Page<ProjectPageVO> voPage = new Page<>(current, pageSize);
        voPage.setRecords(projectPageVOS);
        voPage.setPages(page.getPages());
        voPage.setTotal(page.getTotal());
        return ResultUtils.success(voPage);
    }

    /**
     * Web端管理员上(下)架项目
     * @param commonRequest 项目id
     * @return 是否更新成功
     */
    @PostMapping("shelves")
    @Operation(summary = "Web端管理员上(下)架项目", description = "参数：项目id，权限：管理员(admin, boss)，方法名：updateProjectShelvesStatus")
    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目管理", content = "Web端管理员上(下)架项目")
    public BaseResponse<Boolean> updateProjectShelvesStatus(@Valid @RequestBody CommonRequest commonRequest) {
        // 获取当前服务类商品的上(下)架状态
        Long id = commonRequest.getId();
        Project project = projectService.getById(id);
        Boolean isShelves = project.getIsShelves();
        LambdaUpdateWrapper<Project> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Project::getId, id).set(Project::getIsShelves, !isShelves);
        projectService.update(updateWrapper);
        return ResultUtils.success(true);
    }

//    /**
//     * Web端管理员根据项目id修改项目状态
//     * @param projectStatusUpdateRequest 项目状态更新请求体
//     * @return 是否更新成功
//     */
//    @PostMapping("status")
//    @Operation(summary = "Web端管理员根据项目id修改项目状态", description = "参数：项目id，权限：管理员(admin, boss)，方法名：updateProjectStatus")
//    @RequiresPermission(mustRole = UserConstant.ADMIN_ROLE)
//    @SysLog(title = "项目管理", content = "Web端管理员根据项目id修改项目状态")
//    public BaseResponse<Boolean> updateProjectStatus(@Valid @RequestBody ProjectStatusUpdateRequest projectStatusUpdateRequest) {
//        Long id = projectStatusUpdateRequest.getId();
//        String projectStatus = projectStatusUpdateRequest.getProjectStatus();
//        LambdaUpdateWrapper<Project> updateWrapper = new LambdaUpdateWrapper<>();
//        updateWrapper.eq(Project::getId, id).set(Project::getProjectStatus, projectStatus);
//        projectService.update(updateWrapper);
//        return ResultUtils.success(true);
//    }


}