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

import cn.hutool.core.date.DateUtil;
import com.mortals.xhx.common.code.GoWorkResultEnum;
import com.mortals.xhx.common.code.MustEnum;
import com.mortals.xhx.common.code.TypeEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.attendance.model.*;
import com.mortals.xhx.module.attendance.service.AttendanceClassService;
import com.mortals.xhx.module.attendance.service.AttendanceGroupFixedworkService;
import com.mortals.xhx.module.attendance.service.AttendanceGroupFixedworkSpecialService;
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.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

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


    private AttendanceGroupFixedworkService attendanceGroupFixedworkService;

    private AttendanceClassService attendanceClassService;

    private AttendanceGroupFixedworkSpecialService specialService;

    private HolidayService holidayService;


    public FixWorkAttendance(int type) {
        super(type);
        this.attendanceGroupFixedworkService = SpringUtils.getBean(AttendanceGroupFixedworkService.class);
        this.attendanceClassService = SpringUtils.getBean(AttendanceClassService.class);
        this.specialService = SpringUtils.getBean(AttendanceGroupFixedworkSpecialService.class);
        this.holidayService = SpringUtils.getBean(HolidayService.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();
        //判断当前考勤日期为周几
        String week = super.getWeek(commonData.getAttendanceDate());
        //log.info("week:{}", week);
        //通过考勤日期的星期拿到班次id.
        if (ObjectUtils.isEmpty(attendanceGroupFixedworkEntity)) {
            log.info("attendanceGroupFixedworkEntity is null ! groupId:{}", commonData.getAttendanceGroupEntity().getId());
            return;
        }
        //获取当前日期的详细班次
        Long weekClassId = this.getWeekClassId(attendanceGroupFixedworkEntity, week);
        Boolean checkWorkByHoliday = checkWorkByHoliday();
        Boolean checkHolidayByWorkDay = checkHolidayByWorkDay();

        if (weekClassId == -1L) {
            //跳过本次循环
            log.info("当前日期不在考勤时间范围内，不做处理！");
            if (!checkWorkByHoliday) {
                return;
            }
        } else {
            if (checkHolidayByWorkDay) {
                //本来当天是需要考勤的，但是是节假日，则不计算考勤
                return;
            }
        }
        //特殊日期考勤配置
        List<AttendanceGroupFixedworkSpecialEntity> specialEntities = specialService.find(new AttendanceGroupFixedworkSpecialQuery().fixedWorkId(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 (DateUtil.formatDate(commonData.getAttendanceDate()).equals(DateUtil.formatDate(specialTime))) {
                        //更新打卡情况
                        weekClassId = specialEntity.getClassId();
                    }
                }
            }
            List<AttendanceGroupFixedworkSpecialEntity> mustNotList = collect.get(false);

            if (!ObjectUtils.isEmpty(mustNotList)) {
                //不需要考勤 查看是时间段还是单独时间
                for (AttendanceGroupFixedworkSpecialEntity specialEntity : mustNotList) {
                    Date specialTime = specialEntity.getSpecialTime();
                    if (!ObjectUtils.isEmpty(specialTime)) {
                        if (DateUtil.formatDate(commonData.getAttendanceDate()).equals(DateUtil.formatDate(specialTime))) {
                            //当前日期不需要考勤打卡
                            //获取班次信息
                          //  AttendanceClassEntity attendanceClassEntity = attendanceClassService.get(weekClassId);
                            AttendanceClassEntity attendanceClassEntity = classEntityMap.get(weekClassId);
                            if (ObjectUtils.isEmpty(attendanceClassEntity)) {
                                log.info("attendanceClassEntity is null ,weekClassId:{}", weekClassId);
                                return;
                            }
                            //List<AttendanceClassDetailEntity> attendanceClassDetailEntities = attendanceClassDetailService.find(new AttendanceClassDetailQuery().classId(attendanceClassEntity.getId()));
                            //获取当前班的多个班次，一个班次为一个上下班时间段
                            List<AttendanceClassDetailEntity> attendanceClassDetailEntities = attendanceClassEntity.getAttendanceClassDetailList();
                            for (AttendanceClassDetailEntity classDetail : attendanceClassDetailEntities) {
                                for (AttendanceRecordDetailEntity attendanceRecordDetailEntity : commonData.getDetailEntityList()) {
                                    if (attendanceRecordDetailEntity.getShiftsId() == classDetail.getId()) {
                                        attendanceRecordDetailEntity.setGoWorkResult(GoWorkResultEnum.正常.getValue());
                                        attendanceRecordDetailEntity.setGoWorkDate(commonData.getAttendanceDate());
                                    }
                                }
                                for (AttendanceRecordDetailEntity attendanceRecordDetailEntity : commonData.getDetailEntityList()) {
                                    if (attendanceRecordDetailEntity.getShiftsId() == classDetail.getId()) {
                                        attendanceRecordDetailEntity.setOffWorkResult(GoWorkResultEnum.正常.getValue());
                                        attendanceRecordDetailEntity.setOffWorkDate(commonData.getAttendanceDate());
                                    }
                                }
                            }
                        }
                        return;
                    }
                }
            }
        }

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

        //List<AttendanceClassDetailEntity> attendanceClassDetailEntities = attendanceClassDetailService.find(new AttendanceClassDetailQuery().classId(attendanceClassEntity.getId()));
        //获取当前班的多个班次，一个班次为一个上下班时间段
        List<AttendanceClassDetailEntity> attendanceClassDetailEntities = attendanceClassEntity.getAttendanceClassDetailList();
        Integer orderNum = 0;
        //构造数据
        if (ObjectUtils.isEmpty(commonData.getDetailEntityList())) {
            //遍历班次 构建初始详细考勤数据 当天的第二次考勤记录进来时不做初始化
            for (AttendanceClassDetailEntity classDetailEntity : attendanceClassDetailEntities) {
                orderNum++;
                AttendanceRecordDetailEntity recordDetailEntity = new AttendanceRecordDetailEntity();
                recordDetailEntity.setShiftsId(classDetailEntity.getId());
                recordDetailEntity.setShiftsName(classDetailEntity.getClassName());
                recordDetailEntity.setGoWorkResult(GoWorkResultEnum.缺卡.getValue());
                recordDetailEntity.setOffWorkResult(GoWorkResultEnum.缺卡.getValue());
                recordDetailEntity.setOrderNum(orderNum);
                commonData.getDetailEntityList().add(recordDetailEntity);
            }
        }
        //遍历班次详细记录
        for (AttendanceClassDetailEntity classDetail : attendanceClassDetailEntities) {
            //计算区间范围
            //上班打卡前时间
            Date goWorkDateBefore = DateUtil.offsetMinute(classDetail.getGoWorkDate(), -classDetail.getGoWorkDateBefore());
            //上班打卡后时间
            Date goWorkDateAfter = DateUtil.offsetMinute(classDetail.getGoWorkDate(), classDetail.getGoWorkDateAfter());
            // 下班打卡前时间
            Date offWorkDateBefore = DateUtil.offsetMinute(classDetail.getOffWorkDate(), -classDetail.getOffWorkDateBefore());
            //下班打卡后时间
            Date offWorkDateAfter = DateUtil.offsetMinute(classDetail.getOffWorkDate(), classDetail.getOffWorkDateAfter());
            //判断考勤时间是否在上班打卡区间内  true 在 false 不在  格式化时间
            //String currDate = DateUtil.formatTime(attendanceDate);
            Date curDateTime = DateUtil.parseTime(DateUtil.formatTime(commonData.getAttendanceDate())).toJdkDate();
            boolean goInTime = DateUtil.isIn(curDateTime, goWorkDateBefore, goWorkDateAfter);
            //判断考勤时间是否在下班打卡区间内
            boolean offInTime = DateUtil.isIn(curDateTime, offWorkDateBefore, offWorkDateAfter);
            if (goInTime == false && offInTime == false) {
              //  log.info("考勤时间不在上班区间与下班区间中，不做处理！attendDate:{}", DateUtil.formatDateTime(commonData.getAttendanceDate()));
                continue;
            }
            if (goInTime) {
                //如果是上班打卡区间范围,判断是否迟到
                boolean inTime = DateUtil.isIn(curDateTime, goWorkDateBefore, classDetail.getGoWorkDate());
                if (inTime) {
                    for (AttendanceRecordDetailEntity attendanceRecordDetailEntity : commonData.getDetailEntityList()) {
                        if (attendanceRecordDetailEntity.getShiftsId() == classDetail.getId()) {
                            attendanceRecordDetailEntity.setGoWorkResult(GoWorkResultEnum.正常.getValue());
                            attendanceRecordDetailEntity.setGoWorkDate(commonData.getAttendanceDate());
                        }
                    }
                } else {
                    for (AttendanceRecordDetailEntity attendanceRecordDetailEntity : commonData.getDetailEntityList()) {
                        if (attendanceRecordDetailEntity.getShiftsId() == classDetail.getId()) {
                            attendanceRecordDetailEntity.setGoWorkResult(GoWorkResultEnum.迟到.getValue());
                            attendanceRecordDetailEntity.setGoWorkDate(commonData.getAttendanceDate());
                        }
                    }
                }
            }
            if (offInTime) {
                boolean inTime = DateUtil.isIn(curDateTime, classDetail.getOffWorkDate(), offWorkDateAfter);
                if (inTime) {
                    for (AttendanceRecordDetailEntity attendanceRecordDetailEntity : commonData.getDetailEntityList()) {
                        if (attendanceRecordDetailEntity.getShiftsId() == classDetail.getId()) {
                            attendanceRecordDetailEntity.setOffWorkResult(GoWorkResultEnum.正常.getValue());
                            attendanceRecordDetailEntity.setOffWorkDate(commonData.getAttendanceDate());
                        }
                    }
                } else {
                    for (AttendanceRecordDetailEntity attendanceRecordDetailEntity : commonData.getDetailEntityList()) {
                        if (attendanceRecordDetailEntity.getShiftsId() == classDetail.getId()) {
                            attendanceRecordDetailEntity.setOffWorkResult(GoWorkResultEnum.早退.getValue());
                            attendanceRecordDetailEntity.setOffWorkDate(commonData.getAttendanceDate());
                        }
                    }
                }
            }
        }
    }

    private Boolean checkWorkByHoliday() {
        Boolean bool = false;
        HolidayQuery holidayQuery = new HolidayQuery();
        holidayQuery.setStartTimeStart(DateUtil.today());
        holidayQuery.setStartTimeEnd(DateUtil.today());
        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() {
        Boolean bool = false;
        HolidayQuery holidayQuery = new HolidayQuery();
        holidayQuery.setStartTimeStart(DateUtil.today());
        holidayQuery.setStartTimeEnd(DateUtil.today());
        HolidayEntity holidayEntity = holidayService.selectOne(holidayQuery);
        if (!ObjectUtils.isEmpty(holidayEntity)) {
            Integer workorholiday = holidayEntity.getWorkorholiday();
            if (workorholiday == YesNoEnum.NO.getValue()) {
                bool = true;
            }
        }

        return bool;
    }
}
