package cn.com.oa.service.impl;

import cn.com.oa.common.constant.DataService;
import cn.com.oa.mapper.AttendanceRecordResultMapper;
import cn.com.oa.model.*;
import cn.com.oa.model.dto.AttendanceRecordDTO;
import cn.com.oa.model.dto.FlowInstanceDTO;
import cn.com.oa.model.dto.UserDTO;
import cn.com.oa.model.vo.AttendanceRecordResultVo;
import cn.com.oa.model.vo.DeptAttendanceRecordVo;
import cn.com.oa.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 */
@Service
public class AttendanceRecordResultServiceImpl extends ServiceImpl<AttendanceRecordResultMapper, AttendanceRecordResult> implements IAttendanceRecordResultService {

    @Autowired
    private UserService userService;
    @Autowired
    private AttendanceRecordService attendanceRecordService;
    @Autowired
    private IFlowInstanceService flowInstanceService;
    @Autowired
    private AttendanceShiftSegmentService attendanceShiftSegmentService;

    @Override
    public Map<String, Object> getResultMonth() {
        Map constantData = DataService.getConstantData();
        Group group = (Group)constantData.get("defaultGroup");
        AttendanceRecordResultVo attendanceRecordResult = new AttendanceRecordResultVo();
        attendanceRecordResult.setUnitId(group.getUNIVERSALID());
        Map<String, Object> map = baseMapper.getResultMonth(attendanceRecordResult);
        return map;
    }

