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.ApprovalInformationDao;
import com.zjty.tynotes.attendance.dao.AttendanceDetailsDao;
import com.zjty.tynotes.attendance.dao.CardResultDao;
import com.zjty.tynotes.attendance.dao.DingUserDao;
import com.zjty.tynotes.attendance.entity.ApprovalInformation;
import com.zjty.tynotes.attendance.entity.AttendanceDetails;
import com.zjty.tynotes.attendance.entity.CardResult;
import com.zjty.tynotes.attendance.entity.DingUser;
import com.zjty.tynotes.attendance.service.ApprovalInformationService;
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.*;

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

    /**
     * 定时任务，定时获取打卡信息.计算前天的个人考勤信息情况
     */
//    @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");
        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.setDate(parse);
                }
                try {
                    String format = sdf1.format(parse);
                    Date date = sdf4.parse(format);

                    String format1 = sdf2.format(parse);
                    Date date1 = sdf4.parse(format1);
                    ApprovalInformation approvalInformation = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBeforeAndLeaveEndTimeAfterAndApprovalTypeIn(user.getId(), date, date1,type1);
                    compute(approvalInformation,attendanceDetails,user.getId(),date,date1,type1);
                    ApprovalInformation approvalInformation1 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBeforeAndLeaveEndTimeAfterAndApprovalTypeIn(user.getId(), date, date1,type2);
                    compute(approvalInformation1,attendanceDetails,user.getId(),date,date1,type2);
                    ApprovalInformation approvalInformation2 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBeforeAndLeaveEndTimeAfterAndApprovalTypeIn(user.getId(), date, date1,type3);
                    compute(approvalInformation2,attendanceDetails,user.getId(),date,date1,type3);

                    attendanceDetails.setUserId(user.getId());
                    System.out.println(approvalInformation);
                    System.out.println(approvalInformation1);
                    System.out.println(approvalInformation2);
                    if(cardResults1!=null){
                        List<CardResult> cardResults = new ArrayList<>();
                        cardResults1.forEach(cardResult -> {
                            String userId = cardResult.getUserId();
                            if(user.getId().equals(userId)){
                                cardResults.add(cardResult);
//                            if(!checkType.contains("OnDuty")&&("OnDuty").equals(cardResult.getCheckType())){
//                                checkType.add("OnDuty");
//                            }else if(!checkType.contains("OffDuty")&&("OffDuty").equals(cardResult.getCheckType())){
//                                checkType.add("OffDuty");
//                            }
                            }
                        });
                        if(cardResults.size()>=2){
                            attendanceDetails.setLessCard(0);
                        }else if(cardResults.size()==1){
                            attendanceDetails.setLessCard(1);
                            if(approvalInformation == null && approvalInformation1==null&&approvalInformation2==null){
                                attendanceDetails.setIsAbsenteeismDay(0);
                                attendanceDetails.setAbsenteeismDay(0.5f);
                            }
                        }else{
                            attendanceDetails.setLessCard(2);
                            if(approvalInformation == null && approvalInformation1==null&&approvalInformation2==null){
                                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);
                                }
                            }
                        });

                    }
                } catch (ParseException e) {
                    logger.error(e.getMessage());
                }
                //                List<String> checkType = new ArrayList<>();
                attendanceDetailsList.add(attendanceDetails);
            });
            attendanceDetailsDao.saveAll(attendanceDetailsList);
        }
    }

    /**
     * 计算当天公出，出差，请假时间
     * @param approvalInformation
     * @param attendanceDetails
     * @param userId
     * @param date1
     * @param date2
     * @param types
     */
    private void compute(ApprovalInformation approvalInformation,AttendanceDetails attendanceDetails,String userId,Date date1,Date date2,List<String> types){
        if(approvalInformation!=null){
            attendanceDetails.setIsOutSideBusinessDay(0);
            attendanceDetails.setOutSideBusinessDay(1f);
        }else{
            ApprovalInformation approvalInformation1 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBeforeAndLeaveEndTimeBetweenAndApprovalTypeIn(userId, date1, date1,date2,types);
            ApprovalInformation approvalInformation2 = approvalInformationDao.findAllByUserIdAndLeaveStartTimeBetweenAndLeaveEndTimeAfterAndApprovalTypeIn(userId, date1, date2,date2,types);
            if(approvalInformation1!=null){
                attendanceDetails.setIsOutSideBusinessDay(0);
                attendanceDetails.setOutSideBusinessDay(0.5f);
            }
            if(approvalInformation2!=null){
                attendanceDetails.setIsOutSideBusinessDay(0);
                if(attendanceDetails.getOutSideBusinessDay()!=null){
                    attendanceDetails.setOutSideBusinessDay(attendanceDetails.getOutSideBusinessDay()+0.5f);
                }
            }
        }
    }

    /**
     * 定时任务，定时进行运算
     */
    @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);
    }

}
