package com.mortals.xhx.module.attendance.service.work;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.OrderCol;
import com.mortals.xhx.common.code.*;
import com.mortals.xhx.module.attendance.model.*;
import com.mortals.xhx.module.attendance.service.*;
import com.mortals.xhx.module.holiday.model.HolidayEntity;
import com.mortals.xhx.module.holiday.model.HolidayQuery;
import com.mortals.xhx.module.holiday.service.HolidayService;
import com.mortals.xhx.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 固定班
 *
 * @author:
 * @date: 2023/7/31 15:15
 */
@Slf4j
public class FixWorkOtherAttendance extends AttendanceWorkAbstract {


    private AttendanceGroupFixedworkService attendanceGroupFixedworkService;

    private AttendanceClassService attendanceClassService;

    private AttendanceClassDetailService attendanceClassDetailService;

    private AttendanceGroupFixedworkSpecialService specialService;

    private AttendanceRecordService attendanceRecordService;

    private AttendanceRecordHikService recordHikService;

    private AttendanceRecordErrorService errorService;

    private HolidayService holidayService;

    private AttendanceLeaveRecordService attendanceLeaveRecordService;

    private AttendanceRecordDetailService attendanceRecordDetailService;


    private Map<Long, AttendanceClassDetailEntity> classDetailEntityMap ;

    public FixWorkOtherAttendance(int type) {
        super(type);
        this.attendanceGroupFixedworkService = SpringUtils.getBean(AttendanceGroupFixedworkService.class);
        this.attendanceClassService = SpringUtils.getBean(AttendanceClassService.class);
        this.specialService = SpringUtils.getBean(AttendanceGroupFixedworkSpecialService.class);
        this.attendanceRecordService = SpringUtils.getBean(AttendanceRecordService.class);
        this.recordHikService = SpringUtils.getBean(AttendanceRecordHikService.class);
        this.attendanceClassDetailService = SpringUtils.getBean(AttendanceClassDetailService.class);
        this.errorService = SpringUtils.getBean(AttendanceRecordErrorService.class);
        this.holidayService = SpringUtils.getBean(HolidayService.class);
        this.attendanceLeaveRecordService = SpringUtils.getBean(AttendanceLeaveRecordService.class);
        this.attendanceRecordDetailService = SpringUtils.getBean(AttendanceRecordDetailService.class);
    }

    @Override
    int getType() {
        return TypeEnum.固定班制.getValue();
    }

    @Override
    void initData() {

    }

