package com.zjty.tynotes.attendance.service.impl;

import com.zjty.tynotes.attendance.dao.AttendanceDetailsDao;
import com.zjty.tynotes.attendance.entity.AttendanceDetails;
import com.zjty.tynotes.attendance.entity.vo.UserAttenList;
import com.zjty.tynotes.attendance.entity.vo.UserAttenVo;
import com.zjty.tynotes.attendance.entity.vo.request.AttenRequest;
import com.zjty.tynotes.attendance.service.AttendanceDetailsService;
import com.zjty.tynotes.pas.dao.*;
import com.zjty.tynotes.pas.entity.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Array;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author gwj
 * @create 2020/3/24 14:56
 */
@Service
public class AttendanceDetailsServiceImpl implements AttendanceDetailsService {
    private static final Logger logger = LoggerFactory.getLogger(AttendanceDetailsServiceImpl.class);

    @Autowired
    private AttendanceDetailsDao attendanceDetailsDao;
    @Autowired
    private DayDao dayDao;
    @Autowired
    private PasUserDao pasUserDao;
    @Autowired
    private UserRoleDao userRoleDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private RoleAuthorityDao roleAuthorityDao;
    @Autowired
    private AuthorityDao authorityDao;
    @Autowired
    private DepartmentDao departmentDao;

    @Override
    public UserAttenVo findPersonnel(AttenRequest request) {
        UserAttenVo userAttenVo = new UserAttenVo();
        SimpleDateFormat sdf = null;
        sdf = new SimpleDateFormat("yyyy-MM");
        Calendar calendar = Calendar.getInstance();
        String date = request.getStartDate();
        String endDate = request.getEndDate();
        try {
            Date parse = sdf.parse(date);
            Date parse1 = sdf.parse(endDate);
            calendar.setTime(parse);
            calendar.set(Calendar.DAY_OF_MONTH,1);
            Date startTime = calendar.getTime();
            calendar.setTime(parse1);
            calendar.add(Calendar.MONTH,1);
            calendar.set(Calendar.DAY_OF_MONTH,0);
            Date endTime = calendar.getTime();
            Day day = dayDao.findByStatusAndDateEquals("0", startTime);
            Day day2 = dayDao.findByStatusAndDateEquals("0", endTime);
            List<Day> days = dayDao.findAllByStatusAndDateBetween("0", startTime, endTime);
            if(day!=null){
                days.add(day);
            }
            if(day2!=null){
                days.add(day2);
            }
            AttendanceDetails allByUserIdAndAttenDate1 = attendanceDetailsDao.findByUserIdAndAttenDate(request.getId(), startTime);
            AttendanceDetails allByUserIdAndAttenDate2 = attendanceDetailsDao.findByUserIdAndAttenDate(request.getId(), endTime);
            List<AttendanceDetails> attendanceDetailsList = attendanceDetailsDao.findAllByUserIdAndAttenDateBetween(request.getId(), startTime, endTime);
            if(allByUserIdAndAttenDate1!=null){
                attendanceDetailsList.add(allByUserIdAndAttenDate1);
            }
            if(allByUserIdAndAttenDate2!=null){
                attendanceDetailsList.add(allByUserIdAndAttenDate2);
            }
            userAttenVo = new UserAttenVo();
            userAttenVo.setUserId(request.getId());
            Optional<User> optional = pasUserDao.findById(request.getId());
            if(optional.isPresent()){
                User user = optional.get();
                userAttenVo.setName(user.getUsername());
            }
            if(attendanceDetailsList!=null){
                if(days!=null){
                    userAttenVo.setAttendanceDay(days.size());
                }
                for (AttendanceDetails attendanceDetails : attendanceDetailsList) {
                    if(attendanceDetails.getOutSideBusinessDay()!=null){
                        userAttenVo.setOutSideBusinessDay(attendanceDetails.getOutSideBusinessDay()+userAttenVo.getOutSideBusinessDay());
                    }
                    if(attendanceDetails.getOutWorkDay()!=null){
                        userAttenVo.setOutWorkDay(userAttenVo.getOutWorkDay()+attendanceDetails.getOutWorkDay());
                    }
                    if(attendanceDetails.getSickLeaveDay()!=null){
                        userAttenVo.setSickLeaveDay(userAttenVo.getSickLeaveDay()+attendanceDetails.getSickLeaveDay());
                    }
                    if(attendanceDetails.getThingLeaveDay()!=null){
                        userAttenVo.setThingDay(userAttenVo.getThingDay()+attendanceDetails.getThingLeaveDay());
                    }
                    if(("0").equals(attendanceDetails.getIsLateDay())){
                        if(attendanceDetails.getLateStatus().equals("0")){
                            userAttenVo.setLateOne(userAttenVo.getLateOne()+1);
                        }else if(attendanceDetails.getLateStatus().equals("1")){
                            userAttenVo.setLateTwo(userAttenVo.getLateTwo()+1);
                        }else if(attendanceDetails.getLateStatus().equals("2")){
                            userAttenVo.setLateThree(userAttenVo.getLateThree()+1);
                        }else if(attendanceDetails.getLateStatus().equals("3")){
                            userAttenVo.setLateFour(userAttenVo.getLateFour()+1);
                        }
                        userAttenVo.setLateDay(userAttenVo.getLateDay()+1);
                    }
                    if("0".equals(attendanceDetails.getIsLeaveEarlyDay())){
                        userAttenVo.setLeaveEarlyDay(userAttenVo.getLeaveEarlyDay()+1);
                    }
                    if(attendanceDetails.getWorkOverHours()!=null){
                        userAttenVo.setOverWorkHours(userAttenVo.getOverWorkHours()+attendanceDetails.getWorkOverHours());
                    }

                    if(attendanceDetails.getAbsenteeismDay()!=null){
                        userAttenVo.setAbsenteeismDay(attendanceDetails.getAbsenteeismDay()+userAttenVo.getAbsenteeismDay());
                    }
                }

                userAttenVo.computerRealAttendanceDay();
            }
            return userAttenVo;
        } catch (ParseException e) {
            logger.error("时间转换格式错误");
        }

        return userAttenVo;
    }

