package com.zjty.tynotes.attendance.task;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiAttendanceListRequest;
import com.dingtalk.api.response.OapiAttendanceListResponse;
import com.taobao.api.ApiException;
import com.zjty.tynotes.attendance.dao.*;
import com.zjty.tynotes.attendance.entity.*;
import com.zjty.tynotes.attendance.service.impl.ApprovalInformationServiceImpl;
import com.zjty.tynotes.pas.dao.ConfigDao;
import com.zjty.tynotes.pas.dao.DayDao;
import com.zjty.tynotes.pas.dao.PasUserDao;
import com.zjty.tynotes.pas.entity.Config;
import com.zjty.tynotes.pas.entity.Day;
import com.zjty.tynotes.pas.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotEmpty;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Author gwj
 * @create 2020/3/26 14:51
 * @des 定时任务，定时获取打卡信息
 */
@Component
public class CardTask {

    private static final Logger logger = LoggerFactory.getLogger(CardTask.class);

    @Value("ding.userCardUrl")
    private String userCardUrl;
    @Autowired
    private MyInit init;
    @Autowired
    private DingUserDao dingUserDao;
    @Autowired
    private CardResultDao cardResultDao;
    @Autowired
    private DayDao dayDao;
    @Autowired
    private PasUserDao pasUserDao;
    @Autowired
    private ApprovalInformationDao approvalInformationDao;
    @Autowired
    private ConfigDao configDao;
    @Autowired
    private AttendanceDetailsDao attendanceDetailsDao;
    @Autowired
    private UserOverWorkDao userOverWorkDao;
    @Autowired
    private UserLateNumDao userLateNumDao;
    @Autowired
    private WorkoverApproDao workoverApproDao;

    /**
     * 定时任务，定时获取打卡信息.计算前天的个人考勤信息情况
     */
    @Scheduled(cron = "0 59 23 * * ? ")
    public List<CardResult> getCardDetails(){
        List<User> users = pasUserDao.findAll();
        List<User> userList = new ArrayList<>();
        if(users!=null){
            users.forEach(user -> {
                if(!user.getUsername().equals("root")){
                    userList.add(user);
                }
            });
        }
        List<CardResult> cardResults = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE,-1);
//        LocalDateTime.now().minusDays(1).atOffset(ZoneOffset.ofHours(8)).format(DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00"));

        Date time = calendar.getTime();
        String startTime = sdf.format(time);
        String endTime = sdf3.format(time);

//        String time1 = null;
//        String time2 = null;
//        try {
//            long l1 = sdf2.parse(startTime).getTime() - 8*60*60*1000;
//            time1 = sdf2.format(new Date(l1));
//            long l2 = sdf2.parse(endTime).getTime() - 8*60*60*1000;
//            time2 = sdf2.format(new Date(l2));
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/attendance/list");
        OapiAttendanceListRequest request = new OapiAttendanceListRequest();

        List<DingUser> dingUsers = dingUserDao.findAll();
        List<String> dingUserIds = new ArrayList<>();
        if(dingUsers!=null){
            dingUsers.forEach(dingUser -> {
                dingUserIds.add(dingUser.getDingUserId());
            });
        }

        request.setWorkDateFrom(startTime);
        request.setWorkDateTo(endTime);

