package com.bonus.system.att.utils;

import com.bonus.common.core.utils.DateUtils;
import com.bonus.system.att.entity.AttGroupBean;
import com.bonus.system.att.entity.AttSourceDataBean;
import lombok.extern.slf4j.Slf4j;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: fly
 * @date: 2025/2/13 16:07
 * 考勤计算的时间对比工具类
 */
@Slf4j
public class AttTimeUtil {


    // 定义时间格式
    static DateTimeFormatter YY_MM_DD_HH_MM_SS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    static DateTimeFormatter HH_MM_SS = DateTimeFormatter.ofPattern("HH:mm:ss");
    static DateFormat YY_MM_DD = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 判断打卡类型
     * 判断当前时间是否在早5点到中午12点之间，在则为上班打卡，中午12点到明天上午五点则为今天的下班打卡
     * @param currentTime
     * @return
     */
    public static int getAttTypeByTime(String currentTime) {
        if (currentTime == null || currentTime.isEmpty()) {
            // 如果输入为空或为空字符串，则返回默认值（例如2）
            return 1;
        }
        try {
            // 解析传入的时间字符串
            LocalTime time = LocalTime.parse(currentTime, YY_MM_DD_HH_MM_SS);
            // 定义早上5点和中午12点的时间
            LocalTime morningStart = LocalTime.of(5, 0);
            LocalTime noonEnd = LocalTime.of(12, 0);
            // 判断时间是否在5:00到12:00之间
            if (time.isAfter(morningStart) && !time.isAfter(noonEnd)) {
                return 1; // 在早上5点到12点之间
            } else {
                return 2; // 其他时间
            }
        } catch (DateTimeParseException e) {
            // 如果时间格式不正确，返回默认值（例如2）
            e.printStackTrace();
            log.error("判断打卡类型方法出错啦");
            return 1;
        }
    }

    /**
     * 判断打卡时间归属于当天还是昨天
     * 将00:00:00 至 04:59:59 时间变成att_current_day上一天的
     * @param c
     */
    public static void changeAttCurrentDay(AttSourceDataBean c) {
        try {
            // 解析传入的时间字符串
            LocalTime time = LocalTime.parse(c.getAttCurrentTime(), YY_MM_DD_HH_MM_SS);
            // 定义早上5点和中午12点的时间
            LocalTime morningStart = LocalTime.of(0, 0);
            LocalTime noonEnd = LocalTime.of(5, 0);
            // 判断时间是否在0:00到05:00之间
            if (time.isAfter(morningStart) && !time.isAfter(noonEnd)) {
                //获取前一天时间
                String afterDate = DateUtils.getAfterDate(c.getAttCurrentDay());
                c.setAttCurrentDay(afterDate);
            }
        }catch(Exception e){
            e.printStackTrace();
            log.error("判断打卡归属方法出错啦");
        }

    }


    /**
     * 获取两个日期之间的日期列表
     * @param startDateString
     * @param endDateString
     * @return
     */
    public static List<String> getStrDateListBetween(String startDateString, String endDateString) {
        List<String> dateList = new ArrayList<>();
        try {
            // 解析开始日期和结束日期
            Date startDate = YY_MM_DD.parse(startDateString);
            Date endDate = YY_MM_DD.parse(endDateString);
            // 创建 Calendar 实例并设置为开始日期
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            // 循环直到当前日期超过结束日期
            while (!calendar.getTime().after(endDate)) {
                // 将日期格式化为字符串，并添加到列表中
                dateList.add(YY_MM_DD.format(calendar.getTime()));
                // 将日期加一天
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            }
        } catch (ParseException ignored) {
        }
        return dateList;
    }