    @Override
    public List<DeptAttendanceRecordVo> getResultDay() {
        Map constantData = DataService.getConstantData();
        Group group = (Group) constantData.get("defaultGroup");

        // 考勤规则
        AttendanceShiftSegment segment = attendanceShiftSegmentService.getBaseMapper().selectList(new QueryWrapper<AttendanceShiftSegment>()
                .eq("unit_id", group.getUNIVERSALID())
                .eq("segment_status", "1")).get(0);
        String[] workTimes = segment.getWorkTime().split(";");
        String[] amWorkTimes = workTimes[0].split(",");
        String[] pmWorkTimes = workTimes[1].split(",");

        // 获取考勤规则中的上班时间（精度到分钟，不需要秒）
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");  // 精度到分钟，不需要秒
        LocalTime amStartTime = LocalTime.parse(amWorkTimes[0], timeFormatter);
        LocalTime amEndTime = LocalTime.parse(amWorkTimes[1], timeFormatter);
        LocalTime pmStartTime = LocalTime.parse(pmWorkTimes[0], timeFormatter);
        LocalTime pmEndTime = LocalTime.parse(pmWorkTimes[1], timeFormatter);

        // 各部门应到人数
        User user = new User();
        user.setUnitid(group.getUNIVERSALID());
        user.setUserState(1);
        List<UserDTO> deptCountList = userService.getDeptCount(user);

        // 当日打卡数据
        AttendanceRecord attendanceRecord = new AttendanceRecord();
        attendanceRecord.setUnitId(group.getUNIVERSALID());
        List<AttendanceRecordDTO> recordList = attendanceRecordService.getDayResultList(attendanceRecord);

        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 遍历统计部门数据
        List<DeptAttendanceRecordVo> deptAttendanceRecordVos = new ArrayList<>();
        for (UserDTO userDTO : deptCountList) {
            DeptAttendanceRecordVo deptAttendanceRecordVo = new DeptAttendanceRecordVo();
            deptAttendanceRecordVo.setDeptName(userDTO.getDeptName());
            // 应出勤人数
            int targetCount = userDTO.getDeptCount();
            // 部门打卡记录
            List<AttendanceRecordDTO> deptRecordList = recordList.stream().filter(item -> item.getDeptName().equals(userDTO.getDeptName())).collect(Collectors.toList());
            // 已打卡人数
            int recordCount = deptRecordList.size();
            int actualCount = recordCount;
            int lateCount = 0;
            int leaveEarlyCount = 0;
            int absenceCount = targetCount - recordCount;
            int leaveCount = 0;

            // 遍历打卡记录
            for (AttendanceRecordDTO record : deptRecordList) {
                // 获取打卡日期
                LocalDate recordDate = record.getFirstAttTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

                // 只统计当天的打卡记录
                if (!recordDate.isEqual(today)) continue;

                // 将 Date 转换为 LocalTime（精度到分钟，不需要秒）
                LocalTime firstTime = record.getFirstAttTime().toInstant().atZone(ZoneId.systemDefault()).toLocalTime().truncatedTo(ChronoUnit.MINUTES);
                LocalTime lastTime = record.getLastAttTime().toInstant().atZone(ZoneId.systemDefault()).toLocalTime().truncatedTo(ChronoUnit.MINUTES);

                // 标记是否已经减少 actualCount
                boolean flag = false;

                // 迟到处理：判断首次打卡是否迟到
                if (firstTime.isAfter(amStartTime) && firstTime.isBefore(amEndTime)) {
                    // 上午迟到
                    lateCount++;
                    if (!flag) {
                        actualCount--;
                        flag = true;
                    }
                } else if (firstTime.isAfter(pmStartTime) && firstTime.isBefore(pmEndTime)) {
                    // 下午迟到
                    lateCount++;
                    if (!flag) {
                        actualCount--;
                        flag = true;
                    }
                }

                // 只打卡一次的跳过
                if (firstTime.equals(lastTime)) continue;

                // 早退处理：判断最后打卡是否早退
                if (lastTime.isBefore(amEndTime) && lastTime.isAfter(amStartTime)) {
                    // 上午早退
                    leaveEarlyCount++;
                    if (!flag) {
                        actualCount--;
                    }
                } else if (lastTime.isBefore(pmEndTime) && lastTime.isAfter(pmStartTime)) {
                    // 下午早退
                    leaveEarlyCount++;
                    if (!flag) {
                        actualCount--;
                    }
                }
            }

            deptAttendanceRecordVo.setTargetCount(targetCount);
            deptAttendanceRecordVo.setRecordCount(recordCount);
            deptAttendanceRecordVo.setActualCount(actualCount);
            deptAttendanceRecordVo.setLateCount(lateCount);
            deptAttendanceRecordVo.setLeaveEarlyCount(leaveEarlyCount);
            deptAttendanceRecordVo.setLeaveCount(leaveCount);
            deptAttendanceRecordVo.setAbsenceCount(absenceCount);
            deptAttendanceRecordVos.add(deptAttendanceRecordVo);
        }
        // 当日请假数据
        FlowInstanceDTO flowInstanceDTO = new FlowInstanceDTO();
        flowInstanceDTO.setModelName("请假申请");
        String leaveTableId = flowInstanceService.getFlowInsTableId(flowInstanceDTO);
        flowInstanceDTO.setTableId(leaveTableId);
        List<Map<String, Object>> leaveFormList = flowInstanceService.getFlowInsFormInfo(flowInstanceDTO);
        // 解析请假记录
        for (Map<String, Object> leaveForm : leaveFormList) {
            // 获取请假表单中的时间数据
//            String startTime = getTimeStr(leaveForm.get("form_element_859634698045503"));
//            String endTime = getTimeStr(leaveForm.get("form_element_859634699051312"));
            String username = (String) leaveForm.get("name");
            String deptName = (String) leaveForm.get("form_element_859634696056378");

            // 定义日期时间格式，注意时间部分的格式
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

            // 解析请假时间为 LocalDateTime
            LocalDateTime leaveStartDateTime = (LocalDateTime) leaveForm.get("form_element_859634698045503");
            LocalDateTime leaveEndDateTime = (LocalDateTime) leaveForm.get("form_element_859634699051312");

            // 提取日期部分，转换为 LocalDate
            LocalDate leaveStartDate = leaveStartDateTime.toLocalDate();
            LocalDate leaveEndDate = leaveEndDateTime.toLocalDate();

            // 如果请假日期包含今天，则统计为当日请假
            if ((leaveStartDate.isEqual(today) || leaveStartDate.isBefore(today)) &&
                    (leaveEndDate.isEqual(today) || leaveEndDate.isAfter(today))) {
                // 遍历打卡记录
                for (DeptAttendanceRecordVo recordVo : deptAttendanceRecordVos) {
                    if (recordVo.getDeptName().equals(deptName)) {
                        // 统计请假人数
                        recordVo.setLeaveCount(recordVo.getLeaveCount() + 1);
                        break;
                    }
                }
            }
        }
        return deptAttendanceRecordVos;
    }

