package com.ningdatech.pmapi.projectdeclared.manage;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.pmapi.common.helper.UserInfoHelper;
import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO;
import com.ningdatech.pmapi.projectdeclared.model.req.AdjustmentListReq;
import com.ningdatech.pmapi.projectdeclared.utils.ReStartProcessMapUtil;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage;
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication;
import com.ningdatech.pmapi.projectlib.model.req.ProjectListReq;
import com.ningdatech.pmapi.projectlib.model.vo.ProjectLibListItemVO;
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import com.wflow.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Classname ProjectAdjustmentManage
 * @Description 项目内容调整
 * @Date 2023/2/1 14:48
 * @Author PoffyZhang
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class ProjectAdjustmentManage {

    private final IProjectService projectService;

    private final IProjectApplicationService projectApplicationService;

    private final ReStartProcessMapUtil reStartProcessMapUtil;

    private final DefaultDeclaredProjectManage defaultDeclaredProjectManage;

    private final ProjectLibManage projectLibManage;

    private final UserInfoHelper userInfoHelper;

    /**
     * 项目内容调整
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String adjustment(DefaultDeclaredDTO dto) {
        ProjectDTO projectDto = dto.getProjectInfo();
        Project projectInfo = projectService.getById(projectDto.getId());

        VUtils.isTrue(Objects.isNull(projectInfo)).throwMessage("调整失败 此项目不存在!");

        //项目名称去重
        defaultDeclaredProjectManage.checkDuplication(projectDto);

        //修改项目内容
        if(!modifyProject(projectDto)){
            throw new BusinessException("调整项目失败!");
        }

        //最后去重新 提交项目流程 不同的状态 提交到不同的工作流去
        Function<DefaultDeclaredDTO, String> declaredFunction =
                reStartProcessMapUtil.reStartProcessMap.get(projectInfo.getStatus());
        VUtils.isTrue(Objects.isNull(declaredFunction)).throwMessage("状态不正常 没有找到对应申报函数!");
        return declaredFunction.apply(dto);
    }

    private Boolean modifyProject(ProjectDTO projectDto) {
        //先修改项目信息
        Project project = new Project();
        BeanUtils.copyProperties(projectDto,project);
        project.setUpdateOn(LocalDateTime.now());
        if(!projectService.updateById(project)){
            throw new BusinessException("项目调整失败");
        }
        //再修改应用信息
        if(CollUtil.isNotEmpty(projectDto.getApplicationList())){
            //采取批量删除 批量添加的方式
            projectApplicationService.remove(Wrappers.lambdaQuery(ProjectApplication.class)
                    .eq(ProjectApplication::getProjectId,project.getId()));
            //批量添加
            List<ProjectApplication> applications = projectDto.getApplicationList().stream().map(application -> {
                ProjectApplication projectApplication = new ProjectApplication();
                BeanUtils.copyProperties(application, projectApplication);
                projectApplication.setProjectId(project.getId());
                return projectApplication;
            }).collect(Collectors.toList());
            projectApplicationService.saveBatch(applications);
        }
        return Boolean.TRUE;
    }

    /**
     * 项目库
     * @param preReq
     * @return
     */
    public PageVo<ProjectLibListItemVO> projectLibList(AdjustmentListReq preReq) {
        //限定参数 复制bean
        ProjectListReq req = new ProjectListReq();
        BeanUtils.copyProperties(preReq,req);
        //项目阶段 状态 已定 方案待申报
        req.setStageList(Arrays.asList(ProjectStatusEnum.NOT_APPROVED.getCode()));
        //只有 单位内部审核不通过 省级联审不通过 预审不通过 建设方案不通过 4种状态
        req.setStatusList(Arrays.asList(ProjectStatusEnum.UNDER_INTERNAL_AUDIT_NOT_PASS.getCode(),
                ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode(),
                ProjectStatusEnum.THE_JOINT_REVIEW_OF_PROVINCIAL_DEPARTMENTS_FAILED.getCode(),
                ProjectStatusEnum.SCHEME_REVIEW_FAILED.getCode()));
        Long userId = LoginUserUtil.getUserId();
        VUtils.isTrue(Objects.isNull(userId)).throwMessage("获取登录用户失败!");
        UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userId);
        //放入用户的单位
        req.setBuildOrgCode(userFullInfo.getOrganizationCode());
        return projectLibManage.projectLibList(req);
    }
}