    /**
     * 查询部门下人员的考勤情况
     * @param request
     * @return
     */
    @Override
    public List<UserAttenVo> findDepartment(AttenRequest request) {
        List<UserAttenVo> userAttenVos = new ArrayList<>();
        String id = request.getId();//人的id
        List<User> users = pasUserDao.findAll();
        List<User> userList = new ArrayList<>();
        List<String> departIds = new ArrayList<>();
        List<String> departmentIds = new ArrayList<>();
        Optional<User> byId = pasUserDao.findById(id);
        if(byId.isPresent()){
            User user = byId.get();
            List<UserRole> userRoles = userRoleDao.findAllByUserId(user.getId());
            if(userRoles!=null){
                List<String> roleIds = new ArrayList<>();
                userRoles.forEach(userRole -> {
                    roleIds.add(userRole.getRoleId());
                });
                List<Role> roles = roleDao.findAllByIdIn(roleIds);
                if(roles!=null){
                    roles.forEach(role -> {
                        if(role.getIsLeader().equals("0")){
                            departmentIds.add(role.getDepartmentId());
                        }
                    });
                }
            }
        }
        if(departmentIds!=null){
            List<String> deIds = new ArrayList<>();
            for (String s : departmentIds) {
                deIds = getDepartIds(deIds,s);
                if(deIds!=null){
                    for (String s1 : deIds) {
                        if(!departIds.contains(s1)){
                            departIds.add(s1);
                        }
                    }
                }

            }
        }
        if(users!=null){
            for (User user : users) {
                if(departIds!=null){
                    List<String> departmentIds1 = user.getDepartmentIds();
                    if(departmentIds1!=null){
                        for (String s : departmentIds1) {
                            if(departIds.contains(s)){
                                userList.add(user);
                                break;
                            }
                        }
                    }
                }
            }
        }
        List<AttenRequest> attenRequests = new ArrayList<>();
        userList.forEach(user -> {
            attenRequests.add(new AttenRequest(user.getId(),null,request.getStartDate(),request.getEndDate()));
        });
        if(attenRequests!=null){
            attenRequests.forEach(attenRequest1->{
                UserAttenVo userAttenVo = findPersonnel(attenRequest1);
                userAttenVos.add(userAttenVo);
            });
        }
        return userAttenVos;
    }


