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.LevelEnum;
import cn.wisenergy.model.enums.LevelRankEnum;
import cn.wisenergy.model.enums.StatusEnum;
import cn.wisenergy.service.*;
import cn.wisenergy.service.utils.UserRoleLevelUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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 java.util.*;

import static java.util.Collections.sort;

/**
 * <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 WorkTypeService workTypeService;

    @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;


    // 工单状态

    private final Integer COMPLETED = StatusEnum.COMPLETED.getCode();
    private final Integer APPROVED = StatusEnum.APPROVED.getCode();
    private final Integer REJECTED = StatusEnum.REJECTED.getCode();
    private final Integer RE_SUBMIT = StatusEnum.RE_SUBMIT.getCode();
    private final 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 || null == 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();
        subtotalDto.setUserId(userId);
        subtotalDto.setWorkDay(workDay);
        List<Integer> typeIds = workTypeService.getIdByReviewer(1);

        for (WorkTimeOrder wto : workTimeOrders) {
            totalTime += wto.getWorkTime();
            if (null != wto.getReason() && REJECTED.equals(wto.getStatus()) && reason.toString().equals("")) {
                if (!CollectionUtils.isEmpty(typeIds)) {
                    if (typeIds.contains(wto.getType())) {
                        reason.append(workProjectService.getById(wto.getProjectId()).getProjectName()).append(":").append(wto.getReason()).append(";");
                    }
                    if (!typeIds.contains(wto.getType())) {
                        List<WorkType> workTypes = workTypeService.getAll(null);
                        if (!CollectionUtils.isEmpty(workTimeOrders)) {
                            for (WorkType value : workTypes) {
                                if (value.getId().equals(wto.getType())) {
                                    reason.append(value.getName()).append(":").append(wto.getReason()).append(";");
                                }
                            }
                        }
                    }
                }

            }
        }

        subtotalDto.setReason(reason.toString());
        subtotalDto.setTotalTime(totalTime);
        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);
        }
        WorkUser user = workUserService.getById(createWorkOrderDto.getWorkTimeOrders().get(0).getUserId());
        List<WorkTimeOrderDto> workTimeOrders = createWorkOrderDto.getWorkTimeOrders();
        Date date = new Date();
        WorkSubmitAdopt workSubmitAdopt = workSubmitAdoptService.getById(1);
        Integer submitTime = workSubmitAdopt.getSubmitTime();

        // 1.判断是否重复填报
        isRepeat(workTimeOrders);
        // 2.每天工时累加不得超过八小时
        timeNotEight(workTimeOrders);
        int totalTime = 0;
        List<WorkTimeOrder> addList = new ArrayList<>(8);
        List<WorkType> workTypes = workTypeService.getAll(null);
        List<Integer> notDeleteOrder = new ArrayList<>(8);

        // 3.验证填报类型项目是否已经结项
        orderIsEnd(workTimeOrders, workTypes);
        for (WorkTimeOrderDto dto : workTimeOrders) {
            // 4.判断工单是否合法
            isEmpty(dto);

            // 5.设置状态
            if (null == dto.getStatus() || 0 == dto.getStatus()) {
                dto.setStatus(COMPLETED);
            }
            if (null != dto.getStatus() && REJECTED.equals(dto.getStatus())) {
                dto.setStatus(RE_SUBMIT);
            }
            // 6.是否加班
            dto.setIsOvertime(0);
            if (workHolidayService.isHoliday(dto.getWorkDay())) {
                dto.setIsOvertime(1);
            }
            // 7.是否已经审批
            WorkTimeOrder workTimeOrder = new WorkTimeOrder();
            workTimeOrder.setDeptId(user.getDeptId());
            BeanUtils.copyProperties(dto, workTimeOrder);
            totalTime += dto.getWorkTime();
            if (null != dto.getWorkId()) {
                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);
                    }
                    notDeleteOrder.add(workTimeOrder1.getWorkId());
                    continue;
                } else {
                    WorkTimeOrder order = new WorkTimeOrder();
                    BeanUtils.copyProperties(dto, order);
                    if (workTimeOrder1.equals(order)) {
                        notDeleteOrder.add(workTimeOrder1.getWorkId());
                        continue;
                    }
                }
            }
            BeanUtils.copyProperties(workTimeOrder, dto);
            addList.add(workTimeOrder);
        }
        // 8.判断是否超时
        WorkCollect workCollect = workCollectService.getByUserIdAndWorkDay(workTimeOrders.get(0).getUserId(), workTimeOrders.get(0).getWorkDay());
        for (WorkTimeOrder dto : addList) {
            if (null != workCollect && null != workCollect.getRejectTime()) {
                Date rejectTime1 = workCollect.getRejectTime();
                //dto.setStatus(RE_SUBMIT);
                Date rejectTime = DateUtil.convertStrToDate(DateUtil.convertDateToStr(rejectTime1, "yyyy-MM-dd"), "yyyy-MM-dd");
                if (DateUtil.isThanDay(rejectTime, date, submitTime)) {
                    throw new BaseCustomException("627", "超过" + submitTime + "天的不能填报");
                }
            }
            // 4、默认设置超过系统默认3天（包括驳回3天）未填报的工时将不能填报
            if (!REJECTED.equals(dto.getStatus()) && !RE_SUBMIT.equals(dto.getStatus())) {
                if (DateUtil.isThanDay(dto.getWorkDay(), date, submitTime)) {
                    throw new BaseCustomException("627", "超过" + submitTime + "天的不能填报");
                }
            }

        }

        // 9.删除数据库还没有审批的工单，添加填报没有审批的工单
        UpdateWrapper<WorkTimeOrder> wrapper = new UpdateWrapper<>();
        wrapper.eq("user_id", workTimeOrders.get(0).getUserId());
        wrapper.eq("work_day", workTimeOrders.get(0).getWorkDay());
        wrapper.notIn(!CollectionUtils.isEmpty(notDeleteOrder), "work_id", notDeleteOrder);
        workTimeOrderMapper.delete(wrapper);
        if (!CollectionUtils.isEmpty(addList)) {
            for (WorkTimeOrder workTimeOrder : addList) {
                workTimeOrderMapper.save(workTimeOrder);
            }
        }
        // 10.更新collect表
        int status = statusYes(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 orderIsEnd(List<WorkTimeOrderDto> workTimeOrders, List<WorkType> workTypes) {
        if (!CollectionUtils.isEmpty(workTimeOrders) || !CollectionUtils.isEmpty(workTypes)) {
            List<WorkProject> projectsByIds = workProjectMapper.getProjectsByIds(null, 0);
            if (!CollectionUtils.isEmpty(projectsByIds)) {
                for (WorkTimeOrderDto workTimeOrder : workTimeOrders) {
                    if (workTimeOrder.getType().equals(1) || workTimeOrder.getType().equals(2)) {
                        for (WorkProject projectsById : projectsByIds) {
                            if (projectsById.getId().equals(workTimeOrder.getProjectId())) {

                                throw new BaseCustomException("666", projectsById.getProjectName() + "已经结束，请重新选择填报");
                            }
                        }
                    } else {
                        for (WorkType workType : workTypes) {
                            if (workType.getStatus().equals(0)) {
                                if (workType.getId().equals(workTimeOrder.getType())) {
                                    throw new BaseCustomException("667", workType.getName() + "已经结束，请重新选择填报");
                                }
                            }
                        }
                    }

                }
            }
        }
    }

    // 判断填写工时单是否重复
    private void isRepeat(List<WorkTimeOrderDto> list) {
        if (CollectionUtils.isEmpty(list)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        List<Integer> typeIds = workTypeService.getIdByReviewer(1);
        int size = list.size();
        for (int i = 0; i < size; i++) {
            for (int j = i + 1; j < size; j++) {
                if (!CollectionUtils.isEmpty(typeIds)) {
                    if (typeIds.contains(list.get(i).getType())) {
                        if (list.get(j).getType().equals(list.get(i).getType())) {
                            if (null == list.get(i).getProjectId() || null == list.get(j).getProjectId()) {
                                throw new BaseCustomException(BASE_RESP_CODE_ENUM.NO_JOIN_EVERY_PROJECT_PLASE_JION);
                            } else if (list.get(i).getProjectId().equals(list.get(j).getProjectId())) {
                                throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_ALREADY_COMMIT);
                            }
                        }
                    } else if (list.get(i).getType().equals(list.get(j).getType())) {
                        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 pageSize, List<Integer> status) {
        log.info("WorkOrderServiceImpl[]getExamine[]input.param.userId:{},projectId:{},type:{},page:{},size:{},status:{}" + userId, projectId, type, page, pageSize, status);
        // 判断当前用户是否是管理员
        if (!UserRoleLevelUtils.isManagerLevel(userId, LevelEnum.EXAMINE.getLevelName())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.USER_NOT_LEVEL);
        }
        WorkUser user = workUserService.getById(userId);

        // PC端
        return pageExamine(user, projectId, type, page, pageSize, 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);
        if (!UserRoleLevelUtils.isManagerLevel(userId, LevelEnum.EXAMINE.getLevelName())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.USER_NOT_LEVEL);
        }
        WorkUser user = workUserService.getById(userId);
        if (null == projectId && null == type) {
            return null;
        }
        if (UserRoleLevelUtils.isManagerLevel(userId, LevelEnum.EXAMINE.getLevelName())) {
            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<>(10);
        Date date = workTimeOrders.get(0).getWorkDay();
        AppletsPendApprovalDto dto = new AppletsPendApprovalDto();
        dto.setWorkDay(date);
        appletsPendApprovalDtos.add(dto);
        WorkUser user = workUserService.getById(workTimeOrders.get(0).getUserId());
        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);
        }
        List<Integer> typeIds = workTypeService.getIdByReviewer(1);
        List<WorkType> workTypes = workTypeService.getAll(null);
        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);
                    Integer deptManagerId = workDeptService.getById(user.getDeptId()).getDeptManagerId();
                    if (null != deptManagerId) {
                        workTimeOrderDto.setManagerName(workUserService.getById(deptManagerId).getName());
                    }
                    workTimeOrderDto.setUserName(workUserService.getById(workTimeOrderDto.getUserId()).getName());
                    if (!CollectionUtils.isEmpty(typeIds)) {
                        if (typeIds.contains(workTimeOrder.getType())) {
                            workTimeOrderDto.setProjectName(workProjectService.getById(workTimeOrderDto.getProjectId()).getProjectName());
                            workTimeOrderDto.setManagerName(workUserService.getById(workProjectService.getById(workTimeOrderDto.getProjectId()).getManagerId()).getName());
                        }
                    }
                    workTimeOrderDto.setTypeName(getTypeName(workTimeOrderDto.getType(), workTypes));
                    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);
        }
        if (!UserRoleLevelUtils.isManagerLevel(reviewerId, LevelEnum.EXAMINE.getLevelName())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.USER_NOT_LEVEL);
        }
        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);
        }
        // 判断当前用户是否有权限
        if (!UserRoleLevelUtils.isManagerLevel(reviewerId, LevelEnum.EXAMINE.getLevelName())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.USER_NOT_LEVEL);
        }
        // 修改工单状态
        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[]rejectNotSubmit[]input.param.id:{}" + userId);
        if (!UserRoleLevelUtils.isManagerLevel(userId, LevelEnum.EXAMINE.getLevelName())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.USER_NOT_LEVEL);
        }
        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.userId:{}" + userId);
        System.out.println(userId);
        if (null == userId) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        ProjectsDto projectsDto = new ProjectsDto();
        WorkUser user = workUserService.getById(userId);
        // 逻辑删后的东西
        List<WorkType> workTypeList = workTypeService.getByIsStatus(1, 1);
        projectsDto.setWorkTypeList(workTypeList);
        // 1.获取可填报的类型
        List<WorkType> workTypes = workTypeService.getAll(1);
        if (!CollectionUtils.isEmpty(workTypes)) {
            projectsDto.setWorkTypes(workTypes);
        }
        // 2.获取可填报的项目
        projectsDto.setProjectInfoDto(getProjectInfoDto(userId));
        // 3.获取可审批的项目
        List<ProjectManagerDto> projectManagerDto = getProjectManagerDto(user, workTypes);
        if (!CollectionUtils.isEmpty(projectManagerDto)) {
            projectsDto.setProjectManagerDto(projectManagerDto);
            return projectsDto;
        }
        return projectsDto;
    }

    private List<ProjectManagerDto> getProjectManagerDto(WorkUser user, List<WorkType> workTypes) {
        List<UserRoleLevelDto> roleUserLevel = UserRoleLevelUtils.getRoleUserLevel(user.getId());

        if (CollectionUtils.isEmpty(roleUserLevel)) {
            return null;
        }
        List<ProjectManagerDto> projectManagerDtos = new ArrayList<>();
        for (UserRoleLevelDto userRoleLevelDto : roleUserLevel) {
            // 如果有审批权限
            if (LevelEnum.EXAMINE.getLevelName().equals(userRoleLevelDto.getLevelName())) {
                List<ProjectDto> projectDtos = workProjectService.getByManagerId(user.getId(), 1);
                if (LevelRankEnum.PROJECT_LEVEL.getRank().equals(userRoleLevelDto.getRank())) {
                    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);
                        }
                    }
                }

                if (LevelRankEnum.DEPARTMENT_LEVEL.getRank().equals(userRoleLevelDto.getRank())) {
                    List<WorkType> workTypeServiceAll = workTypeService.getAll(null);
                    if (!CollectionUtils.isEmpty(workTypeServiceAll)) {
                        List<WorkType> managerTypes = new ArrayList<>();
                        Set<Integer> set = new TreeSet<>();
                        workTypes.forEach(type -> {
                            if (3 == type.getReviewer()) {
                                set.add(type.getId());
                                managerTypes.add(type);
                            }
                        });
                        QueryWrapper<WorkTimeOrder> wrapper = new QueryWrapper<>();
                        wrapper.in("type", set);
                        wrapper.eq("dept_id", user.getDeptId());
                        wrapper.in("status", COMPLETED, RE_SUBMIT);
                        List<WorkTimeOrder> timeOrders = workTimeOrderMapper.selectList(wrapper);
                        ProjectManagerDto projectManagerDto1;
                        for (WorkType workType : managerTypes) {
                            projectManagerDto1 = new ProjectManagerDto();
                            Integer pendingApprovalTimes = 0;
                            for (WorkTimeOrder timeOrder : timeOrders) {
                                if (workType.getId()
                                        .equals(timeOrder.getType())) {
                                    pendingApprovalTimes++;
                                }
                            }
                            projectManagerDto1.setPendingApprovalTimes(pendingApprovalTimes);
                            projectManagerDto1.setType(workType.getId());
                            projectManagerDto1.setTypeName(workType.getName());
                            projectManagerDtos.add(projectManagerDto1);
                        }
                    }
                }
            }
        }
        sort(projectManagerDtos);
        return projectManagerDtos;

    }

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

        // 1.获取当前用户的部门管理
        Integer deptId = workUserService.getById(userId).getDeptId();
        Integer deptManagerId = workDeptService.getById(deptId).getDeptManagerId();
        String deptManagerName = null;
        if (null != deptManagerId) {
            deptManagerName = workUserService.getById(workDeptService.getById(deptId).getDeptManagerId()).getName();
        }
        // 2.获取可填报的类型
        List<ProjectInfoDto> projectList = new ArrayList<>();
        // 3.获取正在进行中的项目/商机
        List<WorkProject> projects = workProjectService.getNameByIds(projectIds, 1);

        ProjectInfoDto projectInfoDto;
        List<WorkType> workTypes = workTypeService.getByIsStatus(1, 1);
        if (!CollectionUtils.isEmpty(workTypes)) {
            for (WorkType value : workTypes) {
                projectInfoDto = new ProjectInfoDto().setType(value.getId()).setTypeName(value.getName()).setDeptManagerName(deptManagerName);
                if (1 == value.getReviewer()) {
                    if (!CollectionUtils.isEmpty(projects)) {
                        List<ProjectDto> projectDtos = new ArrayList<>();
                        for (WorkProject project : projects) {
                            if (project.getType().equals(value.getId())) {
                                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
    @Override
    public List<WorkTimeOrderDto> wtoToWtod(List<WorkTimeOrder> workTimeOrders) {
        List<WorkTimeOrderDto> dtos = new ArrayList<>();
        WorkUser user = workUserService.getById(workTimeOrders.get(0).getUserId());
        List<Integer> typeIds = workTypeService.getIdByReviewer(1);
        List<WorkType> workTypes = workTypeService.getAll(null);
        for (WorkTimeOrder workTimeOrder : workTimeOrders) {
            WorkTimeOrderDto dto = new WorkTimeOrderDto();
            BeanUtils.copyProperties(workTimeOrder, dto);
            dto.setUserName(workUserService.getById(workTimeOrder.getUserId()).getName());
            Integer deptManagerId = workDeptService.getById(user.getDeptId()).getDeptManagerId();
            if (null != deptManagerId) {
                dto.setManagerName(workUserService.getById(deptManagerId).getName());
            }
            if (!CollectionUtils.isEmpty(typeIds)) {
                if (typeIds.contains(workTimeOrder.getType())) {
                    dto.setProjectName(workProjectService.getById(workTimeOrder.getProjectId()).getProjectName());
                    dto.setManagerName(getManagerNameByOrder(workTimeOrder));
                }
            }
            dto.setTypeName(getTypeName(dto.getType(), workTypes));
            dtos.add(dto);
        }
        return dtos;
    }


    // 判断工单是否合法
    private void isEmpty(WorkTimeOrderDto dto) {
        int size = 0;
        int range = 2;
        if (null == dto.getType()) {
            size++;
        }
        if (null == dto.getWorkTime() || 0 == dto.getWorkTime()) {
            size++;
        }
        if (1 == dto.getType() || range == dto.getType()) {
            if (null == dto.getProjectId()) {
                size++;
            }
        }
        if (null == dto.getDes() || "".equals(dto.getDes())) {
            size++;
        }
        if (size >= range) {
            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);
            }

        }
        List<WorkType> workTypes = workTypeService.getAll(null);
        if (!CollectionUtils.isEmpty(workTypes)) {
            for (WorkType value : workTypes) {
                if (value.getReviewer() == 2) {
                    if (dto.getType().equals(value.getId())) {
                        return;
                    }
                }
            }
        }
        if (null == dto.getDes() || "".equals(dto.getDes())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.DES_NOT_NULL);
        }
    }

    //3.每天工时累加不得超过八小时
    private void timeNotEight(List<WorkTimeOrderDto> list) {
        int count = 0;
        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 pageSize, List<Integer> status) {
        log.info("WorkOrderServiceImpl[]pageExamine[]input.param.user:{},projectId:{},type:{},page:{},pageSize:{},status:{}" + user, projectId, type, page, pageSize, status);
        page = page == null ? 1 : page;
        pageSize = pageSize == null ? 10 : pageSize;
        List<WorkType> workTypes = workTypeService.getAll(1);
        List<Integer> projectIds = new ArrayList<>();
        List<Integer> types = new ArrayList<>();

        if (null == projectId && null == type) {
            List<ProjectManagerDto> projectManagerDto = getProjectManagerDto(user, workTypes);
            if (!CollectionUtils.isEmpty(projectManagerDto)) {
                projectManagerDto.forEach(project ->{
                    if (null != project.getId()) {
                        projectIds.add(project.getId());
                    } else {
                        types.add(project.getType());
                    }
                } );
            }
        }else{
            if (null != projectId) {
                projectIds.add(projectId);
            }
            if (null != type) {
                types.add(type);
            }
        }
        Page<WorkTimeOrderDto> pageHelper = null;
        List<WorkTimeOrder> workTimeOrders = null;
        if (UserRoleLevelUtils.isManagerLevel(user.getId(), LevelEnum.EXAMINE.getLevelName())) {
            pageHelper = PageHelper.startPage(page, pageSize);
            Integer deptId = user.getDeptId();
            workTimeOrders = workTimeOrderMapper.queryByPage(status, projectIds, types, 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(), workTypes));
            workTimeOrderDtos.add(workTimeOrderDto);
        }
        PageInfo<WorkTimeOrderDto> pageInfo = pageHelper.toPageInfo();
        pageInfo.setList(workTimeOrderDtos);
        return pageInfo;
    }


    // 根据工单获取管理员
    private String getManagerNameByOrder(WorkTimeOrder wto) {
        List<Integer> typeIds = workTypeService.getIdByReviewer(1);
        if (!CollectionUtils.isEmpty(typeIds)) {
            if (typeIds.contains(wto.getType())) {
                WorkProject workProject = workProjectService.getById(wto.getProjectId());
                return workProject != null ? workUserService.getById(workProject.getManagerId()).getName() : "";
            } else {
                Integer deptManagerId = workDeptService.getById(wto.getDeptId()).getDeptManagerId();
                if (null != deptManagerId) {
                    return workUserService.getById(deptManagerId).getName();
                }
            }
        }
        return null;
    }



    private String getTypeName(Integer type, List<WorkType> workTypes) {
        if (!CollectionUtils.isEmpty(workTypes)) {
            for (WorkType value : workTypes) {
                if (value.getId().equals(type)) {
                    return value.getName();
                }
            }
        }
        return null;
    }

    /**
     * 判断当天是否全部审批通过
     */
    @Override
    public int statusYes(Integer userId, Date workDay) {
        int status = COMPLETED;
        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;
    }

    /**
     * 功能：获取工单变更分页
     *
     * @param managerOrderVo 分页套件
     * @return PageInfo
     */


}
