package cn.wisenergy.service.impl;

import cn.wisenergy.common.utils.DateUtil;
import cn.wisenergy.common.utils.exception.BASE_RESP_CODE_ENUM;
import cn.wisenergy.common.utils.exception.BaseCustomException;
import cn.wisenergy.mapper.WorkProjectMapper;
import cn.wisenergy.mapper.WorkTimeOrderMapper;
import cn.wisenergy.mapper.WorkUserMapper;
import cn.wisenergy.model.app.*;
import cn.wisenergy.model.dto.*;
import cn.wisenergy.model.enums.ProjectTypeEnum;
import cn.wisenergy.model.enums.StatusEnum;
import cn.wisenergy.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author chenqi
 * @since 2021-01-19
 */
@Service
@Slf4j
public class WorkTimeOrderServiceImpl implements WorkTimeOrderService {

    @Autowired
    private WorkUserService workUserService;

    @Autowired
    private WorkUserMapper workUserMapper;

    @Autowired
    private WorkProjectService workProjectService;

    @Autowired
    private WorkProjectMapper workProjectMapper;

    @Autowired
    private WorkTimeOrderMapper workTimeOrderMapper;

    @Autowired
    private WorkDeptService workDeptService;

    @Autowired
    private WorkSubmitAdoptService workSubmitAdoptService;

    @Autowired
    private WorkHolidayService workHolidayService;

    @Autowired
    private WorkCollectService workCollectService;

    @Autowired
    private WorkUserDeptService workUserDeptService;

    @Autowired
    private WorkUserProjectService workUserProjectService;

    @Autowired
    private WorkTypeService workTypeService;

    //填报类型
    private final static Integer PROJECT = ProjectTypeEnum.PROJECT.getType();
    private final static Integer BUSINESS_OPPORTUNITY = ProjectTypeEnum.BUSINESS_OPPORTUNITY.getType();
    private final static Integer LEAVE = ProjectTypeEnum.LEAVE.getType();
    private final static Integer COMPENSATORY_LEAVE = ProjectTypeEnum.COMPENSATORY_LEAVE.getType();
    private final static Integer EXTERNAL_BUSINESS = ProjectTypeEnum.EXTERNAL_BUSINESS.getType();
    private final static Integer INTERNAL_TRAINING = ProjectTypeEnum.INTERNAL_TRAINING.getType();
    private final static Integer OTHER_NON_PROJECTS = ProjectTypeEnum.OTHER_NON_PROJECTS.getType();
    // 工单状态
    private final static Integer COMPLETED = StatusEnum.COMPLETED.getCode();
    private final static Integer APPROVED = StatusEnum.APPROVED.getCode();
    private final static Integer REJECTED = StatusEnum.REJECTED.getCode();
    private final static Integer RE_SUBMIT = StatusEnum.RE_SUBMIT.getCode();
    private final static Integer AUTOMATIC_AUDIT = StatusEnum.AUTOMATIC_AUDIT.getCode();

    /**
     * 功能; 获取某日填报情况
     *
     * @param userId  用户id
     * @param workDay 某日
     * @return 工单集合
     */
    @Override

    public List<WorkTimeOrder> getByDay(Integer userId, Date workDay) {
        log.info("WorkTimeOrderServiceImpl[]getByDay[]input.param.userId:{},workDay:{}" + userId, workDay);

        if (null == userId || null == workDay) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        List<WorkTimeOrder> workTimeOrders = workTimeOrderMapper.getByDay(userId, workDay);
        if (CollectionUtils.isEmpty(workTimeOrders)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_INFO_IS_NULL);
        }