    @Override
    public void doHandleWork(CommonData commonData) {
        AttendanceGroupFixedworkEntity attendanceGroupFixedworkEntity = attendanceGroupFixedworkService.selectOne(new AttendanceGroupFixedworkQuery()
                .groupId(commonData.getAttendanceGroupEntity().getId()));
        Map<Long, AttendanceClassEntity> classEntityMap = commonData.getClassEntityMap();
        Map<Long, List<AttendanceGroupFixedworkSpecialEntity>> fixedSpecialGroupMap = commonData.getFixedSpecialGroupMap();
        this.classDetailEntityMap = commonData.getClassDetailEntityMap();

       // Map<Long, List<AttendanceLeaveRecordEntity>> leaveRecordGroupMap = commonData.getLeaveRecordGroupMap();

        if (ObjectUtils.isEmpty(attendanceGroupFixedworkEntity)) {
            log.info("attendanceGroupFixedworkEntity is null ! groupId:{}", commonData.getAttendanceGroupEntity().getId());
            return;
        }
        //判断当前考勤日期为周几
        String week = super.getWeek(DateUtil.parseDate(commonData.getDateStr()));
        //获取当前日期的详细班次
        Long weekClassId = this.getWeekClassId(attendanceGroupFixedworkEntity, week);
        //log.info("weekClassId:{}", weekClassId);
        //weekClassId为-1 则不在考勤
        Boolean checkWorkByHoliday = checkWorkByHoliday(commonData.getDateStr());
        Boolean checkHolidayByWorkDay = checkHolidayByWorkDay(commonData.getDateStr());

        if (weekClassId == -1L) {
            //跳过本次循环
            if (!checkWorkByHoliday) {
                // log.info("当前日期不在考勤时间范围内，不做处理！");
                return;
            } else {
                //工作日要上班 获取配置的周六 周日班次 默认周一
                weekClassId = this.getWeekClassId(attendanceGroupFixedworkEntity, "星期一");
            }
        } else {
            if (checkHolidayByWorkDay) {
                //本来当天是需要考勤的，但是是节假日，则不计算考勤
                return;
            }
        }

        //判断当天是否请假 请假分为多个区间段与请假类型。
        AttendanceLeaveRecordQuery leaveRecordQuery = new AttendanceLeaveRecordQuery();
        leaveRecordQuery.setLeavePersonId(commonData.getStaffId());
        leaveRecordQuery.setAuditResultList(Arrays.asList(1, 4));
        boolean isLeave = false;
        List<AttendanceLeaveRecordEntity> leaveRecordEntities = attendanceLeaveRecordService.find(leaveRecordQuery);
        //List<AttendanceLeaveRecordEntity> leaveRecordEntities = leaveRecordGroupMap.get(commonData.getStaffId());

        List<AttendanceLeaveRecordEntity> leaveRecords = null;
        if (!ObjectUtils.isEmpty(leaveRecordEntities)) {
            //判断当日日期中 是否有请假记录
            leaveRecords = leaveRecordEntities.stream().filter(f -> {
                String curDateStr = commonData.getDateStr();
                DateTime dateTime = DateUtil.parseDate(curDateStr);
                DateTime start = DateUtil.parseDate(DateUtil.formatDate(f.getStartTime()));
                DateTime end = DateUtil.parseDate(DateUtil.formatDate(f.getEndTime()));

                boolean in = DateUtil.isIn(dateTime, start, end);
                return in;
            }).collect(Collectors.toList());

            if (!ObjectUtils.isEmpty(leaveRecords)) {
                //当前日期范围内 存在请假。判断请假计入考勤。目前只有事件计入
                isLeave = true;
            }
        }

        /*AttendanceLeaveRecordEntity attendanceLeaveRecordEntity = attendanceLeaveRecordService.selectOne(leaveRecordQuery);
        if (!ObjectUtils.isEmpty(attendanceLeaveRecordEntity)) {
            // log.info("当天员工请假，不做考勤处理！staffId:{},name:{}", commonData.getStaffId(), attendanceLeaveRecordEntity.getLeavePerson());
            //删除当日考勤记录与详细
            AttendanceRecordQuery attendanceRecordQuery = new AttendanceRecordQuery();
            attendanceRecordQuery.setStaffId(commonData.getStaffId());
            attendanceRecordQuery.setAttendanceDateStart(commonData.getDateStr());
            attendanceRecordQuery.setAttendanceDateEnd(commonData.getDateStr());
            List<AttendanceRecordEntity> attendanceRecordEntities = attendanceRecordService.find(attendanceRecordQuery);
            if (!ObjectUtils.isEmpty(attendanceRecordEntities)) {
                //删除
                Long[] delIds = attendanceRecordEntities.stream().map(AttendanceRecordEntity::getId).toArray(Long[]::new);
                attendanceRecordService.remove(delIds, commonData.getContext());
                AttendanceRecordDetailQuery detailQuery = new AttendanceRecordDetailQuery();
                detailQuery.setRecordIdList(Arrays.asList(delIds));
                List<AttendanceRecordDetailEntity> detailEntities = attendanceRecordDetailService.find(detailQuery);
                if (!ObjectUtils.isEmpty(detailEntities)) {
                    attendanceRecordDetailService.remove(detailEntities.stream().map(AttendanceRecordDetailEntity::getId).toArray(Long[]::new), commonData.getContext());
                }
            }
            //删除当天该员工的异常记录与打卡考勤记录
            deleteErrorRecord(commonData.getDateStr(), commonData.getStaffId(), commonData.getContext());
            return;
        }*/

        //特殊日期考勤配置
        //List<AttendanceGroupFixedworkSpecialEntity> specialEntities = specialService.find(new AttendanceGroupFixedworkSpecialQuery().fixedWorkId(attendanceGroupFixedworkEntity.getId()));
        List<AttendanceGroupFixedworkSpecialEntity> specialEntities = fixedSpecialGroupMap.get(attendanceGroupFixedworkEntity.getId());
        if (!ObjectUtils.isEmpty(specialEntities)) {
            //分组 需要考勤与不需要考勤
            Map<Boolean, List<AttendanceGroupFixedworkSpecialEntity>> collect = specialEntities.stream().collect(Collectors.partitioningBy(item -> item.getMust() == MustEnum.是.getValue()));
            List<AttendanceGroupFixedworkSpecialEntity> mustList = collect.get(true);
            if (!ObjectUtils.isEmpty(mustList)) {
                //需要打卡
                for (AttendanceGroupFixedworkSpecialEntity specialEntity : mustList) {
                    //必须考勤时间，单位日
                    Date specialTime = specialEntity.getSpecialTime();
                    //判断当前考勤日期是否需要考勤，如果需要重叠 则更新为特殊日期考勤
                    //判断考勤日期与特殊日期是否一致
                    if (!ObjectUtils.isEmpty(specialTime) && DateUtil.formatDate(commonData.getAttendanceDate()).equals(DateUtil.formatDate(specialTime))) {
                        //更新打卡情况
                        if (!ObjectUtils.isEmpty(specialEntity.getClassId())) {
                            weekClassId = specialEntity.getClassId();
                        }
                    }
                }
            }
            List<AttendanceGroupFixedworkSpecialEntity> mustNotList = collect.get(false);
            if (!ObjectUtils.isEmpty(mustNotList)) {
                //不需要考勤 查看是时间段还是单独时间
                for (AttendanceGroupFixedworkSpecialEntity specialEntity : mustNotList) {
                    if (AddWayEnum.单个日期.getValue() == specialEntity.getAddWay()) {
                        Date specialTime = specialEntity.getSpecialTime();
                        if (!ObjectUtils.isEmpty(specialTime) && DateUtil.parseDate(commonData.getDateStr()).equals(DateUtil.formatDate(specialTime))) {
                            log.info("当天特殊日期，无需考勤！dateStr:{}", commonData.getDateStr());
                            return;
                        }
                    }

                    if (AddWayEnum.时间段.getValue() == specialEntity.getAddWay()) {
                        Date specialStartTime = specialEntity.getSpecialStartTime();
                        Date specialEndTime = specialEntity.getSpecialEndTime();
                        if (!ObjectUtils.isEmpty(specialStartTime) && !ObjectUtils.isEmpty(specialEndTime)) {
                            boolean in = DateUtil.isIn(DateUtil.parseDate(commonData.getDateStr()), specialStartTime, specialEndTime);
                            if (in) {
                                //直接返回 无班次信息
                                log.info("当天特殊日期，无需考勤！dateStr:{}", commonData.getDateStr());
                                return;
                            }
                        }
                    }
                }
            }
        }

        //获取班次信息
        //   AttendanceClassEntity attendanceClassEntity = attendanceClassService.get(weekClassId);
        AttendanceClassEntity attendanceClassEntity = classEntityMap.get(weekClassId);
        if (ObjectUtils.isEmpty(attendanceClassEntity)) {
            log.info("attendanceClassEntity is null ,weekClassId:{}", weekClassId);
            return;
        }

        //查询当天，该人员的考勤记录
/*        AttendanceRecordHikQuery recordHikQuery = new AttendanceRecordHikQuery();
        recordHikQuery.setAttendanceDateStart(commonData.getDateStr());
        recordHikQuery.setAttendanceDateEnd(commonData.getDateStr());
        recordHikQuery.setStaffId(commonData.getStaffId());
        recordHikQuery.setOrderColList(Arrays.asList(new OrderCol("attendanceDate")));
        List<AttendanceRecordHikEntity> recordHikEntities = recordHikService.find(recordHikQuery);*/

        List<AttendanceRecordHikEntity> recordHikEntities = commonData.getRecordHikEntities();


        List<AttendanceClassDetailEntity> attendanceClassDetailEntities = attendanceClassEntity.getAttendanceClassDetailList();

        Integer orderNum = 0;
        for (AttendanceClassDetailEntity classDetailEntity : attendanceClassDetailEntities) {
            orderNum++;
            AttendanceRecordDetailEntity recordDetailEntity = new AttendanceRecordDetailEntity();
            recordDetailEntity.setShiftsId(classDetailEntity.getId());
            recordDetailEntity.setShiftsName(classDetailEntity.getClassName());

            recordDetailEntity.setGoWorkResult(GoWorkResultEnum.缺卡.getValue());
            //recordDetailEntity.setGoWorkDate(DateUtil.parse(commonData.getDateStr() + " " + DateUtil.formatTime(classDetailEntity.getGoWorkDate())));
            recordDetailEntity.setOffWorkResult(GoWorkResultEnum.缺卡.getValue());
            //recordDetailEntity.setOffWorkDate(DateUtil.parse(commonData.getDateStr() + " " + DateUtil.formatTime(classDetailEntity.getOffWorkDate())));
            recordDetailEntity.setOrderNum(orderNum);
            commonData.getDetailEntityList().add(recordDetailEntity);
        }

        if (!ObjectUtils.isEmpty(recordHikEntities)) {
            //针对当天的考勤记录进行计算与判断
            //获取当前班的多个班次，一个班次为一个上下班时间段
            for (AttendanceRecordHikEntity recordHikEntity : recordHikEntities) {
                Date attendanceDate = recordHikEntity.getAttendanceDate();
                //遍历班次详细记录
                for (AttendanceClassDetailEntity classDetail : attendanceClassDetailEntities) {
                    //计算区间范围
                    //上班打卡前时间
                    Date goWorkDateBefore = DateUtil.offsetMinute(classDetail.getGoWorkDate(), -classDetail.getGoWorkDateBefore() - 1);
                    //上班打卡后时间
                    Date goWorkDateAfter = DateUtil.offsetMinute(classDetail.getGoWorkDate(), classDetail.getGoWorkDateAfter() + 1);
                    // 下班打卡前时间
                    Date offWorkDateBefore = DateUtil.offsetMinute(classDetail.getOffWorkDate(), -classDetail.getOffWorkDateBefore() - 1);
                    //下班打卡后时间,默认偏移多一分钟
                    Date offWorkDateAfter = DateUtil.offsetMinute(classDetail.getOffWorkDate(), classDetail.getOffWorkDateAfter() + 1);
                    //判断考勤时间是否在上班打卡区间内  true 在 false 不在  格式化时间
                    //String currDate = DateUtil.formatTime(attendanceDate);
                    Date curDateTime = DateUtil.parseTime(DateUtil.formatTime(attendanceDate));
                    boolean goInTime = DateUtil.isIn(curDateTime, goWorkDateBefore, goWorkDateAfter);
                    //判断考勤时间是否在下班打卡区间内
                    boolean offInTime = DateUtil.isIn(curDateTime, offWorkDateBefore, offWorkDateAfter);
                    //判断在上班与下班区间访问内   在上班的最后时间 与下班的开始时间
                    boolean goOffBetweenTime = DateUtil.isIn(curDateTime, goWorkDateAfter, offWorkDateBefore);
                    boolean updateCheck = false;

                    if (goInTime) {
                        //如果是上班打卡区间范围,判断是否迟到
                        for (AttendanceRecordDetailEntity attendanceRecordDetailEntity : commonData.getDetailEntityList()) {
                            if (attendanceRecordDetailEntity.getShiftsId() == classDetail.getId()) {
                                attendanceRecordDetailEntity.setGoWorkResult(GoWorkResultEnum.正常.getValue());
                                attendanceRecordDetailEntity.setGoWorkDate(recordHikEntity.getAttendanceDate());
                                updateCheck = true;
                            }
                        }
                    } else {
                        if (goOffBetweenTime) {
                            for (AttendanceRecordDetailEntity attendanceRecordDetailEntity : commonData.getDetailEntityList()) {
                                if (attendanceRecordDetailEntity.getShiftsId() == classDetail.getId() && GoWorkResultEnum.缺卡.getValue() == attendanceRecordDetailEntity.getGoWorkResult()) {
                                    attendanceRecordDetailEntity.setGoWorkResult(GoWorkResultEnum.迟到.getValue());
                                    attendanceRecordDetailEntity.setGoWorkDate(recordHikEntity.getAttendanceDate());
                                    updateCheck = true;
                                }
                            }
                        }
                    }
                    if (offInTime) {
                        for (AttendanceRecordDetailEntity attendanceRecordDetailEntity : commonData.getDetailEntityList()) {
                            if (attendanceRecordDetailEntity.getShiftsId() == classDetail.getId()) {
                                attendanceRecordDetailEntity.setOffWorkResult(OffWorkResultEnum.正常.getValue());
                                attendanceRecordDetailEntity.setOffWorkDate(recordHikEntity.getAttendanceDate());
                            }
                        }
                    } else {
                        if (goOffBetweenTime) {
                            for (AttendanceRecordDetailEntity attendanceRecordDetailEntity : commonData.getDetailEntityList()) {
                                if (attendanceRecordDetailEntity.getShiftsId() == classDetail.getId() && !updateCheck) {
                                    attendanceRecordDetailEntity.setOffWorkResult(OffWorkResultEnum.早退.getValue());
                                    attendanceRecordDetailEntity.setOffWorkDate(recordHikEntity.getAttendanceDate());
                                }
                            }
                        }
                    }
                }
            }
        }
        if (!ObjectUtils.isEmpty(commonData.getDetailEntityList())) {
            //判断当前计算的时间，如果小于缺卡打卡时间 则删除详细考勤记录
            Iterator<AttendanceRecordDetailEntity> iterator = commonData.getDetailEntityList().iterator();
            while (iterator.hasNext()) {
                AttendanceRecordDetailEntity next = iterator.next();
                if (next.getGoWorkResult() == GoWorkResultEnum.缺卡.getValue()) {
                    if (DateUtil.compare(new Date(), next.getGoWorkDate()) < 0) {
                        iterator.remove();
                    }
                }
                if (next.getOffWorkResult() == OffWorkResultEnum.缺卡.getValue()) {
                    if (DateUtil.compare(new Date(), next.getOffWorkDate()) < 0) {
                        next.setOffWorkDate(null);
                        //  next.setOffWorkResult(OffWorkResultEnum.正常.getValue());
                        next.setOffWorkResult(null);
                    }
                }
            }

            // AttendanceClassDetailEntity attendanceClassDetailEntity = attendanceClassDetailService.get(commonData.getDetailEntityList().get(0).getShiftsId());
            AttendanceClassDetailEntity attendanceClassDetailEntity = classDetailEntityMap.get(commonData.getDetailEntityList().get(0).getShiftsId());

            commonData.getAttendanceRecordEntity().setClassId(attendanceClassDetailEntity == null ? 0L : attendanceClassDetailEntity.getClassId());
            commonData.getAttendanceRecordEntity().setClassName(attendanceClassDetailEntity == null ? "" : attendanceClassDetailEntity.getClassName());
        }

        //todo 判断当日当前人员是否存在请假，有请假则重新计算考勤  并根据时间段 更新详细记录中的请假状态
        if (isLeave) {
            //查看请假时间段，是否为跨天记录
            for (AttendanceLeaveRecordEntity leaveRecord : leaveRecords) {
                //  AttendanceLeaveRecordEntity leaveRecord = leaveRecords.get(0);
                long between = DateUtil.between(leaveRecord.getStartTime(), leaveRecord.getEndTime(), DateUnit.DAY);
                if (between > 0) {
                    //跨天 判断当前日期是否在全天，没在 就
                    //判断日期是否在最后一天 不是的话 为全天
                    long betweened = DateUtil.between(DateUtil.parseDate(commonData.getDateStr()), leaveRecord.getEndTime(), DateUnit.DAY);
                    if (betweened > 0) {
                        //全天
                        calLeaveDate(commonData, DateUtil.parseDateTime(commonData.getDateStr() + " 00:00:00"), DateUtil.parseDateTime(commonData.getDateStr() + " 23:59:59"));
                    } else if (betweened == 0) {
                        //最后一天
                        calLeaveDate(commonData, DateUtil.parseDateTime(commonData.getDateStr() + " 00:00:00"), leaveRecord.getEndTime());
                    }

                } else if (between == 0) {
                    calLeaveDate(commonData, leaveRecord.getStartTime(), leaveRecord.getEndTime());
                } else {
                    //错误
                }
            }
        }

        //生成异常记录
        genErrorAttendRecord(commonData.getContext(), commonData.getDateStr(), commonData.getAttendanceRecordEntity(), commonData.getDetailEntityList());

    }