        request.setUserIdList(dingUserIds);
        request.setOffset(0L);
        request.setLimit(50L);
        try {
            init.getToken();
            OapiAttendanceListResponse response = client.execute(request,init.token);
            if(response!=null){
                List<OapiAttendanceListResponse.Recordresult> recordresult = response.getRecordresult();
                if(recordresult!=null){
                    recordresult.forEach(recordresult1 -> {
                        String userId = recordresult1.getUserId();
                        DingUser dingUser = dingUserDao.findByDingUserId(userId);
                        CardResult cardResult = new CardResult(recordresult1);
                        cardResult.setUserId(dingUser.getUserId());
                        cardResults.add(cardResult);
                    });
                }
                List<CardResult> cardResults1 = cardResultDao.saveAll(cardResults);
                computerPersonAttenDanceDay(startTime,endTime,userList,cardResults1);
                return cardResults1;
            }
        } catch (ApiException e) {
            logger.error("定时获取打卡信息失败");
        }
        return null;
    }

    /**
     * 计算个人每天的考勤情况
     * @param startTime
     * @param endTime
     * @param userList
     * @param cardResults1
     */
    private void computerPersonAttenDanceDay(String startTime
            , String endTime, List<User> userList, List<CardResult> cardResults1) {
        List<AttendanceDetails> attendanceDetailsList = new ArrayList<>();
        Config config = configDao.findAll().get(0);
        String workTime = config.getWorkTime();//上班时间
        String afterWorkTime = config.getAfterWorkTime();//下班时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        workTime = "yyyy-MM-dd "+workTime;
        afterWorkTime = "yyyy-MM-dd "+afterWorkTime;
        SimpleDateFormat sdf1 = new SimpleDateFormat(workTime);
        SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf2 = new SimpleDateFormat(afterWorkTime);
        List<String> type1 = new ArrayList<>();
        type1.add("公出");
        List<String> type2 = new ArrayList<>();
        type2.add("出差");
        List<String> type3 = new ArrayList<>();
        type3.add("事假");
        type3.add("病假");
        type3.add("调休");
        if(userList!=null){
            userList.forEach(user -> {
                AttendanceDetails attendanceDetails = new AttendanceDetails();
                Date parse = null;
                try {
                    parse = sdf.parse(startTime);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                if(parse!=null){
                    attendanceDetails.setAttenDate(parse);
                }
                try {
                    String format = sdf1.format(parse);
                    Date date = sdf4.parse(format);

                    String format1 = sdf2.format(parse);
                    Date date1 = sdf4.parse(format1);
                    System.out.println(date);
                    System.out.println(date1);
//                    List<ApprovalInformation> all = approvalInformationDao.findAll();
//                    System.out.println("startTime"+all.get(0).getLeaveStartTime()+"\n"+"endTime"+all.get(0).getLeaveEndTime());
                    Day day = dayDao.findByDate(parse);
                    if(day!=null){
                        if(day.getStatus()!=null && day.getStatus().equals("0")){
                            List<ApprovalInformation> approvalInformation = approvalInformationDao.findAllByUserIdAndLeaveStartTimeLessThanEqualAndLeaveEndTimeGreaterThanEqualAndStatus(user.getId(), date, date1,"1");
                            List<ApprovalInformation> approvalInformationList = new ArrayList<>();
                            if(approvalInformation!=null){
                                approvalInformationList.forEach(approvalInformation1 -> {
                                    List<ApprovalInformation> compute = compute(approvalInformation1, attendanceDetails, user.getId(), date, date1);
                                    if(compute!=null){
                                        approvalInformationList.addAll(compute);
                                    }
                                });
                            }

                            WorkoverAppro workoverAppro = workoverApproDao.findByUserIdAndStatusAndOverDate(user.getId(), "1", parse);
                            List<WorkoverAppro> workoverAppros = workoverApproDao.findAllByGroupMenbersContainsAndStatusAndOverDate(user.getId(), "1", parse);
                            //                            ApprovalInformation approvalInformation1 = approvalInformationDao.findByUserIdAndStatusAndApprovalType(user.getId(), "1", "加班");
                            attendanceDetails.setUserId(user.getId());
                            if(cardResults1!=null){
                                List<CardResult> cardResults = new ArrayList<>();
                                cardResults1.forEach(cardResult -> {
                                    String userId = cardResult.getUserId();
                                    if(user.getId().equals(userId)){
                                        cardResults.add(cardResult);
                                    }
                                });
                                if(cardResults.size()>=2){
                                    attendanceDetails.setLessCard(0);
                                    if(workoverAppro!=null || workoverAppros!=null){
                                        cardResults.forEach(cardResult -> {
                                            if(cardResult.getCheckType()!=null && cardResult.getCheckType().equals("OffDuty")){
                                                Long l = cardResult.getUserCheckTime().getTime() - date1.getTime();
                                                Long hour = 60*60*1000L;
                                                Long x = 0L;
                                                x = l/hour;
                                                if(x>=4){
                                                    x = 4L;
                                                }else if(x<=0){
                                                    x = 0L;
                                                }
                                                attendanceDetails.setIsWorkOverHours(0);
                                                attendanceDetails.setWorkOverHours(x.intValue());
                                            }
                                        });
                                    }
                                    cardResults.forEach(cardResult -> {
                                        @NotEmpty(message = "迟到次数时间规定") String lateNumOfFixedTime = config.getLateNumOfFixedTime();
                                        @NotEmpty(message = "弹性迟到1时间") String lateWorkTimeOne = config.getLateWorkTimeOne();
                                        @NotEmpty(message = "弹性迟到2时间") String lateWorkTimeTwo = config.getLateWorkTimeTwo();
                                        Long real = cardResult.getUserCheckTime().getTime();
                                        if(cardResult.getCheckType()!=null&&cardResult.getCheckType().equals("OnDuty")){
                                            Long l = date.getTime();
                                            Long l1 = date.getTime()+Integer.parseInt(lateNumOfFixedTime)*1000*60;
                                            Long l2 = date.getTime()+Integer.parseInt(lateWorkTimeOne)*1000*60*60;
                                            Long l3 = date.getTime()+Integer.parseInt(lateWorkTimeTwo)*1000*60*60;
                                            if(real>l&&real<=l1){
                                                attendanceDetails.setIsLateDay(0);
                                                attendanceDetails.setLateStatus(0);
                                                String format2 = simpleDateFormat.format(startTime);
                                                UserLateNum userLateNum = userLateNumDao.findByUserIdAndDate(user.getId(), format2);
                                                if(userLateNum!=null){
                                                    userLateNum.setLateNum(userLateNum.getLateNum()+1);
                                                }else{
                                                    UserLateNum userLateNum1 = new UserLateNum();
                                                    userLateNum1.setId(null);
                                                    userLateNum1.setDate(format2);
                                                    userLateNum1.setUserId(user.getId());
                                                    userLateNum1.setLateNum(1);
                                                    userLateNum = userLateNum1;
                                                }
                                                userLateNumDao.save(userLateNum);
                                            }else if(real>l1&&real<=l2){
                                                attendanceDetails.setIsLateDay(0);
                                                attendanceDetails.setLateStatus(1);
                                            }else if(real>l2&&real<=l3){
                                                attendanceDetails.setIsLateDay(0);
                                                attendanceDetails.setLateStatus(2);
                                                attendanceDetails.setIsAbsenteeismDay(0);
                                                attendanceDetails.setAbsenteeismDay(0.5f);
                                            }else if(real>l3){
                                                if(attendanceDetails.getLateStatus()!=null&&!attendanceDetails.getLateStatus().equals(3)){
                                                    attendanceDetails.setIsLateDay(0);
                                                    attendanceDetails.setLateStatus(3);
                                                    attendanceDetails.setIsAbsenteeismDay(0);
                                                    attendanceDetails.setAbsenteeismDay(1f);
                                                }
                                            }
                                        }else if(cardResult.getCheckType()!=null&&cardResult.getCheckType().equals("OffDuty")){
                                            Long l = date1.getTime();
                                            Long l1 = date1.getTime()-Integer.parseInt(lateNumOfFixedTime)*1000*60;
                                            Long l2 = date1.getTime()-Integer.parseInt(lateWorkTimeOne)*1000*60*60;
                                            Long l3 = date1.getTime()-Integer.parseInt(lateWorkTimeTwo)*1000*60*60;
                                            if(real<l&&real>=l1){
                                                attendanceDetails.setIsLeaveEarlyDay(0);
                                                attendanceDetails.setEarlyStatus(0);;
                                            }else if(real<l1&&real>=l2){
                                                attendanceDetails.setIsLeaveEarlyDay(0);
                                                attendanceDetails.setEarlyStatus(1);
                                            }else if(real<l2&&real>=l3){
                                                attendanceDetails.setIsLeaveEarlyDay(0);
                                                attendanceDetails.setEarlyStatus(2);
                                            }else if(real<l3){
                                                if(attendanceDetails.getEarlyStatus()!=null&&!attendanceDetails.getEarlyStatus().equals(3)){
                                                    attendanceDetails.setIsLeaveEarlyDay(0);
                                                    attendanceDetails.setEarlyStatus(3);
                                                }
                                            }
                                        }
                                    });

                                }else if(cardResults.size()==1){
                                    attendanceDetails.setLessCard(1);
                                    if(approvalInformation == null && (approvalInformationList == null || approvalInformationList.size() ==0)){
                                        attendanceDetails.setIsAbsenteeismDay(0);
                                        attendanceDetails.setAbsenteeismDay(1f);
                                    }
                                }else{
                                    attendanceDetails.setLessCard(2);
                                    if(approvalInformation == null && (approvalInformationList == null || approvalInformationList.size() ==0)){
                                        attendanceDetails.setIsAbsenteeismDay(0);
                                        attendanceDetails.setAbsenteeismDay(1f);
                                    }
                                }
//                                cardResults.forEach(cardResult -> {
//                                    String checkType = cardResult.getCheckType();
//                                    String timeResult = cardResult.getTimeResult();
//                                    if(("OnDuty").equals(checkType)){
//                                        if("Late".equals(timeResult)||"SeriousLate".equals(timeResult)){
//                                            attendanceDetails.setIsLateDay(0);
//                                        }
//                                    }else if("OffDuty".equals(checkType)){
//                                        if("Early".equals(timeResult)||"Absenteeism".equals(timeResult)){
//                                            attendanceDetails.setIsLeaveEarlyDay(0);
//                                        }
//                                    }
//                                });
                            }
                        }else if(day.getStatus()!=null && day.getStatus().equals("1")
                                || day.getStatus()!=null && day.getStatus().equals("2")){
                            if(cardResults1!=null){
                                List<CardResult> cardResults = new ArrayList<>();
                                cardResults1.forEach(cardResult -> {
                                    String userId = cardResult.getUserId();
                                    if(user.getId().equals(userId)){
                                        cardResults.add(cardResult);
                                    }
                                });
                                WorkoverAppro workoverAppro = workoverApproDao.findByUserIdAndStatusAndOverDate(user.getId(), "1", parse);
                                List<WorkoverAppro> workoverAppros = workoverApproDao.findAllByGroupMenbersContainsAndStatusAndOverDate(user.getId(), "1", parse);
//                                ApprovalInformation approvalInformation1 = approvalInformationDao.findByUserIdAndStatusAndApprovalType(user.getId(), "1", "加班");
                                if(cardResults.size()>=2){
                                    if(workoverAppro!=null || workoverAppros!=null){
                                        cardResults.forEach(cardResult -> {
                                            if(cardResult.getCheckType()!=null && cardResult.getCheckType().equals("OffDuty")){
                                                Long l = cardResult.getUserCheckTime().getTime() - date1.getTime();
                                                Long hour = 60*60*1000L;
                                                Long x = 0L;
                                                x = l/hour;
                                                if(x>=8){
                                                    x = 8L;
                                                }else if(x<=0){
                                                    x = 0L;
                                                }
                                                attendanceDetails.setIsWorkOverHours(0);
                                                attendanceDetails.setWorkOverHours(x.intValue());
                                            }
                                        });
                                    }
                                }
                            }
                        }
                    }

                } catch (ParseException e) {
                    logger.error(e.getMessage());
                }
                //                List<String> checkType = new ArrayList<>();
                if(attendanceDetails.getWorkOverHours()>=0){
                    UserOverWork userOverWork = userOverWorkDao.findByUserId(user.getId());
                    try {
                        Long overWorkHour = userOverWork.getOverWorkHour();
                        Long timeLeft = overWorkHour + attendanceDetails.getWorkOverHours();
                        userOverWork.setOverWorkHour(timeLeft);
                        userOverWorkDao.save(userOverWork);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                attendanceDetailsList.add(attendanceDetails);
            });
            attendanceDetailsDao.saveAll(attendanceDetailsList);
        }
    }

    /**
     * 计算当天公出，出差，请假时间
     * @param approvalInformation
     * @param attendanceDetails
     * @param userId
     * @param date1
     * @param date2
     */
    private List<ApprovalInformation> compute(ApprovalInformation approvalInformation,AttendanceDetails attendanceDetails,String userId,Date date1,Date date2){
        List<ApprovalInformation> approvalInformationList = null;
        if(approvalInformation.getApprovalType()!=null&&approvalInformation.getApprovalType().equals("公出")){
            approvalInformationList = outSideBusinessDay(approvalInformation,
                    attendanceDetails, userId, date1, date2, approvalInformation.getApprovalType());
        }else if(approvalInformation.getApprovalType()!=null&&approvalInformation.getApprovalType().equals("出差")){
            approvalInformationList = outWorkDay(approvalInformation,
                    attendanceDetails, userId, date1, date2, approvalInformation.getApprovalType());
        }else if(approvalInformation.getApprovalType()!=null&&approvalInformation.getApprovalType().equals("事假")){
            approvalInformationList = sickLeaveDay(approvalInformation,
                    attendanceDetails, userId, date1, date2, approvalInformation.getApprovalType());
        }else if(approvalInformation.getApprovalType()!=null&&approvalInformation.getApprovalType().equals("病假")){
            approvalInformationList = sickLeaveDay(approvalInformation,
                    attendanceDetails, userId, date1, date2, approvalInformation.getApprovalType());
        }else if(approvalInformation.getApprovalType()!=null&&approvalInformation.getApprovalType().equals("调休")){
            approvalInformationList = paidLeaveDay(approvalInformation,
                    attendanceDetails, userId, date1, date2, approvalInformation.getApprovalType());
        }

        return approvalInformationList;
    }

    /**
     * 计算公出
     * @throws Exception
     */
    private List<ApprovalInformation> outSideBusinessDay(ApprovalInformation approvalInformation,AttendanceDetails attendanceDetails
            ,String userId,Date date1,Date date2,String type){
        List<ApprovalInformation> approvalInformationList = new ArrayList<>();
        if(approvalInformation!=null){
            attendanceDetails.setIsOutSideBusinessDay(0);
            attendanceDetails.setOutSideBusinessDay(1f);
        }else{
            ApprovalInformation approvalInformation1 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBeforeAndLeaveEndTimeBetweenAndApprovalTypeAndStatus(userId, date1, date1,date2,type,"1");
            ApprovalInformation approvalInformation2 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBetweenAndLeaveEndTimeAfterAndApprovalTypeAndStatus(userId, date1, date2,date2,type,"1");
            if(approvalInformation1!=null){
                attendanceDetails.setIsOutSideBusinessDay(0);
                attendanceDetails.setOutSideBusinessDay(0.5f);
                approvalInformationList.add(approvalInformation1);
            }
            if(approvalInformation2!=null){
                attendanceDetails.setIsOutSideBusinessDay(0);
                if(attendanceDetails.getOutSideBusinessDay()!=null){
                    attendanceDetails.setOutSideBusinessDay(attendanceDetails.getOutSideBusinessDay()+0.5f);
                }
                approvalInformationList.add(approvalInformation2);
            }
        }
        return approvalInformationList;
    }

    /**
     * 计算出差
     * @throws Exception
     */
    private List<ApprovalInformation> outWorkDay(ApprovalInformation approvalInformation,AttendanceDetails attendanceDetails
            ,String userId,Date date1,Date date2,String type){
        List<ApprovalInformation> approvalInformationList = new ArrayList<>();
        if(approvalInformation!=null){
            attendanceDetails.setIsOutWorkDay(0);
            attendanceDetails.setOutWorkDay(1f);
        }else{
            ApprovalInformation approvalInformation1 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBeforeAndLeaveEndTimeBetweenAndApprovalTypeAndStatus(userId, date1, date1,date2,type,"1");
            ApprovalInformation approvalInformation2 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBetweenAndLeaveEndTimeAfterAndApprovalTypeAndStatus(userId, date1, date2,date2,type,"1");
            if(approvalInformation1!=null){
                attendanceDetails.setIsOutWorkDay(0);
                attendanceDetails.setOutWorkDay(0.5f);
                approvalInformationList.add(approvalInformation1);
            }
            if(approvalInformation2!=null){
                attendanceDetails.setIsOutWorkDay(0);
                if(attendanceDetails.getOutWorkDay()!=null){
                    attendanceDetails.setOutWorkDay(attendanceDetails.getOutWorkDay()+0.5f);
                }
                approvalInformationList.add(approvalInformation2);
            }
        }
        return approvalInformationList;
    }


    /**
     * 计算病假
     */
    private List<ApprovalInformation> sickLeaveDay(ApprovalInformation approvalInformation,AttendanceDetails attendanceDetails
            ,String userId,Date date1,Date date2,String type){
        List<ApprovalInformation> approvalInformationList = new ArrayList<>();
        if(approvalInformation!=null){
            attendanceDetails.setIsSickLeaveDay(0);
            attendanceDetails.setSickLeaveDay(1f);
        }else{
            ApprovalInformation approvalInformation1 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBeforeAndLeaveEndTimeBetweenAndApprovalTypeAndStatus(userId, date1, date1,date2,type,"1");
            ApprovalInformation approvalInformation2 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBetweenAndLeaveEndTimeAfterAndApprovalTypeAndStatus(userId, date1, date2,date2,type,"1");
            if(approvalInformation1!=null){
                attendanceDetails.setIsSickLeaveDay(0);
                attendanceDetails.setSickLeaveDay(0.5f);
                approvalInformationList.add(approvalInformation1);
            }
            if(approvalInformation2!=null){
                attendanceDetails.setIsSickLeaveDay(0);
                if(attendanceDetails.getSickLeaveDay()!=null){
                    attendanceDetails.setSickLeaveDay(attendanceDetails.getSickLeaveDay()+0.5f);
                }
                approvalInformationList.add(approvalInformation2);
            }
        }
        return approvalInformationList;
    }

    /**
     * 计算事假
     */
    private List<ApprovalInformation> thingLeaveDay(ApprovalInformation approvalInformation,AttendanceDetails attendanceDetails
            ,String userId,Date date1,Date date2,String type){
        List<ApprovalInformation> approvalInformationList = new ArrayList<>();
        if(approvalInformation!=null){
            attendanceDetails.setIsThingLeaveDay(0);
            attendanceDetails.setThingLeaveDay(1f);
        }else{
            ApprovalInformation approvalInformation1 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBeforeAndLeaveEndTimeBetweenAndApprovalTypeAndStatus(userId, date1, date1,date2,type,"1");
            ApprovalInformation approvalInformation2 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBetweenAndLeaveEndTimeAfterAndApprovalTypeAndStatus(userId, date1, date2,date2,type,"1");
            if(approvalInformation1!=null){
                attendanceDetails.setIsThingLeaveDay(0);
                attendanceDetails.setThingLeaveDay(0.5f);
                approvalInformationList.add(approvalInformation1);
            }
            if(approvalInformation2!=null){
                attendanceDetails.setIsThingLeaveDay(0);
                if(attendanceDetails.getIsThingLeaveDay()!=null){
                    attendanceDetails.setThingLeaveDay(attendanceDetails.getThingLeaveDay()+0.5f);
                }
                approvalInformationList.add(approvalInformation2);
            }
        }
        return approvalInformationList;
    }

    /**
     * 计算调休
     */
    private List<ApprovalInformation> paidLeaveDay(ApprovalInformation approvalInformation,AttendanceDetails attendanceDetails
            ,String userId,Date date1,Date date2,String type){
        List<ApprovalInformation> approvalInformationList = new ArrayList<>();
        if(approvalInformation!=null){
            attendanceDetails.setIsPaidLeaveDay(0);
            attendanceDetails.setPaidLeaveDay(1f);
        }else{
            ApprovalInformation approvalInformation1 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBeforeAndLeaveEndTimeBetweenAndApprovalTypeAndStatus(userId, date1, date1,date2,type,"1");
            ApprovalInformation approvalInformation2 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBetweenAndLeaveEndTimeAfterAndApprovalTypeAndStatus(userId, date1, date2,date2,type,"1");
            if(approvalInformation1!=null){
                attendanceDetails.setIsPaidLeaveDay(0);
                attendanceDetails.setPaidLeaveDay(0.5f);
                approvalInformationList.add(approvalInformation1);
            }
            if(approvalInformation2!=null){
                attendanceDetails.setIsPaidLeaveDay(0);
                if(attendanceDetails.getIsPaidLeaveDay()!=null){
                    attendanceDetails.setPaidLeaveDay(attendanceDetails.getPaidLeaveDay()+0.5f);
                }
                approvalInformationList.add(approvalInformation2);
            }
        }
        return approvalInformationList;
    }



    /**
     * 定时任务，定时进行运算
     */
    @Scheduled(cron = "0/30 * * * * ? ")
    public void calculate() throws Exception{
        int attendanceDay = 0;//应出勤天数
        int averageWorkHours = 0;//平均工时
        int realAttendanceDay = 0;//实际出勤天数
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(new Date());
        Date parse = sdf.parse(format);
        //计算这个月的应出勤天数
        calendar.set(Calendar.DAY_OF_MONTH,1);
        Date startTime = calendar.getTime();
        calendar.add(Calendar.MONTH,1);
        calendar.set(Calendar.DAY_OF_MONTH,0);
        Date endTime = calendar.getTime();
        List<Day> days = dayDao.findAllByStatusAndDateBetween("0", startTime, endTime);
        if(days!=null){
            attendanceDay = days.size();
        }
        List<User> users = pasUserDao.findAll();
        List<User> userList = new ArrayList<>();
        if(users!=null){
            users.forEach(user -> {
                if(!user.getUsername().equals("root")){
                    userList.add(user);
                    List<CardResult> cardResults = cardResultDao.findAllByUserIdAndUserCheckTimeBetween(user.getId(), startTime, endTime);
                }
            });
        }
    }

    public static void main(String[] args) throws Exception{
//        Calendar calendar = Calendar.getInstance();
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
////        Date date = new Date();
//        String date = "2020-03-29 11:11:11";
//        String format = sdf.format(new Date());
//        //计算这个月的应出勤天数
//        Date parse = sdf.parse(date);
//        calendar.setTime(parse);
//        calendar.set(Calendar.DAY_OF_MONTH,1);
//        Date time = calendar.getTime();
//        System.out.println(time);
//        calendar.add(Calendar.MONTH,1);
//        calendar.set(Calendar.DAY_OF_MONTH,0);
//        Date time1 = calendar.getTime();
//        System.out.println("time1:"+time1);
//        Float aFloat = CardTask.fullScore();
//        System.out.println(aFloat);
        String month = "2020-04";
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        String format = "2020-04-05 00:00:00";
        try {
            Date parse = sdf2.parse(format);
            calendar.setTime(parse);
            calendar.add(Calendar.DATE,-1);
            Date date = sdf.parse(month);
            System.out.println(calendar.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    /**
     * 计算个人当月总考勤分
     * @return
     */
    public Double calcuteScore(String month){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String userId = "5e86ac92986f2c9064e29b32";
        Double fullScore = fullScore(sdf,month);
        System.out.println(fullScore);
        Double minusScore = getScore(sdf,userId,month);
        Double monthScore = fullScore - minusScore;
        return monthScore;
//        Calendar calendar = Calendar.getInstance();
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
//        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
//        String format = sdf2.format(new Date());
//        try {
//            Date parse = sdf2.parse(format);
//            calendar.setTime(parse);
//            calendar.add(Calendar.DATE,-1);
//            Date time = calendar.getTime();
//            String format1 = sdf.format(time);
//
//
//
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 计算月基础分
     * @return
     */
    private Double fullScore(SimpleDateFormat sdf2,String month){
        Date parse = null;
        try {
            parse = sdf2.parse(month);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(parse);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        Date start = calendar.getTime();
        calendar.add(Calendar.MONTH,1);
        calendar.set(Calendar.DAY_OF_MONTH,0);
        Date end = calendar.getTime();
        Double monthSocre = 0d;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        try {
            Date startTime = sdf.parse(sdf.format(start));
            Date endTime = sdf.parse(sdf.format(end));
//            List<Day> days = dayDao.findAllByStatusAndDateGreaterThanEqual("0", startTime);
//            List<Day> days2 = dayDao.findAllByStatusAndDateLessThanEqual("0", endTime);
            Day time = dayDao.findByStatusAndDateEquals("0", startTime);
            Day time1 = dayDao.findByStatusAndDateEquals("0", endTime);
            List<Day> days = dayDao.findAllByStatusAndDateBetween("0",startTime, endTime);
            days.add(time);
            days.add(time1);
            List<Config> configs = configDao.findAll();
            Config config = configs.get(0);
            @NotEmpty(message = "每日考勤基础分") String score = config.getScore();
            int i = Integer.parseInt(score);
            if(days!=null){
                int size = days.size();
                monthSocre = new Double(i*size);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return monthSocre;
    }

    /**
     * 计算公出、出差、加班、调休、病假、事假、迟到、早退
     * @param userId
     * @return
     */
    public Double getScore(SimpleDateFormat sdf2,String userId,String month){
        Date parse = null;
        try {
            parse = sdf2.parse(month);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Double score = 0d;
        Config config = configDao.findAll().get(0);
        @NotEmpty(message = "事假一天扣分") String thingDay = config.getThingDay();
        double thingDayScore = Double.parseDouble(thingDay);
        @NotEmpty(message = "调休一天扣分") String paidDayLeave = config.getPaidDayLeave();
        double paidDayLeaveScore = Double.parseDouble(paidDayLeave);
        @NotEmpty(message = "加班一小时加分") String workOverScore = config.getWorkOverScore();
        double workOverHourScore = Double.parseDouble(workOverScore);
        @NotEmpty(message = "全天旷工扣分") String absenteeism = config.getAbsenteeism();
        double absenteeismScore = Double.parseDouble(absenteeism);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(parse);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        Date start = calendar.getTime();
        calendar.add(Calendar.MONTH,1);
        calendar.set(Calendar.DAY_OF_MONTH,0);
        Date end = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        Map<String,Integer> monthTypeScore1 = new HashMap<>();
        Map<String,Float> monthTypeScore2 = new HashMap<>();
        monthTypeScore1.put("加班",0);
        monthTypeScore2.put("调休",0f);
        monthTypeScore2.put("公出",0f);
        monthTypeScore2.put("出差",0f);
        monthTypeScore2.put("事假",0f);
        monthTypeScore2.put("病假",0f);
        monthTypeScore2.put("旷工",0f);
        AtomicReference<Double> lateEarlySocre = new AtomicReference<>(0d);
        try {
            Date startTime = sdf.parse(sdf.format(start));
            Date endTime = sdf.parse(sdf.format(end));
            List<AttendanceDetails> attendanceDetails = attendanceDetailsDao.findAllByUserIdAndAttenDateBetween(userId, startTime, endTime);
            if(attendanceDetails!=null){
                attendanceDetails.forEach(attendanceDetails1 -> {
                    attendanceDetails1.getLateStatus();
                    if(attendanceDetails1.getLateStatus()!=null &&
                            attendanceDetails1.getLateStatus().equals(1)){
                        @NotEmpty(message = "迟到15分钟以上扣分") String latePointsFifteen = config.getLatePointsFifteen();
                        Double latePointsFifteenScore = Double.parseDouble(latePointsFifteen);
                        lateEarlySocre.updateAndGet(v -> v + latePointsFifteenScore);
                    }else if(attendanceDetails1.getLateStatus()!=null &&
                            attendanceDetails1.getLateStatus().equals(2)){
                        @NotEmpty(message = "迟到半天扣分") String latePointsHalfOfDay = config.getLatePointsHalfOfDay();
                        Double latePointsHalfOfDayScore = Double.parseDouble(latePointsHalfOfDay);
                        lateEarlySocre.updateAndGet(v -> v + latePointsHalfOfDayScore);
                    }else if(attendanceDetails1.getLateStatus()!=null &&
                            attendanceDetails1.getLateStatus().equals(3)){
                        @NotEmpty(message = "迟到半天扣分") String latePointsHalfOfDay = config.getLatePointsHalfOfDay();
                        Double latePointsHalfOfDayScore = Double.parseDouble(latePointsHalfOfDay);
                        lateEarlySocre.updateAndGet(v -> v + latePointsHalfOfDayScore * 2);
                    }
                    monthTypeScore1.put("加班",monthTypeScore1.get("加班")+attendanceDetails1.getWorkOverHours());
                    monthTypeScore2.put("调休",monthTypeScore2.get("调休")+attendanceDetails1.getPaidLeaveDay());
                    monthTypeScore2.put("公出",monthTypeScore2.get("公出")+attendanceDetails1.getOutSideBusinessDay());
                    monthTypeScore2.put("出差",monthTypeScore2.get("出差")+attendanceDetails1.getOutWorkDay());
                    monthTypeScore2.put("事假",monthTypeScore2.get("事假")+attendanceDetails1.getThingLeaveDay());
                    monthTypeScore2.put("病假",monthTypeScore2.get("病假")+attendanceDetails1.getSickLeaveDay());
                    monthTypeScore2.put("旷工",monthTypeScore2.get("旷工")+attendanceDetails1.getAbsenteeismDay());
                });
            }
            score = thingDayScore*monthTypeScore2.get("事假")+thingDayScore*monthTypeScore2.get("病假")
                    +paidDayLeaveScore*monthTypeScore2.get("调休")+absenteeismScore*monthTypeScore2.get("旷工")
                    -workOverHourScore*monthTypeScore1.get("加班")+lateEarlySocre.get();
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return score;
    }

    @Scheduled(cron = "0 0 23 * * ? ")
    public void setApproPass(){
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        String format = sdf.format(new Date());
        try {
            Date parse = sdf.parse(format);
            calendar.setTime(parse);
            calendar.add(Calendar.DATE,1);
            Date startTime = calendar.getTime();
            calendar.add(Calendar.DATE,1);
            Date endTime = calendar.getTime();
            List<ApprovalInformation> approvalInformations =
                    approvalInformationDao.findAllByLeaveStartTimeBetween(startTime, endTime);
            List<WorkoverAppro> workoverAppros = workoverApproDao.findAllByOverDate(startTime);
            if(approvalInformations!=null){
                approvalInformations.forEach(approvalInformation -> {
                    approvalInformation.setStatus("1");
                });
            }
            if(workoverAppros!=null){
                workoverAppros.forEach(workoverAppro -> {
                    workoverAppro.setStatus("1");
                });
            }
            approvalInformationDao.saveAll(approvalInformations);
            workoverApproDao.saveAll(workoverAppros);
        } catch (ParseException e) {
            e.printStackTrace();
        }

    }


}
