package com.ningdatech.pmapi.performance.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisal;
import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalProject;
import com.ningdatech.pmapi.performance.model.req.PerformanceAppraisalListReq;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalProjectVO;
import com.ningdatech.pmapi.performance.model.vo.PerformanceAppraisalVO;
import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalApplicationService;
import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalProjectService;
import com.ningdatech.pmapi.performance.service.IPerformanceAppraisalService;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.sys.model.entity.Role;
import com.ningdatech.pmapi.sys.service.IRoleService;
import com.ningdatech.pmapi.user.entity.enumeration.RoleEnum;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Classname OrgSelfAppraisalManage
 * @Description
 * @Date 2023/6/19 14:18
 * @Author PoffyZhang
 */
@Component
@Slf4j
@AllArgsConstructor
public class OrgSelfAppraisalManage {

    private final IPerformanceAppraisalService performanceAppraisalService;

    private final IPerformanceAppraisalProjectService performanceAppraisalProjectService;

    private final IPerformanceAppraisalApplicationService performanceAppraisalApplicationService;

    private final IProjectService projectService;

    private final IProjectApplicationService applicationService;
    private final IRoleService roleService;

    /**
     * 绩效列表
     * @param req
     * @return
     */
    public PageVo<PerformanceAppraisalVO> list(PerformanceAppraisalListReq req) {
        UserInfoDetails user = LoginUserUtil.loginUserDetail();

        //当前登录用户 单位code
        String empPosUnitCode = user.getEmpPosUnitCode();
        // 获取当前登录用户的角色列表，只有单位管理员才能查看该列表
        List<Role> userRoleList = user.getUserRoleList();
        List<Long> roleIdList = userRoleList.stream().map(Role::getId).collect(Collectors.toList());
        Role role = roleService.getOne(Wrappers.lambdaQuery(Role.class)
                .eq(Role::getName, RoleEnum.COMPANY_MANAGER.getDesc()));
        if (Objects.isNull(role)){
            throw new BizException("系统没有单位管理员角色!");
        }

        // 登录用户不是单位管理员，不能查看本单位的自评计划列表
        if (!roleIdList.contains(role.getId())){
            return PageVo.empty();
        }

        // 获取登录用户所在单位的所有已终验项目信息
        List<Project> projectLists = projectService.list(Wrappers.lambdaQuery(Project.class)
                .eq(Project::getStatus, ProjectStatusEnum.ACCEPTED.getCode())
                .eq(Project::getBuildOrgCode, empPosUnitCode));

        if(CollUtil.isEmpty(projectLists)){
            return PageVo.empty();
        }
        List<Long> projectIds = projectLists.stream().map(Project::getId).collect(Collectors.toList());
        // 获取添加过该单位项目的所有评价计划信息
        List<PerformanceAppraisalProject> paps = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
                .in(PerformanceAppraisalProject::getProjectId, projectIds));
        if(CollUtil.isEmpty(paps)){
            return PageVo.empty();
        }
        Set<Long> paIds = paps.stream().map(PerformanceAppraisalProject::getAppraisalId).collect(Collectors.toSet());
        // 获取评价计划列表
        Page<PerformanceAppraisal> page = req.page();
        LambdaQueryWrapper<PerformanceAppraisal> wrapper = Wrappers.lambdaQuery(PerformanceAppraisal.class)
                .in(PerformanceAppraisal::getId,paIds)
                .orderByDesc(PerformanceAppraisal::getUpdateOn);
        performanceAppraisalService.page(page,wrapper);
        if(0L == page.getTotal()){
            return PageVo.empty();
        }

        List<PerformanceAppraisalVO> res = page.getRecords().stream()
                .map(p -> BeanUtil.copyProperties(p, PerformanceAppraisalVO.class))
                .collect(Collectors.toList());
        return PageVo.of(res,page.getTotal());
    }

    public PageVo<PerformanceAppraisalProjectVO> pendingList(Long planId, PerformanceAppraisalListReq req) {
        UserInfoDetails user = LoginUserUtil.loginUserDetail();

        PerformanceAppraisal plan = performanceAppraisalService.getById(planId);
        VUtils.isTrue(Objects.isNull(plan)).throwMessage("该评价计划不存在!");

        // 获取评价计划内已添加的待评价项目信息
        List<PerformanceAppraisalProject> paps = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
                .eq(PerformanceAppraisalProject::getAppraisalId, plan.getId()));
        Map<Long, PerformanceAppraisalProject> papsMap = paps.stream().collect(Collectors.toMap(PerformanceAppraisalProject::getProjectId, p -> p));

        if(CollUtil.isEmpty(paps)){
            return PageVo.empty();
        }

        // 获取本单位在当前评价计划内的项目
        Set<String> projectCodes = paps.stream().map(PerformanceAppraisalProject::getProjectCode).collect(Collectors.toSet());
        Page<Project> page = req.page();
        LambdaQueryWrapper<Project> wrapper = Wrappers.lambdaQuery(Project.class)
                .in(Project::getProjectCode, projectCodes)
                .eq(Project::getNewest, Boolean.TRUE)
                .eq(Project::getBuildOrgCode, user.getEmpPosUnitCode())
                .like(StringUtils.isNotBlank(req.getProjectName()),Project::getProjectName,req.getProjectName());
        projectService.page(page,wrapper);

        if(0L == page.getTotal()){
            return PageVo.empty();
        }

        List<PerformanceAppraisalProjectVO> res = page.getRecords().stream()
                .map(p -> {
                    PerformanceAppraisalProjectVO vo = BeanUtil.copyProperties(p, PerformanceAppraisalProjectVO.class);
                    PerformanceAppraisalProject appraisalProject = papsMap.get(p.getId());
                    vo.setProjectTypeName(ProjectTypeEnum.getDesc(p.getProjectType()));
                    vo.setIsReAppraisal(appraisalProject.getIsReAppraisal());
                    vo.setSelfAppraisalStart(appraisalProject.getSelfAppraisalStart());
                    vo.setSelfAppraisalEnd(appraisalProject.getSelfAppraisalEnd());
                    vo.setCanSelfAppraisal(checkCanSelfAppraisal(appraisalProject));
                    return vo;
                })
                .collect(Collectors.toList());

        return PageVo.of(res,page.getTotal());
    }

    /**
     * 已经自评表
     * @param planId
     * @return
     */
    public PageVo<PerformanceAppraisalProjectVO> appraisaledList(Long planId) {

        return PageVo.empty();
    }

    /**
     * 是否可以自评
     * @param appraisalProject
     * @return
     */
    private Boolean checkCanSelfAppraisal(PerformanceAppraisalProject appraisalProject) {
        if(LocalDateTime.now().compareTo(appraisalProject.getSelfAppraisalStart()) > 0 &&
                LocalDateTime.now().compareTo(appraisalProject.getSelfAppraisalEnd()) < 0){
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
}