    /**
     * 计算异常
     *
     * @param commonData
     * @param startLeaveTime
     * @param endLeaveTime
     */
    private void calLeaveDate(CommonData commonData, Date startLeaveTime, Date endLeaveTime) {
        //当日 请假开始时间
/*        Date startLeaveTime = leaveRecord.getStartTime();
        Date endLeaveTime = leaveRecord.getEndTime();*/
        //修改当日记录集
        List<AttendanceRecordDetailEntity> detailEntityList = commonData.getDetailEntityList();

        for (AttendanceRecordDetailEntity detail : detailEntityList) {
            Integer goWorkResult = detail.getGoWorkResult();
            Integer offWorkResult = detail.getOffWorkResult();
            Date goWorkDate = detail.getGoWorkDate();
            Date offWorkDate = detail.getOffWorkDate();
            AttendanceClassDetailEntity attendanceClassDetailEntity = classDetailEntityMap.get(detail.getShiftsId());

            if (GoWorkResultEnum.请假.getValue() < goWorkResult) {
                //判断 异常记录是否在请假时间段内 如果缺卡是没有goWorkDate的
                if (ObjectUtils.isEmpty(goWorkDate)) {
                    //goWorkDate为空 缺卡状态
                    Date goWorkDate1 = attendanceClassDetailEntity.getGoWorkDate();

                    if(attendanceClassDetailEntity.getGoWorkDateAfter()>0){
                        goWorkDate1=DateUtil.offsetMinute(goWorkDate1, attendanceClassDetailEntity.getGoWorkDateAfter());

                    }

                    //判断请假区间是否在上班区间内 如果在 则设置为请假 格式化时间范围
                    boolean in = DateUtil.isIn(goWorkDate1, DateUtil.parse(DateUtil.format(startLeaveTime, "HH:mm:ss"), "HH:mm:ss"),
                            DateUtil.parse(DateUtil.format(endLeaveTime, "HH:mm:ss"), "HH:mm:ss"));
                    if(in){
                        detail.setGoWorkResult(GoWorkResultEnum.请假.getValue());
                    }

                } else {
                    boolean in = DateUtil.isIn(goWorkDate, startLeaveTime, endLeaveTime);
                    if (in) {
                        detail.setGoWorkResult(GoWorkResultEnum.请假.getValue());
                    }
                }
            }

            if (GoWorkResultEnum.请假.getValue() < offWorkResult) {
                //判断 异常记录是否在请假时间段内
                // DateUtil.between()
                if (ObjectUtils.isEmpty(offWorkDate)) {
                    Date offWorkDate1 = attendanceClassDetailEntity.getOffWorkDate();

                    if(attendanceClassDetailEntity.getOffWorkDateBefore()>0){
                        offWorkDate1=DateUtil.offsetMinute(offWorkDate1, -attendanceClassDetailEntity.getOffWorkDateBefore());
                    }

                    boolean in = DateUtil.isIn(offWorkDate1, DateUtil.parse(DateUtil.format(startLeaveTime, "HH:mm:ss"), "HH:mm:ss"),
                            DateUtil.parse(DateUtil.format(endLeaveTime, "HH:mm:ss"), "HH:mm:ss"));
                    if (in) {
                        detail.setOffWorkResult(GoWorkResultEnum.请假.getValue());
                    }
                } else {
                    boolean in = DateUtil.isIn(offWorkDate, startLeaveTime, endLeaveTime);
                    if (in) {
                        detail.setOffWorkResult(GoWorkResultEnum.请假.getValue());
                    }
                }
            }
        }
    }

