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.WorkTimeOrderMapper;
import cn.wisenergy.model.app.*;
import cn.wisenergy.model.dto.*;
import cn.wisenergy.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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 org.springframework.web.bind.annotation.RequestBody;

import java.util.*;

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

    @Autowired
    private WorkUserService workUserService;

    @Autowired
    private WorkProjectService workProjectService;

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


    /**
     * 功能; 获取某日填报情况
     *
     * @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;
        // 被驳回原因
        String reason = "";
        // 今日被驳回次数
        int rejectMonth = 0;
        subtotalDto.setUserId(userId);
        subtotalDto.setWorkDay(workDay);
        for (WorkTimeOrder wto : workTimeOrders) {
            totalTime += wto.getWorkTime();
            if (null != wto.getReason()) {
                reason = workProjectService.getById(wto.getProjectId()).getProjectName() + ":" + wto.getReason() + ";";
            }
            if (3 == wto.getStatus()) {
                rejectMonth += 1;
            }
        }
        subtotalDto.setReason(reason);
        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 dto 自定义填报类
     * @return dto
     */
    @Transactional
    @Override
    public List<WorkTimeOrderDto> add(@RequestBody CreateWorkOrderDto dto) {
        log.info("WorkTimeOrderServiceImpl[]add[]input.param.CreateWorkOrderDto:{}" + dto);
        if (null == dto || CollectionUtils.isEmpty(dto.getWorkTimeOrders())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_INFO_IS_NULL);
        }
        // 1.检查工单
        this.checkWorkOrderInfo(dto.getWorkTimeOrders());

        // 2.保存工单信息
        List<WorkTimeOrderDto> result = this.saveWorkOrderInfo(dto.getWorkTimeOrders());
        log.info("WorkOrderServiceImpl[]add[]add.success");
        return result;

    }

    /**
     * 功能：测试添加
     *
     * @param createWorkOrderDto
     * @return
     */
    @Transactional
    @Override
    public List<WorkTimeOrderDto> addTest(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 submitTime = workSubmitAdopt.getSubmitTime();

        // 检查工单

        // 1.判断是否重复填报
        isRepeat(workTimeOrders);
        // 2.每天工时累加不得超过八小时
        timeNotEight(0, workTimeOrders);

        int totalTime = 0;
        List<Integer> typeList = new ArrayList<>();
        for (WorkTimeOrderDto dto : workTimeOrders) {
            // 3.判断工单是否合法
            isEmpty(dto);
            // 4、默认设置超过系统默认3天（包括驳回3天）未填报的工时将不能填报
            System.out.println("判断是否超过三天");
            if (date.getTime() - dto.getWorkDay().getTime() > submitTime * 24 * 60 * 60 * 1000) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_DAY_THAN_DATE);
            }
            // 获取某些数据
            Integer type = dto.getType();
            dto.setUserName(workUserService.getById(dto.getUserId()).getName());
            dto.setTypeName(getTypeName(type));
            if (1 == type || 2 == type) {
                dto.setProjectName(workProjectService.getById(dto.getProjectId()).getProjectName());
                dto.setManagerName(workUserService.getById(workProjectService.getById(dto.getProjectId()).getManagerId()).getName());
            }
            if (1 != type && 2 != type) {
                dto.setManagerName(workUserService.getById(workTypeService.getByDeptId(workUserService.getById(dto.getUserId()).getDeptId()).get(0).getManagerId()).getName());

            }

            if (null == dto.getStatus()) {
                dto.setStatus(1);
            }
            if (3 == type || 4 == type) {
                dto.setStatus(2);
            }
            if (null != dto.getStatus() && 3 == dto.getStatus()) {
                dto.setStatus(4);
            }

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

            // 修改
            if (null != dto.getWorkId()) {
                workTimeOrderMapper.updateToNull(dto.getWorkId());
                workTimeOrderMapper.updateById(workTimeOrder);
            }
            // 插入
            if (null == dto.getWorkId() || 0 == dto.getWorkId()) {
                workTimeOrderMapper.save(workTimeOrder);
                dto.setWorkId(workTimeOrder.getWorkId());

            }
            typeList.add(type);
            totalTime += dto.getWorkTime();
            BeanUtils.copyProperties(workTimeOrder, dto);
        }

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


    /**
     * 功能： 驳回重新填报
     *
     * @param dto 自定义DTO
     * @return 填报信息
     */
    @Transactional
    @Override
    public List<WorkTimeOrderDto> update(CreateWorkOrderDto dto) {
        log.info("WorkTimeOrderServiceImpl[]update[]input.param.CreateWorkOrderDto:{}" + dto);
        if (null == dto || CollectionUtils.isEmpty(dto.getWorkTimeOrders())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_INFO_IS_NULL);
        }
        List<WorkTimeOrderDto> workTimeOrders = dto.getWorkTimeOrders();
        // 1.判断是否超过8小时
        int count = 0;
        List<WorkTimeOrder> byDayToDto = getByDayToDto(workTimeOrders.get(0).getUserId(), workTimeOrders.get(0).getWorkDay());
        int i;
        for (WorkTimeOrder timeOrder : byDayToDto) {
            i = 0;
            for (WorkTimeOrderDto workTimeOrder : workTimeOrders) {
                if (!workTimeOrder.getWorkId().equals(timeOrder.getWorkId())) {
                    i++;
                }
            }
            if (i == workTimeOrders.size())
                count += timeOrder.getWorkTime();
        }
        System.out.println(count);
        timeNotEight(count, workTimeOrders);

        // 2.判断是否重复填报
        isRepeat(workTimeOrders);
        for (WorkTimeOrderDto workTimeOrder : workTimeOrders) {
            for (WorkTimeOrder orderDto : byDayToDto) {
                // workId如果相同就不管
                if (workTimeOrder.getWorkId().equals(orderDto.getWorkId())) {
                    break;
                }
                // 填报和数据库的类型相同
                if (workTimeOrder.getType().equals(orderDto.getType())) {
                    if (1 == workTimeOrder.getType() || 2 == workTimeOrder.getType())
                        if (workTimeOrder.getProjectId().equals(orderDto.getProjectId())) {
                            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_ALREADY_COMMIT);
                        }
                    throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_ALREADY_COMMIT);
                }
            }

        }

        List<WorkTimeOrderDto> workTimeOrderDtos = reSubmit(workTimeOrders);
        // 更新collect表

        int status = statusYes(workTimeOrders.get(0).getUserId(), workTimeOrderDtos.get(0).getWorkDay());
        int totalTime = 0;
        List<WorkTimeOrder> byDay = workTimeOrderMapper.getByDay(workTimeOrders.get(0).getUserId(), workTimeOrderDtos.get(0).getWorkDay());
        for (WorkTimeOrder workTimeOrder : byDay) {
            totalTime += workTimeOrder.getWorkTime();
        }
        WorkCollect workCollect = new WorkCollect();
        BeanUtils.copyProperties(workTimeOrders.get(0), workCollect);
        workCollect.setTotalTime(totalTime);
        workCollect.setStatus(status);
        workCollectService.update(workCollect);
        // 更新数据
        return workTimeOrderDtos;
    }


    // 判断填写工时单是否重复
    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
     */
    @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 (1 == user.getLevel()) {
            QueryWrapper<WorkTimeOrder> wrapper = new QueryWrapper<>();
            projectId = projectId == null ? workProjectService.getByManagerId(userId).get(0).getId() : projectId;
            // wrapper.eq("dept_id", user.getDeptId());
            wrapper.in("status", 1, 4);
            wrapper.eq("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);
        }
        // 部门经理
        if (2 == user.getLevel()) {
            type = null == type ? 5 : type;
            Integer deptId = user.getDeptId();
            QueryWrapper<WorkTimeOrder> wrapper = new QueryWrapper<>();
            wrapper.eq("dept_id", deptId);
            wrapper.in("status", 1, 4);
            wrapper.eq("type", type);
            List<WorkTimeOrder> workTimeOrders = workTimeOrderMapper.selectList(wrapper);
            if (CollectionUtils.isEmpty(workTimeOrders)) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_END);
            }
            return getDto(workTimeOrders);
        }
        return null;
    }

    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.setUserName(workUserService.getById(workTimeOrderDto.getUserId()).getName());
                    workTimeOrderDto.setManagerName(workUserService.getById(workTypeService.getByDeptId(workTimeOrder.getDeptId()).get(0).getManagerId()).getName());
                    if (1 == workTimeOrder.getType() || 2 == 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);

        // 更新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(3);
        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", 3);
        List<WorkTimeOrder> workTimeOrders = workTimeOrderMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(workTimeOrders)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_INFO_IS_NULL);
        }

        return wtoToWtod(workTimeOrders);
    }

    /**
     * 功能：获取用户参与的项目
     *
     * @param userId
     * @return
     */
    @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);
            ProjectManagerDto projectManagerDto;
            for (ProjectDto projectDto : projectDtos) {
                projectManagerDto = new ProjectManagerDto();
                BeanUtils.copyProperties(projectDto, projectManagerDto);
                projectManagerDtos.add(projectManagerDto);
            }
            List<WorkType> WorkTypes = workTypeService.getByManagerId(userId);
            ProjectManagerDto projectManagerDto1;
            for (WorkType workType : WorkTypes) {
                projectManagerDto1 = new ProjectManagerDto();
                projectManagerDto1.setType(workType.getType()).setTypeName(workType.getName());
                projectManagerDtos.add(projectManagerDto1);

            }
            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<>();
        ProjectInfoDto projectInfoDto1 = new ProjectInfoDto().setType(1).setTypeName(getTypeName(1)).setManagerName(deptManagerName);
        ProjectInfoDto projectInfoDto2 = new ProjectInfoDto().setType(2).setTypeName(getTypeName(2)).setManagerName(deptManagerName);
        if (!CollectionUtils.isEmpty(projectIds)) {
            List<ProjectDto> projectDto1 = new ArrayList<>();
            List<ProjectDto> projectDto2 = new ArrayList<>();
            WorkProject workProject;
            for (Integer projectId : projectIds) {
                workProject = workProjectService.getById(projectId);
                if (1 == workProject.getType()) {
                    projectDto1.add(projectToProjectDto(workProject));
                }
                if (2 == workProject.getType()) {
                    projectDto2.add(projectToProjectDto(workProject));
                }
            }
            if (!CollectionUtils.isEmpty(projectDto1))
                projectInfoDto1.setProjectDto(projectDto1);
            if (!CollectionUtils.isEmpty(projectDto2))
                projectInfoDto2.setProjectDto(projectDto2);
        }
        projectList.add(projectInfoDto1);
        projectList.add(projectInfoDto2);
        projectList.add(new ProjectInfoDto().setType(3).setTypeName(getTypeName(3)).setManagerName(deptManagerName));
        projectList.add(new ProjectInfoDto().setType(4).setTypeName(getTypeName(4)).setManagerName(deptManagerName));
        List<WorkType> workTypes = workTypeService.getByDeptId(deptId);
        for (WorkType workType : workTypes) {
            projectList.add(new ProjectInfoDto().setType(workType.getType()).setTypeName(workType.getName()).setManagerName(workUserService.getById(workType.getManagerId()).getName()));
        }

        return projectList;
    }

    // project转ProjectDto
    private ProjectDto projectToProjectDto(WorkProject workProject) {
        ProjectDto projectDto = new ProjectDto();
        BeanUtils.copyProperties(workProject, projectDto);
        // 获取项目管理
        projectDto.setManagerName(workUserService.getById(workProject.getManagerId()).getName());
        return projectDto;
    }

    // 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 (1 == workTimeOrder.getType() || 2 == workTimeOrder.getType()) {
                dto.setProjectName(workProjectService.getById(workTimeOrder.getProjectId()).getProjectName());
                dto.setManagerName(getManagerNameByOrder(workTimeOrder));
            }
            dto.setTypeName(getTypeName(dto.getType()));
            dtos.add(dto);
        }
        return dtos;
    }


    private List<ExamineGroupbyProjectDto> getExamineGroupByProjectDto(Integer projectId) {
        QueryWrapper<WorkTimeOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("project_id", projectId);
        wrapper.in("status", 1, 4);
        wrapper.orderByDesc("work_day");
        List<WorkTimeOrder> workTimeOrders = workTimeOrderMapper.selectList(wrapper);
        return WorkTimeOrderTOEGPD(workTimeOrders);
    }

    private List<ExamineGroupbyProjectDto> WorkTimeOrderTOEGPD(List<WorkTimeOrder> workTimeOrders) {
        if (CollectionUtils.isEmpty(workTimeOrders)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_END);
        }
        List<ExamineGroupbyProjectDto> egpds = new ArrayList<>();
        for (WorkTimeOrder workTimeOrder : workTimeOrders) {
            ExamineGroupbyProjectDto dto = new ExamineGroupbyProjectDto();
            BeanUtils.copyProperties(workTimeOrder, dto);
            egpds.add(dto);
        }
        return egpds;
    }


    private void checkWorkOrderInfo(List<WorkTimeOrderDto> list) {
        log.info("WorkOrderServiceImpl[]checkWorkOrderInfo[]input.method");
        // 1、工单时间不能大于当前天
        Date date = new Date();
        WorkSubmitAdopt workSubmitAdopt = workSubmitAdoptService.getById(1);
        Integer submitTime = workSubmitAdopt.getSubmitTime();

        for (WorkTimeOrderDto dto : list) {
            isEmpty(dto);
            // 2、默认设置超过系统默认3天（包括驳回3天）未填报的工时将不能填报
            if (date.getTime() - dto.getWorkDay().getTime() > submitTime * 24 * 60 * 60 * 1000) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_DAY_THAN_DATE);
            }
            // 3.判断当日是否已经填报
            WorkCollect byUserIdAndWorkDay = workCollectService.getByUserIdAndWorkDay(dto.getUserId(), dto.getWorkDay());
            if (null != byUserIdAndWorkDay) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_ORDER_ALREADY_COMMIT);
            }
        }


        // 判断是否重复填报
        isRepeat(list);
        // 4.每天工时累加不得超过八小时
        timeNotEight(0, list);


    }


    private void isEmpty(WorkTimeOrderDto dto) {
        if (null == dto.getWorkTime() || 0 == dto.getWorkTime()) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.TIME_NOT_IS_NULL);
        }
        if (null == dto.getDes() || "".equals(dto.getDes())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.DES_NOT_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);
        }
    }

    //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 List<WorkTimeOrderDto> reSubmit(List<WorkTimeOrderDto> workTimeOrders) {
        WorkSubmitAdopt workSubmitAdopt = workSubmitAdoptService.getById(1);
        Integer submitTime = workSubmitAdopt.getSubmitTime();
        for (WorkTimeOrderDto workTimeOrderDto : workTimeOrders) {
            if (null == workTimeOrderDto.getDes()) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.DES_NOT_NULL);
            }
            WorkTimeOrder order = workTimeOrderMapper.selectById(workTimeOrderDto.getWorkId());
            if (order.getWorkDay().compareTo(workTimeOrderDto.getWorkDay()) != 0) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.DATE_IS_ERROR);
            }
            Date modifyTime = order.getModifyTime();
            // 判断是否已经驳回三天
            if (new Date().getTime() - DateUtil.getStartOfDay(modifyTime).getTime() > submitTime * 24 * 60 * 60 * 1000) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.WORK_DAY_THAN_DATE);
            }
            workTimeOrderDto.setStatus(4);
            WorkTimeOrder workTimeOrder = new WorkTimeOrder();
            BeanUtils.copyProperties(workTimeOrderDto, workTimeOrder);

            // 获取用户名
            workTimeOrderDto.setUserName(workUserService.getById(workTimeOrder.getUserId()).getName());
            // 获取项目名
            if (1 == workTimeOrder.getType() || 2 == workTimeOrder.getType()) {
                workTimeOrderDto.setProjectName(workProjectService.getById(workTimeOrder.getProjectId()).getProjectName());
            }
            // 获取类型名
            workTimeOrderDto.setTypeName(getTypeName(workTimeOrderDto.getType()));
            // 获取部门id
            Integer deptIdByUserId = workUserDeptService.getDeptIdByUserId(workTimeOrder.getUserId());
            workTimeOrder.setDeptId(deptIdByUserId);
            Date workDay = workTimeOrder.getWorkDay();
            // 默认正常工时
            workTimeOrder.setIsOvertime(0);
            if (workHolidayService.isHoliday(workDay)) {
                workTimeOrder.setIsOvertime(1);
            }
            int iRow = workTimeOrderMapper.updateById(workTimeOrder);
            if (0 == iRow) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.UPDATE_DATA_FAIL);
            }
        }
        return workTimeOrders;
    }

    private List<WorkTimeOrderDto> saveWorkOrderInfo(List<WorkTimeOrderDto> list) {
        log.info("WorkOrderServiceImpl[]saveWorkOrderInfo[]input.method");
        int totalTime = 0;
        int status = 1;
        //根据用户id,获取用户信息

        for (WorkTimeOrderDto dto : list) {
            WorkTimeOrder workTimeOrder = new WorkTimeOrder();
            // 获取用户名
            dto.setUserName(workUserService.getById(dto.getUserId()).getName());
            // 获取项目名
            if ((1 == dto.getType() || 2 == dto.getType()) && null == dto.getProjectId()) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.NO_JOIN_EVERY_PROJECT_PLASE_JION);
            }
            dto.setProjectName(null != dto.getProjectId() ? workProjectService.getById(dto.getProjectId()).getProjectName() : getTypeName(dto.getType()));
            // 获取项目经理
            if (null != dto.getProjectId())
                dto.setManagerName(workUserService.getById(workProjectService.getById(dto.getProjectId()).getManagerId()).getName());
            // 获取类型名
            dto.setTypeName(getTypeName(dto.getType()));

            // 获取部门id
            workTimeOrder.setDeptId(workUserDeptService.getDeptIdByUserId(dto.getUserId()));
            Date workDay = dto.getWorkDay();
            // 默认正常工时
            workTimeOrder.setIsOvertime(0);
            if (workHolidayService.isHoliday(workDay)) {
                workTimeOrder.setIsOvertime(1);
            }
            dto.setStatus(status);
            // 如果是请假或者调休直接通过
            if (3 == dto.getType() || 4 == dto.getType()) {
                dto.setStatus(2);
                dto.setProjectName(null);
                dto.setProjectId(null);
            }
            BeanUtils.copyProperties(dto, workTimeOrder);
            int saveRow = workTimeOrderMapper.save(workTimeOrder);
            if (0 == saveRow) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.INSERT_DATA_IS_FAIL);
            }
            totalTime += workTimeOrder.getWorkTime();
        }
        WorkCollect workCollect = new WorkCollect();
        BeanUtils.copyProperties(list.get(0), workCollect);
        workCollect.setTotalTime(totalTime);
        workCollect.setStatus(status);
        if (!workCollectService.insertCollect(workCollect)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INSERT_DATA_IS_FAIL);
        }

        return list;
    }


    // 审批分页
    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();
        List<Integer> types;
        // 项目经理
        if (1 == level) {
            types = type == null ? Arrays.asList(1, 2) : new ArrayList<>(Collections.singletonList(type));
            workTimeOrders = workTimeOrderMapper.queryByPage(status, projectId, types);
        }
        // 部门经理
        if (2 == level) {
            System.out.println(type);
            types = type == null ? Arrays.asList(5, 6, 7) : new ArrayList<>(Collections.singletonList(type));
            System.out.println(types);
            workTimeOrders = workTimeOrderMapper.queryByPage(status, null, types);
        }
        List<WorkTimeOrderDto> workTimeOrderDtos = new ArrayList<>();
        for (WorkTimeOrder workTimeOrder : workTimeOrders) {
            WorkTimeOrderDto workTimeOrderDto = new WorkTimeOrderDto();
            BeanUtils.copyProperties(workTimeOrder, workTimeOrderDto);
            workTimeOrderDto.setUserName(workUserService.getById(workTimeOrder.getUserId()).getName());
            if (null != workTimeOrder.getProjectId()) {
                workTimeOrderDto.setProjectName(workProjectService.getById(workTimeOrder.getProjectId()).getProjectName());
            }
            workTimeOrderDto.setTypeName(getTypeName(workTimeOrderDto.getType()));
            workTimeOrderDtos.add(workTimeOrderDto);
        }

        PageInfo<WorkTimeOrderDto> pageInfo = new PageInfo<>(workTimeOrderDtos);
        return pageInfo;
    }


    // 根据工单获取管理员
    private String getManagerNameByOrder(WorkTimeOrder wto) {
        if (1 == wto.getType() || 2 == wto.getType()) {
            WorkProject workProject = workProjectService.getById(wto.getProjectId());
            return workProject != null ? workUserService.getById(workProject.getManagerId()).getName() : "";
        }
        if (1 != wto.getType() && 2 != 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) {
        List<WorkType> types = workTypeService.getType();
        String[] str = {"", "项目", "商机", "请假", "调休"};
        Map<Integer, String> map = new HashMap<>();
        for (int i = 1; i < str.length; i++) {
            map.put(i, str[i]);
        }
        for (WorkType workType : types) {
            map.put(workType.getType(), workType.getName());
        }
        return map.get(type);
    }

    // 判断当天是否全部审批通过
    public int statusYes(Integer userId, Date workDay) {
        int status = 1;
        int size = 0;

        List<WorkTimeOrder> workTimeOrderDtos = workTimeOrderMapper.getByDay(userId, workDay);

        for (WorkTimeOrder dto : workTimeOrderDtos) {
            if (2 == dto.getStatus() || 5 == dto.getStatus()) {
                size++;
            }
            if (3 == dto.getStatus()) {
                status = 3;
            }
        }
        if (size == workTimeOrderDtos.size()) {
            status = 2;
        }
        return status;
    }

}