        return workTimeOrders;
    }

    /**
     * 功能：获取某日填报小计
     *
     * @param userId  用户id
     * @param workDay 某日
     * @return 填报小计
     */
    @Override
    public SubtotalDto getSubtotalReport(Integer userId, Date workDay) {
        log.info("WorkTimeOrderServiceImpl[]getSubtotalReport[]input.param.userId:{},workDay:{}" + userId, workDay);
        if (null == userId || StringUtils.isEmpty(workDay)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }

        List<WorkTimeOrder> workTimeOrders = getByDay(userId, workDay);
        if (CollectionUtils.isEmpty(workTimeOrders)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_INFO_IS_NULL);
        }
        SubtotalDto subtotalDto = new SubtotalDto();
        // 今日总工时
        int totalTime = 0;
        // 被驳回原因
        StringBuilder reason = new StringBuilder();
        // 今日被驳回次数
        int rejectMonth = 0;
        subtotalDto.setUserId(userId);
        subtotalDto.setWorkDay(workDay);
        for (WorkTimeOrder wto : workTimeOrders) {
            totalTime += wto.getWorkTime();
            if (null != wto.getReason() && REJECTED.equals(wto.getStatus()) && reason.toString().equals("")) {
                if (PROJECT.equals(wto.getType()) || BUSINESS_OPPORTUNITY.equals(wto.getType())) {
                    reason.append(workProjectService.getById(wto.getProjectId()).getProjectName()).append(":").append(wto.getReason()).append(";");
                }
                if (!PROJECT.equals(wto.getType()) && !BUSINESS_OPPORTUNITY.equals(wto.getType())) {
                    for (ProjectTypeEnum value : ProjectTypeEnum.values()) {
                        if (value.getType().equals(wto.getType())) {
                            reason.append(value.getTypeName()).append(":").append(wto.getReason()).append(";");
                        }
                    }
                }
            }
        }

        List<WorkTimeOrder> timeOrders = workTimeOrderMapper.geByMonth(userId, workDay, REJECTED);
        if (!CollectionUtils.isEmpty(timeOrders)) {
            rejectMonth = timeOrders.size();
        }

        subtotalDto.setReason(reason.toString());
        subtotalDto.setTotalTime(totalTime);
        subtotalDto.setRejectMonth(rejectMonth);
        return subtotalDto;
    }

    /**
     * 功能; 获取某日填报信息
     *
     * @param userId  用户id
     * @param workDay 工作日
     * @return dto
     */
    @Override
    public List<WorkTimeOrder> getByDayToDto(Integer userId, Date workDay) {
        log.info("WorkTimeOrderServiceImpl[]getByDayToDto[]input.param.userId:{},workDay:{}" + userId, workDay);
        List<WorkTimeOrder> workTimeOrders = getByDay(userId, workDay);
        if (CollectionUtils.isEmpty(workTimeOrders)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_INFO_IS_NULL);
        }
        return workTimeOrders;
    }


    /**
     * 功能：测试添加
     *
     * @param createWorkOrderDto dto
     * @return dto
     */
    @Transactional
    @Override
    public List<WorkTimeOrderDto> addOrder(CreateWorkOrderDto createWorkOrderDto) {
        log.info("WorkTimeOderServiceImpl[]addTest[]input.param.creatWorkOrderDto" + createWorkOrderDto);
        if (null == createWorkOrderDto || CollectionUtils.isEmpty(createWorkOrderDto.getWorkTimeOrders())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_INFO_IS_NULL);
        }

        List<WorkTimeOrderDto> workTimeOrders = createWorkOrderDto.getWorkTimeOrders();
        Date date = new Date();
        WorkSubmitAdopt workSubmitAdopt = workSubmitAdoptService.getById(1);
        Integer autoExamine = workSubmitAdopt.getAutoExamine();

        // 1.判断是否重复填报
        isRepeat(workTimeOrders);
        // 2.每天工时累加不得超过八小时
        timeNotEight(0, workTimeOrders);
        int totalTime = 0;
        List<WorkTimeOrder> addList = new ArrayList<>();
        for (WorkTimeOrderDto dto : workTimeOrders) {
            // 3.判断工单是否合法
            isEmpty(dto);

            // 获取用户名和类型名
            Integer type = dto.getType();
            dto.setUserName(workUserService.getById(dto.getUserId()).getName());
            dto.setTypeName(getTypeName(type));
            if (PROJECT.equals(type) || BUSINESS_OPPORTUNITY.equals(type)) {
                dto.setProjectName(workProjectService.getById(dto.getProjectId()).getProjectName());
                dto.setManagerName(workUserService.getById(workProjectService.getById(dto.getProjectId()).getManagerId()).getName());
            }
            if (!PROJECT.equals(type) && !BUSINESS_OPPORTUNITY.equals(type)) {
                dto.setManagerName(workUserService.getById(workTypeService.getByDeptId(workUserService.getById(dto.getUserId()).getDeptId()).get(0).getManagerId()).getName());
            }
            // 设置状态
            if (null == dto.getStatus() || 0 == dto.getStatus()) {
                dto.setStatus(COMPLETED);
            }
            if (null != dto.getStatus() && REJECTED.equals(dto.getStatus())) {
                dto.setStatus(RE_SUBMIT);
            }
            // 是否加班
            dto.setIsOvertime(0);
            if (workHolidayService.isHoliday(dto.getWorkDay())) {
                dto.setIsOvertime(1);
            }
            // 是否已经审批
            WorkTimeOrder workTimeOrder = new WorkTimeOrder();
            workTimeOrder.setDeptId(workUserDeptService.getDeptIdByUserId(dto.getUserId()));
            BeanUtils.copyProperties(dto, workTimeOrder);
            totalTime += dto.getWorkTime();
            if (dto.getWorkId() != null) {
                WorkTimeOrder workTimeOrder1 = workTimeOrderMapper.selectById(dto.getWorkId());
                if (2 == workTimeOrder1.getStatus() || 5 == workTimeOrder1.getStatus()) {
                    if (!dto.getStatus().equals(workTimeOrder1.getStatus())) {
                        throw new BaseCustomException(BASE_RESP_CODE_ENUM.ORDER_EXAMINE);
                    }
                    continue;
                }
            }
            BeanUtils.copyProperties(workTimeOrder, dto);
            addList.add(workTimeOrder);
        }

        for (WorkTimeOrder dto : addList) {
            // 4、默认设置超过系统默认3天（包括驳回3天）未填报的工时将不能填报
            if (!REJECTED.equals(dto.getStatus()) && !RE_SUBMIT.equals(dto.getStatus())) {
                if (date.getTime() - dto.getWorkDay().getTime() > autoExamine * 24 * 60 * 60 * 1000) {
                    throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_DAY_THAN_DATE);
                }
            }
            if (REJECTED.equals(dto.getStatus()) || RE_SUBMIT.equals(dto.getStatus())) {
                Date modifyTime = DateUtil.convertStrToDate(DateUtil.convertDateToStr(workTimeOrderMapper.selectById(dto.getWorkId()).getModifyTime(), "yyyy-MM-dd"), "yyyy-MM-dd");
                System.out.println(modifyTime);
                if (date.getTime() - modifyTime.getTime() > autoExamine * 24 * 60 * 60 * 1000) {
                    throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_DAY_THAN_DATE);
                }
            }
        }

        // 删除数据库还没有审批的工单，添加填报没有审批的工单
        UpdateWrapper<WorkTimeOrder> wrapper = new UpdateWrapper<>();
        wrapper.eq("user_id", workTimeOrders.get(0).getUserId());
        wrapper.eq("work_day", workTimeOrders.get(0).getWorkDay());
        wrapper.notIn("status", 2, 5);
        workTimeOrderMapper.delete(wrapper);
        for (WorkTimeOrder workTimeOrder : addList) {
            workTimeOrderMapper.save(workTimeOrder);
        }
        // 更新collect表
        int status = statusYes(workTimeOrders.get(0).getUserId(), workTimeOrders.get(0).getWorkDay());
        WorkCollect workCollect = workCollectService.getByUserIdAndWorkDay(workTimeOrders.get(0).getUserId(), workTimeOrders.get(0).getWorkDay());
        if (null == workCollect) {
            workCollect = new WorkCollect();
            BeanUtils.copyProperties(workTimeOrders.get(0), workCollect);
            workCollect.setTotalTime(totalTime);
            workCollect.setStatus(status);
            workCollectService.insertCollect(workCollect);
        }
        if (null != workCollect) {
            workCollect = new WorkCollect();
            BeanUtils.copyProperties(workTimeOrders.get(0), workCollect);
            workCollect.setTotalTime(totalTime);
            workCollect.setStatus(status);
            workCollectService.update(workCollect);
        }
        return workTimeOrders;
    }




    // 判断填写工时单是否重复
    private void isRepeat(List<WorkTimeOrderDto> list) {
        if (CollectionUtils.isEmpty(list)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        int size = list.size();
        for (int i = 0; i < size; i++) {
            for (int j = i + 1; j < size; j++) {
                if (list.get(i).getType().equals(list.get(j).getType())) {
                    if (null != list.get(i).getProjectId() && null != list.get(j).getProjectId() && !list.get(i).getProjectId().equals(list.get(j).getProjectId())) {
                        continue;
                    }
                    throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_ALREADY_COMMIT);
                }
            }
        }
    }

    /**
     * 功能：获取待审批数据
     *
     * @param userId    用户id
     * @param projectId 项目id
     * @param type      项目类型
     * @param status    状态
     * @return 自定义dto
     */
    @Override
    public PageInfo<WorkTimeOrderDto> getExamine(Integer userId, Integer projectId, Integer type, Integer page, Integer size, Integer status) {
        log.info("WorkOrderServiceImpl[]getExamine[]input.param.userId:{},projectId:{},type:{},page:{},size:{},status:{}" + userId, projectId, type, page, size, status);
        // 判断当前用户是否是管理员
        isManager(userId);
        WorkUser user = workUserService.getById(userId);
        // PC端

        return pageExamine(user, projectId, type, page, size, status);
    }

    /**
     * 功能：获取小程序待审批
     *
     * @param userId    用户id
     * @param projectId 项目Id
     * @param type      类型
     * @return dto
     */
    @Override
    public List<AppletsPendApprovalDto> getExamineApplets(Integer userId, Integer projectId, Integer type) {
        log.info("WorkOrderServiceImpl[]getExamineApplets[]input.param.userId:{},projectId:{},type:{}" + userId, projectId, type);
        isManager(userId);
        WorkUser user = workUserService.getById(userId);
        if (null == projectId && null == type) {
            return null;
        }
        if (0 != user.getLevel()) {
            QueryWrapper<WorkTimeOrder> wrapper = new QueryWrapper<>();
            wrapper.in("status", COMPLETED, RE_SUBMIT);
            wrapper.eq(type != null, "type", type);
            wrapper.eq(type != null, "dept_id", user.getDeptId());
            wrapper.eq(projectId != null, "project_id", projectId);
            wrapper.orderByDesc("work_day");
            List<WorkTimeOrder> workTimeOrders = workTimeOrderMapper.selectList(wrapper);
            if (CollectionUtils.isEmpty(workTimeOrders)) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_END);
            }
            return getDto(workTimeOrders);
        }
        throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_END);
    }

    // 封装可填报的数据
    private List<AppletsPendApprovalDto> getDto(List<WorkTimeOrder> workTimeOrders) {
        List<AppletsPendApprovalDto> appletsPendApprovalDtos = new ArrayList<>();
        Date date = workTimeOrders.get(0).getWorkDay();
        AppletsPendApprovalDto dto = new AppletsPendApprovalDto();
        dto.setWorkDay(date);
        appletsPendApprovalDtos.add(dto);
        for (WorkTimeOrder workTimeOrder : workTimeOrders) {
            if (date.compareTo(workTimeOrder.getWorkDay()) != 0) {
                date = workTimeOrder.getWorkDay();
                AppletsPendApprovalDto dto2 = new AppletsPendApprovalDto();
                dto2.setWorkDay(workTimeOrder.getWorkDay());
                appletsPendApprovalDtos.add(dto2);
            }
        }
        for (WorkTimeOrder workTimeOrder : workTimeOrders) {
            System.out.println(workTimeOrder);
        }
        for (AppletsPendApprovalDto approvalDto : appletsPendApprovalDtos) {
            List<WorkTimeOrderDto> workTimeOrderList = new ArrayList<>();
            for (WorkTimeOrder workTimeOrder : workTimeOrders) {
                if (approvalDto.getWorkDay().compareTo(workTimeOrder.getWorkDay()) == 0) {
                    WorkTimeOrderDto workTimeOrderDto = new WorkTimeOrderDto();
                    BeanUtils.copyProperties(workTimeOrder, workTimeOrderDto);
                    workTimeOrderDto.setManagerName(workUserService.getById(workTypeService.getByDeptId(workTimeOrder.getDeptId()).get(0).getManagerId()).getName());
                    workTimeOrderDto.setUserName(workUserService.getById(workTimeOrderDto.getUserId()).getName());
                    if (PROJECT.equals(workTimeOrder.getType()) || BUSINESS_OPPORTUNITY.equals(workTimeOrder.getType())) {
                        workTimeOrderDto.setProjectName(workProjectService.getById(workTimeOrderDto.getProjectId()).getProjectName());
                        workTimeOrderDto.setManagerName(workUserService.getById(workProjectService.getById(workTimeOrderDto.getProjectId()).getManagerId()).getName());
                    }
                    workTimeOrderDto.setTypeName(getTypeName(workTimeOrderDto.getType()));
                    workTimeOrderList.add(workTimeOrderDto);
                }
            }
            approvalDto.setWorkTimeOrderDto(workTimeOrderList);
        }
        return appletsPendApprovalDtos;
    }

    /**
     * 功能：批量审批
     *
     * @param reviewerId 审批人
     * @param ids        工单
     * @return 是否成功
     */
    @Transactional
    @Override
    public Boolean examineByIds(Integer reviewerId, List<Integer> ids) {
        log.info("WorkOrderServiceImpl[]examineByIds[]input.param.ids:" + ids);
        if (CollectionUtils.isEmpty(ids)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }

        Integer level = workUserService.getById(reviewerId).getLevel();
        if (level == 0) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.THE_USER_NOT_MANAGER_PLASE_MANAGER_LOGIN);
        }

        int i = workTimeOrderMapper.updateByIds(reviewerId, ids);
        if (i == 0) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.UPDATE_DATA_FAIL);
        }

        List<WorkTimeOrder> workTimeOrders = workTimeOrderMapper.selectBatchIds(ids);
        if (ids.size() != workTimeOrders.size()) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.HAVE_ORDER_DELETE);
        }
        // 更新collect表
        workCollectService.updateByWorkTimeOrder(workTimeOrders);

        return true;
    }

    /**
     * 功能： 驳回
     *
     * @param reviewerId 审核人id
     * @param id         工单id
     * @param reason     驳回理由
     * @return 是否成功
     */
    @Transactional
    @Override
    public Boolean rejectById(Integer reviewerId, Integer id, String reason) {
        log.info("WorkOrderServiceImpl[]rejectById[]input.param.reviewerId:{},id:{},reason:{}" + reviewerId, id, reason);
        if (null == reviewerId || null == id || StringUtils.isEmpty(reason)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        Integer level = workUserService.getById(reviewerId).getLevel();
        if (level == 0) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.THE_USER_NOT_MANAGER_PLASE_MANAGER_LOGIN);
        }

        int i = workTimeOrderMapper.updateStatusById(reviewerId, id, reason);
        if (i == 0) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.UPDATE_DATA_FAIL);
        }
        WorkTimeOrder workTimeOrder = workTimeOrderMapper.selectById(id);
        Integer userId = workTimeOrder.getUserId();
        Date workDay = workTimeOrder.getWorkDay();
        WorkCollect workCollect = workCollectService.getByUserIdAndWorkDay(userId, workDay);
        if (null == workCollect) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_INFO_IS_NULL);
        }
        workCollect.setStatus(REJECTED);
        return workCollectService.update(workCollect);
    }

    /**
     * 功能：查询驳回未提交的
     *
     * @param userId 用户id
     * @return dto
     */
    @Transactional
    @Override
    public List<WorkTimeOrderDto> rejectNotSubmit(Integer userId) {
        log.info("WorkOrderServiceImpl[]rejectById[]input.param.id:{}" + userId);
        isManager(userId);
        QueryWrapper<WorkTimeOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("reviewer_id", userId);
        wrapper.eq("status", REJECTED);
        wrapper.orderByDesc("work_day");
        List<WorkTimeOrder> workTimeOrders = workTimeOrderMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(workTimeOrders)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.NO_WORK_ORDERS_HAVE_BEEN_REJECTED);
        }
        return wtoToWtod(workTimeOrders);
    }

    /**
     * 功能：获取用户参与的项目
     *
     * @param userId 用户id
     * @return dto
     */
    @Override
    public ProjectsDto getProjectDto(Integer userId) {
        log.info("WorkOrderServiceImpl[]getProjectDto[]input.param.id:{}" + userId);
        if (null == userId) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        ProjectsDto projectsDto = new ProjectsDto();
        WorkUser user = workUserService.getById(userId);
        // 1.获取可填报的项目
        projectsDto.setProjectInfoDto(getProjectInfoDto(userId));
        // 2.获取可审批的项目
        if (0 != user.getLevel()) {
            List<ProjectManagerDto> projectManagerDtos = new ArrayList<>();
            List<ProjectDto> projectDtos = workProjectService.getByManagerId(userId);
            if (!CollectionUtils.isEmpty(projectDtos)) {
                QueryWrapper<WorkTimeOrder> wrapper = new QueryWrapper<>();
                List<Integer> projectIds = new ArrayList<>();
                for (ProjectDto projectDto : projectDtos) {
                    projectIds.add(projectDto.getId());
                }
                wrapper.in("project_id", projectIds);
                wrapper.in("status", COMPLETED, RE_SUBMIT);
                List<WorkTimeOrder> timeOrders = workTimeOrderMapper.selectList(wrapper);
                ProjectManagerDto projectManagerDto;
                for (ProjectDto projectDto : projectDtos) {
                    projectManagerDto = new ProjectManagerDto();
                    Integer pendingApprovalTimes = 0;
                    for (WorkTimeOrder timeOrder : timeOrders) {
                        if (timeOrder.getProjectId().equals(projectDto.getId())) {
                            pendingApprovalTimes++;
                        }
                    }
                    projectManagerDto.setPendingApprovalTimes(pendingApprovalTimes);
                    BeanUtils.copyProperties(projectDto, projectManagerDto);
                    projectManagerDtos.add(projectManagerDto);
                }
            }
            List<WorkType> WorkTypes = workTypeService.getByManagerId(userId);
            QueryWrapper<WorkTimeOrder> wrapper = new QueryWrapper<>();
            wrapper.in("type", EXTERNAL_BUSINESS, INTERNAL_TRAINING, OTHER_NON_PROJECTS);
            wrapper.eq("dept_id", user.getDeptId());
            wrapper.in("status", COMPLETED, RE_SUBMIT);
            List<WorkTimeOrder> timeOrders = workTimeOrderMapper.selectList(wrapper);
            ProjectManagerDto projectManagerDto1;
            for (WorkType workType : WorkTypes) {
                projectManagerDto1 = new ProjectManagerDto();
                Integer pendingApprovalTimes = 0;
                for (WorkTimeOrder timeOrder : timeOrders) {
                    if (workType.getType().equals(timeOrder.getType())) {
                        pendingApprovalTimes++;
                    }
                }
                projectManagerDto1.setPendingApprovalTimes(pendingApprovalTimes);
                projectManagerDto1.setType(workType.getType()).setTypeName(workType.getName());
                projectManagerDtos.add(projectManagerDto1);

            }
            Collections.sort(projectManagerDtos);
            projectsDto.setProjectManagerDto(projectManagerDtos);
        }
        return projectsDto;
    }

    // 获取可以填报的数据
    private List<ProjectInfoDto> getProjectInfoDto(Integer userId) {
        // 获取该用户参与的项目
        List<Integer> projectIds = workUserProjectService.getProjectIdByUserId(userId);

        // 1.获取当前用户的部门管理
        Integer deptId = workUserService.getById(userId).getDeptId();

        String deptManagerName = workUserService.getById(workDeptService.getById(deptId).getDeptManagerId()).getName();
        // 2.获取可填报的类型
        List<ProjectInfoDto> projectList = new ArrayList<>();

        List<WorkProject> projects = workProjectService.getNameById(projectIds);
        ProjectInfoDto projectInfoDto;
        for (ProjectTypeEnum value : ProjectTypeEnum.values()) {
            projectInfoDto = new ProjectInfoDto().setType(value.getType()).setTypeName(value.getTypeName()).setDeptManagerName(deptManagerName);
            if (1 == value.getReviewer()) {
                if (!CollectionUtils.isEmpty(projectIds)) {
                    List<ProjectDto> projectDtos = new ArrayList<>();
                    for (WorkProject project : projects) {
                        if (project.getType().equals(value.getType())) {
                            ProjectDto projectDto = new ProjectDto();
                            BeanUtils.copyProperties(project, projectDto);
                            projectDto.setManagerName(workUserService.getById(project.getManagerId()).getName());
                            projectDtos.add(projectDto);
                        }
                    }
                    projectInfoDto.setProjectDto(projectDtos);
                }

            }
            projectList.add(projectInfoDto);
        }

        return projectList;
    }


    // workTimeOrder TO WorkTimeOrderDto
    public List<WorkTimeOrderDto> wtoToWtod(List<WorkTimeOrder> workTimeOrders) {
        List<WorkTimeOrderDto> dtos = new ArrayList<>();
        for (WorkTimeOrder workTimeOrder : workTimeOrders) {
            WorkTimeOrderDto dto = new WorkTimeOrderDto();
            BeanUtils.copyProperties(workTimeOrder, dto);
            dto.setUserName(workUserService.getById(workTimeOrder.getUserId()).getName());
            dto.setManagerName(workUserService.getById(workTypeService.getByDeptId(workTimeOrder.getDeptId()).get(0).getManagerId()).getName());
            if (PROJECT.equals(workTimeOrder.getType()) || BUSINESS_OPPORTUNITY.equals(workTimeOrder.getType())) {
                dto.setProjectName(workProjectService.getById(workTimeOrder.getProjectId()).getProjectName());
                dto.setManagerName(getManagerNameByOrder(workTimeOrder));
            }
            dto.setTypeName(getTypeName(dto.getType()));
            dtos.add(dto);
        }
        return dtos;
    }



    // 判断工单是否合法
    private void isEmpty(WorkTimeOrderDto dto) {
        int size = 0;

        if (null == dto.getType()) {
            size++;
        }
        if (null == dto.getWorkTime() || 0 == dto.getWorkTime()) {
            size++;
        }
        if (1 == dto.getType() || 2 == dto.getType()) {
            if (null == dto.getProjectId())
                size++;
        }
        if (null == dto.getDes() || "".equals(dto.getDes())) {
            size++;
        }
        if (size >= 2) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INCOMPLETE_WORK_ORDER_INFORMATION);
        }


        if (null == dto.getWorkTime() || 0 == dto.getWorkTime()) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.TIME_NOT_IS_NULL);
        }
        if (null == dto.getWorkDay()) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORKDAY_NOT_NULL);
        }
        if (null == dto.getType() || 0 == dto.getType()) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.PROJECT_NOT_NULL);
        }
        if (thanDate(dto.getWorkDay())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_TIME_OVER_NOW_DAY);
        }
        if (1 == dto.getType() || 2 == dto.getType()) {
            if (null == dto.getProjectId())
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.NO_JOIN_EVERY_PROJECT_PLASE_JION);

        }
        for (ProjectTypeEnum value : ProjectTypeEnum.values()) {
            if (value.getReviewer() == 2) {
                if (dto.getType().equals(value.getType())) {
                    return;
                }
            }
        }
        if (null == dto.getDes() || "".equals(dto.getDes())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.DES_NOT_NULL);
        }
    }

    //3.每天工时累加不得超过八小时
    private void timeNotEight(int count, List<WorkTimeOrderDto> list) {
        for (WorkTimeOrderDto workOrder : list) {
            isEmpty(workOrder);
            count = count + workOrder.getWorkTime();
            if (count > 8) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_TIME_NOT_OVER_EIGHT);
            }
        }
    }

    //判断填报是否超过今天
    private boolean thanDate(Date date) {
        Date date1 = new Date();
        int i;
        i = date1.compareTo(date);
        return -1 == i;
    }


    // 审批分页
    private PageInfo<WorkTimeOrderDto> pageExamine(WorkUser user, Integer projectId, Integer type, Integer page, Integer size, Integer status) {
        log.info("WorkOrderServiceImpl[]pageExamine[]input.param.user:{},projectId:{},type:{},page:{},size:{},status:{}" + user, projectId, type, page, size, status);
        page = page == null ? 1 : page;
        size = size == null ? 10 : size;
        PageHelper.startPage(page, size);
        List<WorkTimeOrder> workTimeOrders = null;
        Integer level = user.getLevel();

        if (0 != level) {
            Integer deptId = user.getDeptId();
            workTimeOrders = workTimeOrderMapper.queryByPage(status, projectId, type, deptId);
        }


        List<WorkTimeOrderDto> workTimeOrderDtos = new ArrayList<>();

        List<WorkUser> workUsers = workUserMapper.selectList(new QueryWrapper<>());
        List<WorkProject> workProjects = workProjectMapper.selectList(new QueryWrapper<>());
        for (WorkTimeOrder workTimeOrder : workTimeOrders) {
            WorkTimeOrderDto workTimeOrderDto = new WorkTimeOrderDto();
            BeanUtils.copyProperties(workTimeOrder, workTimeOrderDto);
            for (WorkUser workUser : workUsers) {
                if (workTimeOrderDto.getUserId().equals(workUser.getId())) {
                    workTimeOrderDto.setUserName(workUser.getName());
                }
            }
            for (WorkProject workProject : workProjects) {
                if (null != workTimeOrderDto.getProjectId() && workTimeOrderDto.getProjectId().equals(workProject.getId())) {
                    workTimeOrderDto.setProjectName(workProject.getProjectName());
                }
            }
            workTimeOrderDto.setTypeName(getTypeName(workTimeOrderDto.getType()));
            workTimeOrderDtos.add(workTimeOrderDto);
        }
        return new PageInfo<>(workTimeOrderDtos);
    }


    // 根据工单获取管理员
    private String getManagerNameByOrder(WorkTimeOrder wto) {
        if (PROJECT.equals(wto.getType()) || BUSINESS_OPPORTUNITY.equals(wto.getType())) {
            WorkProject workProject = workProjectService.getById(wto.getProjectId());
            return workProject != null ? workUserService.getById(workProject.getManagerId()).getName() : "";
        }
        if (!PROJECT.equals(wto.getType()) && !PROJECT.equals(wto.getType())) {
            return workUserService.getById(
                    workDeptService.getById(wto.getDeptId()).getDeptManagerId())
                    .getName();
        }
        return null;
    }

    // 判断当前用户是否是管理员
    private void isManager(Integer userId) {
        if (null == userId) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        // 判断当前用户是否为管理
        WorkUser user = workUserService.getById(userId);
        if (0 == user.getLevel()) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.THE_USER_NOT_MANAGER_PLASE_MANAGER_LOGIN);
        }
    }

    private String getTypeName(Integer type) {
        for (ProjectTypeEnum value : ProjectTypeEnum.values()) {
            if (value.getType().equals(type)) {
                return value.getTypeName();
            }
        }
        return null;
    }

    // 判断当天是否全部审批通过
    public int statusYes(Integer userId, Date workDay) {
        int status = PROJECT;
        int size = 0;
        List<WorkTimeOrder> workTimeOrderDtos = workTimeOrderMapper.getByDay(userId, workDay);
        for (WorkTimeOrder dto : workTimeOrderDtos) {
            if (APPROVED.equals(dto.getStatus()) || AUTOMATIC_AUDIT.equals(dto.getStatus())) {
                size++;
            }
            if (REJECTED.equals(dto.getStatus())) {
                status = REJECTED;
            }
        }
        if (size == workTimeOrderDtos.size()) {
            status = APPROVED;
        }
        return status;
    }

}