    private void deleteErrorRecord(String dateStr, Long staffId, Context context) {
        //删除当前员工当日未处理的异常后，重新添加
        AttendanceRecordErrorQuery errorQuery = new AttendanceRecordErrorQuery();
        errorQuery.setErrorDateTimeStart(dateStr);
        errorQuery.setErrorDateTimeEnd(dateStr);
        errorQuery.setStaffId(staffId);
        errorQuery.setProcessStatus(YesNoEnum.NO.getValue());
        List<AttendanceRecordErrorEntity> attendanceRecordErrorEntities = errorService.find(errorQuery);
        Long[] errorIds = attendanceRecordErrorEntities.stream().map(i -> i.getId()).toArray(Long[]::new);
        if (!ObjectUtils.isEmpty(errorIds)) {
            log.info("删除 {} 人员:{} 异常记录:{}",dateStr,staffId, JSON.toJSONString(attendanceRecordErrorEntities));
            errorService.remove(errorIds, context);
        }
    }


    public void genErrorAttendRecord(Context context, String dateStr, AttendanceRecordEntity attendanceRecordEntity, List<AttendanceRecordDetailEntity> detailEntityList) {
        //处理异常打卡，所以异常打卡的 都新增一条记录
        List<AttendanceRecordErrorEntity> errorEntityList = new ArrayList<>();
       // Map<Long, AttendanceClassDetailEntity> classDetailEntityMap = attendanceClassDetailService.find(new AttendanceClassDetailQuery()).stream().collect(Collectors.toMap(x -> x.getId(), y -> y, (o, n) -> n));
        for (AttendanceRecordDetailEntity recordDetailEntity : detailEntityList) {
            Integer goWorkResult = recordDetailEntity.getGoWorkResult();
            Integer offWorkResult = recordDetailEntity.getOffWorkResult();
            //判断是否是离职员工 如果是 则不添加
            //判断上班
            // AttendanceClassDetailEntity attendanceClassDetailEntity = attendanceClassDetailService.get(recordDetailEntity.getShiftsId());
            AttendanceClassDetailEntity attendanceClassDetailEntity = classDetailEntityMap.get(recordDetailEntity.getShiftsId());
            if (ObjectUtils.isEmpty(attendanceClassDetailEntity)) continue;
            //判断上班
            if (GoWorkResultEnum.请假.getValue() < goWorkResult) {
                AttendanceRecordErrorEntity errorEntity = new AttendanceRecordErrorEntity();
                errorEntity.initAttrValue();
                BeanUtils.copyProperties(attendanceRecordEntity, errorEntity, new String[]{"id"});

                errorEntity.setShiftsId(recordDetailEntity.getShiftsId());
                errorEntity.setShiftsName(recordDetailEntity.getShiftsName());
                errorEntity.setProcessStatus(YesNoEnum.NO.getValue());
                errorEntity.setCreateTime(new Date());
                errorEntity.setCreateUserId(1L);
                Date goWorkDate = attendanceClassDetailEntity.getGoWorkDate();
                errorEntity.setGoOffDateTime(DateUtil.parseDateTime(dateStr + " " + DateUtil.formatTime(goWorkDate)).toJdkDate());
                if (!ObjectUtils.isEmpty(recordDetailEntity.getGoWorkDate())) {
                    errorEntity.setErrorDateTime(recordDetailEntity.getGoWorkDate());
                    errorEntity.setActualAttendanceDateTime(recordDetailEntity.getGoWorkDate());
                } else {
                    errorEntity.setErrorDateTime(DateUtil.parseDateTime(dateStr + " " + DateUtil.formatTime(goWorkDate)).toJdkDate());
                }
                if (GoWorkResultEnum.早退.getValue() == recordDetailEntity.getGoWorkResult()) {
                    errorEntity.setErrorStatus(ErrorStatusEnum.早退.getValue());
                }
                if (GoWorkResultEnum.迟到.getValue() == recordDetailEntity.getGoWorkResult()) {
                    errorEntity.setErrorStatus(ErrorStatusEnum.迟到.getValue());
                }
                if (GoWorkResultEnum.缺卡.getValue() == recordDetailEntity.getGoWorkResult()) {
                    errorEntity.setErrorStatus(ErrorStatusEnum.缺卡.getValue());
                    errorEntity.setActualAttendanceDateTime(null);
                }
                errorEntity.setProcessResult(errorEntity.getErrorStatus().toString());
                errorEntityList.add(errorEntity);
            }
            //判断下班
            if (OffWorkResultEnum.请假.getValue() < offWorkResult) {
                AttendanceRecordErrorEntity errorEntity = new AttendanceRecordErrorEntity();
                errorEntity.initAttrValue();
                BeanUtils.copyProperties(attendanceRecordEntity, errorEntity, new String[]{"id"});
                errorEntity.setShiftsId(recordDetailEntity.getShiftsId());
                errorEntity.setShiftsName(recordDetailEntity.getShiftsName());
                errorEntity.setProcessStatus(YesNoEnum.NO.getValue());
                errorEntity.setCreateTime(new Date());
                errorEntity.setCreateUserId(1L);
                Date offWorkDate = attendanceClassDetailEntity.getOffWorkDate();
                errorEntity.setGoOffDateTime(DateUtil.parseDateTime(dateStr + " " + DateUtil.formatTime(offWorkDate)).toJdkDate());
                if (!ObjectUtils.isEmpty(recordDetailEntity.getOffWorkDate())) {
                    errorEntity.setErrorDateTime(recordDetailEntity.getOffWorkDate());
                    errorEntity.setActualAttendanceDateTime(recordDetailEntity.getOffWorkDate());
                } else {
                    errorEntity.setErrorDateTime(DateUtil.parseDateTime(dateStr + " " + DateUtil.formatTime(offWorkDate)).toJdkDate());
                }
                if (OffWorkResultEnum.缺卡.getValue() == recordDetailEntity.getOffWorkResult()) {
                    errorEntity.setErrorStatus(ErrorStatusEnum.缺卡.getValue());
                    errorEntity.setActualAttendanceDateTime(null);
                }
                if (OffWorkResultEnum.早退.getValue() == recordDetailEntity.getOffWorkResult()) {
                    errorEntity.setErrorStatus(ErrorStatusEnum.早退.getValue());
                }
                if (OffWorkResultEnum.迟到.getValue() == recordDetailEntity.getOffWorkResult()) {
                    errorEntity.setErrorStatus(ErrorStatusEnum.迟到.getValue());
                }
                errorEntity.setProcessResult(errorEntity.getErrorStatus().toString());
                errorEntityList.add(errorEntity);
            }
        }
        //删除当前员工当日未处理的异常后，重新添加 处理的 不做删除
        deleteErrorRecord(dateStr, attendanceRecordEntity.getStaffId(), context);
        AttendanceRecordErrorQuery errorQuery;

        if (!ObjectUtils.isEmpty(errorEntityList)) {
            //过滤异常列表中存在相同的记录
            errorEntityList = errorEntityList.stream().distinct().collect(Collectors.toList());

            for (AttendanceRecordErrorEntity errorEntity : errorEntityList) {
                //查看是否存在相同的异常记录，如果存在 则不添加
                errorQuery = new AttendanceRecordErrorQuery();
                errorQuery.setErrorDateTime(errorEntity.getErrorDateTime());
                errorQuery.setStaffId(errorEntity.getStaffId());
                errorQuery.setShiftsId(errorEntity.getShiftsId());
                errorQuery.setProcessStatus(YesNoEnum.YES.getValue());

                AttendanceRecordErrorEntity attendanceRecordErrorEntity = errorService.selectOne(errorQuery, context);
                if (ObjectUtils.isEmpty(attendanceRecordErrorEntity)) {
                    errorService.save(errorEntity, context);
                }else {
                    //log.info("异常记录已存在，不添加");
                }
            }
        }


    }