    public static void processGroupedItems(Map<String, List<AttSourceDataBean>> groupedItems, AttGroupBean attGroupBean) {
        for (Map.Entry<String, List<AttSourceDataBean>> entry : groupedItems.entrySet()) {
            String key = entry.getKey();
            List<AttSourceDataBean> items = entry.getValue();
            if (items.isEmpty()) {
                continue; // 如果列表为空，跳过
            }
            //五点之前的数据属于过来当天的下班打卡，不计入
            LocalTime noonEnd = LocalTime.of(5, 0);
            // 获取上班时间并转换为 LocalTime 以便比较
            LocalTime toWorkTime = LocalTime.parse(attGroupBean.getToWorkTime(), HH_MM_SS);
            // 初始化变量来保存最接近上班时间的数据项及其索引
            AttSourceDataBean closestBeforeToWork = null;
            int closestIndex = -1;
            // 遍历并查找最接近上班时间且 attType=2 的数据项
            //前面已经排过序了，取第一个就可以了
            for (int i = 0; i < items.size(); i++) {
                AttSourceDataBean item = items.get(i);
//                if("王义".equals(item.getName())){
//                    System.out.println(111);
//                }
                if ("2".equals(item.getAttType())) {
                    // 只提取时间部分进行比较
                    LocalTime recordTime = LocalTime.parse(item.getAttCurrentTime().substring(11), HH_MM_SS);
                    // 检查是否在上班时间之前并且是目前找到的最接近上班时间的
                    if (recordTime.isBefore(toWorkTime) && recordTime.isAfter(noonEnd) &&
                            (closestBeforeToWork == null ||
                                    recordTime.isAfter(LocalTime.parse(closestBeforeToWork.getAttCurrentTime().substring(11), HH_MM_SS)))) {
                        closestBeforeToWork = item;
                        closestIndex = i;
                    }
                }
            }
            // 如果找到了符合条件的数据项，则移除它之前的所有数据，包括它自己
            if (closestIndex != -1) {
                List<AttSourceDataBean> filteredItems = items.stream()
                        .skip(closestIndex) // 跳过最接近上班时间的数据项及其之前的所有数据
                        .collect(Collectors.toList());
                // 更新原始映射中的列表
                groupedItems.put(key, filteredItems);
            } else {
                // 如果没有找到符合条件的数据项，可以选择保留所有数据或清空列表
            }
        }
    }

    public static Duration calculateWorkDuration(LocalTime outTime, LocalTime inTime, AttGroupBean group) {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
            // 解析上班、下班、午休开始、结束时间
            LocalTime offWorkTime = LocalTime.parse(group.getOffWorkTime(), formatter);
            LocalTime breakStartTime = LocalTime.parse(group.getBreakStartTime(), formatter);
            LocalTime breakEndTime = LocalTime.parse(group.getBreakEndTime(), formatter);
            // 如果出勤时间在午休时间内，调整出勤时间为午休结束时间
            if (outTime.isAfter(breakStartTime) && outTime.isBefore(breakEndTime)) {
                outTime = breakEndTime;
            }
            // 如果进入时间在午休时间内，调整进入时间为午休开始时间
            if (inTime.isAfter(breakStartTime) && inTime.isBefore(breakEndTime)) {
                inTime = breakStartTime;
            }
            // 如果进入时间在下班时间内，调整进入时间为下班时间
            if (inTime.isAfter(offWorkTime)) {
                inTime = offWorkTime;
            }
            // 计算总的工作时间
            Duration totalDuration = Duration.between(outTime, inTime);
            // 如果时间段跨越了午休时间，减去午休时长
            if (outTime.isBefore(breakEndTime) && inTime.isAfter(breakStartTime)) {
                Duration breakDuration = Duration.between(breakStartTime, breakEndTime);
                totalDuration = totalDuration.minus(breakDuration);
            }
            return totalDuration;
        } catch (DateTimeParseException e) {
            // 处理解析异常，例如记录日志或返回默认值
            System.err.println("时间解析错误: " + e.getMessage());
            return null; // 或者返回一个默认的 LocalDateTime
        }
    }

    /**
     * 判断当前时间是否大于几点
     * @param hour 时
     * @param minute 分
     * @return
     */
    public static boolean timeCheck(int hour,int minute) {
        // 获取当前时间
        LocalTime now = LocalTime.now();
        // 定义目标时间 hour:minutes
        LocalTime targetTime = LocalTime.of(hour, minute);

        // 判断当前时间是否大于
        if (now.isAfter(targetTime)) {
            System.out.println("当前时间已超过 "+hour+":"+minute+"！");
            return true;
        }else {
            System.out.println("当前时间还未到 "+hour+":"+minute+"！");
            return false;
        }
    }

}