    @Override
    public List<DeptAttendanceRecordVo> getResultDayGroupByDept() {
        Map constantData = DataService.getConstantData();
        Group group = (Group)constantData.get("defaultGroup");
        // 各部门应到人数
        User user = new User();
        user.setUnitid(group.getUNIVERSALID());
        user.setUserState(1);
        List<UserDTO> deptCountList = userService.getDeptCount(user);
        AttendanceRecord attendanceRecord = new AttendanceRecord();
        attendanceRecord.setUnitId(group.getUNIVERSALID());

        // 当日打卡数据
        List<AttendanceRecordDTO> recordList = attendanceRecordService.getDayResultList(attendanceRecord);
        LocalTime lateThreshold = LocalTime.of(9, 0, 59);
        LocalTime leaveEarlyThreshold = LocalTime.of(17, 30, 0);
        List<DeptAttendanceRecordVo> deptAttendanceRecordVos = new ArrayList<>();
        //遍历deptCount
        for (UserDTO userDTO : deptCountList) {
            //当前部门应道人数
            int deptCountNum = userDTO.getDeptCount();
            //打卡人数
            int recordCount = 0;
            //当前部门实际到人数
            int actualCount = 0;
            //当前部门迟到人数
            int lateCount = 0;
            //当前部门早退人数
            int leaveEarlyCount = 0;
            //当前部门缺勤人数
            int absenceCount = 0;
            //从recordList遍历出deptName为当前部门的数据
            for (AttendanceRecordDTO record : recordList) {
                if (record.getDeptName().equals(userDTO.getDeptName())) {
                    actualCount++;
                    recordCount++;
                    // 将 Date 转换为 LocalTime
                    LocalTime firstTime = record.getFirstAttTime().toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
                    LocalTime lastTime = record.getLastAttTime().toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
                    // 标记是否已经减少 actualCount
                    boolean flag = false;
                    // 迟到处理
                    if (firstTime.isAfter(lateThreshold)) {
                        lateCount++;
                        if (!flag) {
                            actualCount--;
                            flag = true;
                        }
                    }
                    // 只打卡一次的跳过
                    if (firstTime.equals(lastTime)) continue;
                    // 早退处理
                    if (lastTime.isBefore(leaveEarlyThreshold)) {
                        leaveEarlyCount++;
                        if (!flag) {
                            actualCount--;
                        }
                    }
                }
            }
            //计算缺勤人数
            absenceCount=deptCountNum-recordCount;
            DeptAttendanceRecordVo deptAttendanceRecordVo=new DeptAttendanceRecordVo();
            deptAttendanceRecordVo.setDeptName(userDTO.getDeptName());
            deptAttendanceRecordVo.setActualCount(actualCount);
            deptAttendanceRecordVo.setLateCount(lateCount);
            deptAttendanceRecordVo.setLeaveEarlyCount(leaveEarlyCount);
            deptAttendanceRecordVo.setAbsenceCount(absenceCount);
            deptAttendanceRecordVo.setRecordCount(recordCount);
            deptAttendanceRecordVos.add(deptAttendanceRecordVo);
        }
        return deptAttendanceRecordVos;
    }

    String getTimeStr(Object time) {
        if (time instanceof String) {
            return (String) time;
        } else if (time instanceof LocalDateTime) {
            // 推荐使用自定义格式化
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            return ((LocalDateTime) time).format(formatter);
        } else if (time != null) {
            return time.toString(); // 最保守的 fallback（可能格式不标准）
        }
        return null;
    }
}