    private Boolean checkWorkByHoliday(String date) {
        Boolean bool = false;
        HolidayQuery holidayQuery = new HolidayQuery();
        holidayQuery.setStartTimeStart(date);
        holidayQuery.setStartTimeEnd(date);
        HolidayEntity holidayEntity = holidayService.selectOne(holidayQuery);
        if (!ObjectUtils.isEmpty(holidayEntity)) {
            Integer workorholiday = holidayEntity.getWorkorholiday();
            if (workorholiday == YesNoEnum.YES.getValue()) {
                bool = true;
            }
        }

        return bool;
    }

    private Boolean checkHolidayByWorkDay(String date) {
        Boolean bool = false;
        HolidayQuery holidayQuery = new HolidayQuery();
        holidayQuery.setStartTimeStart(date);
        holidayQuery.setStartTimeEnd(date);
        HolidayEntity holidayEntity = holidayService.selectOne(holidayQuery);
        if (!ObjectUtils.isEmpty(holidayEntity)) {
            Integer workorholiday = holidayEntity.getWorkorholiday();
            if (workorholiday == YesNoEnum.NO.getValue()) {
                bool = true;
            }
        }

        return bool;
    }


    public static void main(String[] args) {

    /*    String date = "2021-05-01 09:00:00";
        String endDate = "2021-05-02 18:00:00";

        long between = DateUtil.between(DateUtil.parseDate(date), DateUtil.parseDate(endDate), DateUnit.DAY);

        System.out.println(between);



        String curDateStr = "2024-01-05";
        DateTime dateTime = DateUtil.parseDate(curDateStr);
        DateTime start = DateUtil.parseDate("2024-01-05 18:45:15");
        DateTime end = DateUtil.parseDate("2024-01-05 08:45:15");

        boolean in = DateUtil.isIn(dateTime, start, end);

        System.out.println(in);*/


        System.out.println(GoWorkResultEnum.getEnumMap().keySet());


    }
}