    /**
     * 查询可查看的部门列表
     * @param id
     * @return
     */
    @Override
    public List<Department> findDepartmentList(String id) {
        List<UserRole> userRoles = userRoleDao.findAllByUserId(id);
        List<String> roleIds = new ArrayList<>();
        List<String> departmentIds = new ArrayList<>();
        for (UserRole userRole : userRoles) {
            roleIds.add(userRole.getRoleId());
        }
        List<Role> roles = roleDao.findAllByIdIn(roleIds);
        for (Role role : roles) {
            List<RoleAuthority> roleAuthorities = roleAuthorityDao.findAllByRoleId(role.getId());
            List<String> authorityIds = new ArrayList<>();
            for (RoleAuthority roleAuthority : roleAuthorities) {
                authorityIds.add(roleAuthority.getAuthorityId());
            }
            Authority authority = authorityDao.findByIdInAndName(authorityIds, "部门考勤");
            if(authority!=null){
                String departmentId = role.getDepartmentId();
                departmentIds.add(departmentId);
            }
        }
        List<Department> departmentList = departmentDao.findAllByIdIn(departmentIds);
        getDepartments(departmentList);
//        getDepartments(departmentIdList,departmentIds);
//        List<Department> departments = departmentDao.findAllByIdIn(departmentIdList);

        return departmentList;
    }

    /**
     * 查找请假或者旷工、加班等等列表
     * @param request
     * @param type
     * @return
     */
    @Override
    public UserAttenList findAttenList(AttenRequest request, String type) {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        UserAttenList userAttenList = new UserAttenList();
        userAttenList.setUserId(request.getId());
        userAttenList.setName(request.getName());
        userAttenList.setType(type);
        try {
            Date start = sdf.parse(request.getStartDate());
            Date end = sdf.parse(request.getEndDate());
            calendar.setTime(start);
            calendar.set(Calendar.DAY_OF_MONTH,1);
            Date startTime = calendar.getTime();
            calendar.setTime(end);
            calendar.add(Calendar.MONTH,1);
            calendar.set(Calendar.DAY_OF_MONTH,0);
            Date endTime = calendar.getTime();
            if(type!=null){
                List<AttendanceDetails> attendanceDetailsList = null;
                List<Date> dates = new ArrayList<>();
                if(type.equals("事假")){
                    attendanceDetailsList = attendanceDetailsDao.findAllByUserIdAndAttenDateBetweenAndIsThingLeaveDay(
                            request.getId(), startTime, endTime, "0");
                }else if(type.equals("病假")){
                    attendanceDetailsList = attendanceDetailsDao.findAllByUserIdAndAttenDateBetweenAndIsSickLeaveDay(
                            request.getId(), startTime, endTime, "0");
                }else if(type.equals("调休")){
                    attendanceDetailsList = attendanceDetailsDao.findAllByUserIdAndAttenDateBetweenAndIsPaidLeaveDay(
                            request.getId(), startTime, endTime, "0");
                }else if(type.equals("旷工")){
                    attendanceDetailsList = attendanceDetailsDao.findAllByUserIdAndAttenDateBetweenAndIsAbsenteeismDay(
                            request.getId(), startTime, endTime, "0");
                }else if(type.equals("迟到")){
                    attendanceDetailsList = attendanceDetailsDao.findAllByUserIdAndAttenDateBetweenAndIsLateDay(
                            request.getId(), startTime, endTime, "0");
                }else if(type.equals("早退")){
                    attendanceDetailsList = attendanceDetailsDao.findAllByUserIdAndAttenDateBetweenAndIsLeaveEarlyDay(
                            request.getId(), startTime, endTime, "0");
                }else if(type.equals("公出")){
                    attendanceDetailsList = attendanceDetailsDao.findAllByUserIdAndAttenDateBetweenAndIsOutSideBusinessDay(
                            request.getId(), startTime, endTime, "0");
                }else if(type.equals("出差")){
                    attendanceDetailsList = attendanceDetailsDao.findAllByUserIdAndAttenDateBetweenAndIsOutWorkDay(
                            request.getId(), startTime, endTime, "0");
                }
                if(attendanceDetailsList!=null){
                    attendanceDetailsList.forEach(attendanceDetails -> {
                        dates.add(attendanceDetails.getAttenDate());
                    });
                }
                userAttenList.setDates(dates);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

//        attendanceDetailsDao.findAllByUserIdAndDateBetween()
        return userAttenList;
    }


    /**
     * 递归获得部门树
     * @param departments
     */
    public void getDepartments(List<Department> departments) {
        for (Department department : departments) {
            List<Department> departmentList = departmentDao.findAllByParentId(department.getId());
            getDepartments(departmentList);
            department.setDepartments(departmentList);
        }
    }

    /**
     * 递归获得某个部门下的所有部门id集合
     * @param ids
     * @param departId
     * @return
     */
    public List<String> getDepartIds(List<String> ids,String departId){
        ids.add(departId);
        List<Department> departments = departmentDao.findAllByParentId(departId);
        if(departments!=null){
            departments.forEach(department -> {
                getDepartIds(ids,department.getId());
            });
        }
        return ids;
    }

}
