package cn.iocoder.yudao.module.attendance.service.info;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.attendance.controller.admin.employeesetting.vo.AttendanceEmployeeSettingRespVO;
import cn.iocoder.yudao.module.attendance.controller.admin.info.vo.*;
import cn.iocoder.yudao.module.attendance.dal.dataobject.business.AttendanceBusinessDO;
import cn.iocoder.yudao.module.attendance.dal.dataobject.info.AttendanceInfoDO;
import cn.iocoder.yudao.module.attendance.dal.dataobject.leave.AttendanceLeaveDO;
import cn.iocoder.yudao.module.attendance.dal.dataobject.workdaysetting.AttendanceWorkdaySettingDO;
import cn.iocoder.yudao.module.attendance.dal.mysql.info.AttendanceInfoMapper;
import cn.iocoder.yudao.module.attendance.service.business.AttendanceBusinessService;
import cn.iocoder.yudao.module.attendance.service.employeesetting.AttendanceEmployeeSettingService;
import cn.iocoder.yudao.module.attendance.service.leave.AttendanceLeaveService;
import cn.iocoder.yudao.module.attendance.service.out.AttendanceOutService;
import cn.iocoder.yudao.module.attendance.service.workdaysetting.AttendanceWorkdaySettingService;
import cn.iocoder.yudao.module.employee.api.EmployeeApi;
import cn.iocoder.yudao.module.employee.api.dto.EmployeeQueryReqDTO;
import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
import cn.iocoder.yudao.module.employee.controller.admin.info.vo.EmployeeInfoPageReqVO;
import cn.iocoder.yudao.module.employee.dal.dataobject.info.EmployeeInfoDO;
import cn.iocoder.yudao.module.employee.service.info.EmployeeInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import javax.annotation.Resource;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.attendance.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.employee.enums.ErrorCodeConstants.EMPLOYEE_INFO_NOT_EXISTS;

/**
 * 考勤信息 Service 实现类
 *
 * @author zhaopq
 */
@Service
@Validated
public class AttendanceInfoServiceImpl implements AttendanceInfoService {

    private static final Logger log = LoggerFactory.getLogger(AttendanceInfoServiceImpl.class);
    @Resource
    private AttendanceInfoMapper infoMapper;
    @Resource
    private EmployeeInfoService employeeInfoService;
    @Resource
    private AttendanceEmployeeSettingService attendanceEmployeeSettingService;
    @Resource
    private AttendanceLeaveService attendanceLeaveService;
    @Resource
    private AttendanceBusinessService attendanceBusinessService;
    @Resource
    private AttendanceOutService attendanceOutService;
    @Resource
    private AttendanceWorkdaySettingService workdaySettingService;
    @Resource
    private EmployeeApi employeeApi;

    @Override
    public Long createInfo(AttendanceInfoSaveReqVO createReqVO) {
        // 选择员工信息
        EmployeeRespDTO choseEmployee = employeeApi.getEmployeeById(createReqVO.getEmployeeId());
        if (choseEmployee != null) {
            createReqVO.setDeptId(choseEmployee.getDeptId());
            createReqVO.setDeptName(choseEmployee.getDeptName());
        }
        if (createReqVO != null && createReqVO.getAttendanceDate() != null) {
            LocalDate localDate = createReqVO.getAttendanceDate();
            // 使用 DateTimeFormatter 来格式化 LocalDate 为 "yyyy-MM" 格式的字符串
            String formattedMonth = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
            createReqVO.setAttendanceMonth(formattedMonth);
        }
        // 插入
        AttendanceInfoDO info = BeanUtils.toBean(createReqVO, AttendanceInfoDO.class);
        infoMapper.insert(info);
        // 返回
        return info.getId();
    }

    @Override
    public void updateInfo(AttendanceInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateInfoExists(updateReqVO.getId());
        // 选择员工信息
        EmployeeRespDTO choseEmployee = employeeApi.getEmployeeById(updateReqVO.getEmployeeId());
        if (choseEmployee != null) {
            updateReqVO.setDeptId(choseEmployee.getDeptId());
            updateReqVO.setDeptName(choseEmployee.getDeptName());
        }
        if (updateReqVO != null && updateReqVO.getAttendanceDate() != null) {
            LocalDate localDate = updateReqVO.getAttendanceDate();
            // 使用 DateTimeFormatter 来格式化 LocalDate 为 "yyyy-MM" 格式的字符串
            String formattedMonth = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
            updateReqVO.setAttendanceMonth(formattedMonth);
        }
        // 更新
        AttendanceInfoDO updateObj = BeanUtils.toBean(updateReqVO, AttendanceInfoDO.class);
        infoMapper.updateById(updateObj);
    }

    @Override
    public void deleteInfo(Long id) {
        // 校验存在
        validateInfoExists(id);
        // 删除
        infoMapper.deleteById(id);
    }

    private void validateInfoExists(Long id) {
        if (infoMapper.selectById(id) == null) {
            throw exception(ATTENDANCE_INFO_NOT_EXISTS);
        }
    }

    @Override
    public AttendanceInfoDO getInfo(Long id) {
        return infoMapper.selectById(id);
    }

    @Override
    public PageResult<AttendanceInfoDO> getInfoPage(AttendanceInfoPageReqVO pageReqVO) {
        return infoMapper.selectPage(pageReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class) // 添加事务，异常则回滚所有导入
    public AttendanceInfoImportRespVO importAttendanceInfoList(List<AttendanceInfoImportExcelVO> importAttendanceInfos) {
        if (CollUtil.isEmpty(importAttendanceInfos)) {
            throw exception(ATTENDANCE_INFO_IMPORT_LIST_IS_EMPTY);
        }

        // 获取用户信息和租户ID
        LoginUser user = SecurityFrameworkUtils.getLoginUser();
        Long tenantId = user != null && user.getTenantId() != null ? user.getTenantId() : 0L;

        // 初始化响应对象
        AttendanceInfoImportRespVO respVO = AttendanceInfoImportRespVO.builder()
                .createEmployeeNames(new ArrayList<>())
                .deleteEmployeeNames(new ArrayList<>())
                .failureEmployeeNames(new LinkedHashMap<>())
                .build();

        // 收集要删除和创建的数据
        List<AttendanceInfoDO> toInsert = new ArrayList<>();
        List<Long> toDeleteIds = new ArrayList<>();
        List<String> failedEmployeeNames = new ArrayList<>();

        for (AttendanceInfoImportExcelVO importAttendance : importAttendanceInfos) {
            try {
                // 验证员工是否存在
                validateEmployeeExists(importAttendance.getEmployeeName(), importAttendance.getEmployeeMobile(), tenantId);
                EmployeeQueryReqDTO reqDTO = new EmployeeQueryReqDTO().setName(importAttendance.getEmployeeName()).setPhone(importAttendance.getEmployeeMobile());
                EmployeeRespDTO choseEmployee = employeeApi.getEmployee(reqDTO);
                if (choseEmployee != null) {
                    importAttendance.setDeptId(choseEmployee.getDeptId());
                    importAttendance.setDeptName(choseEmployee.getDeptName());
                }
                if (importAttendance != null && importAttendance.getAttendanceDate() != null) {
                    LocalDate localDate = importAttendance.getAttendanceDate()[0];
                    // 使用 DateTimeFormatter 来格式化 LocalDate 为 "yyyy-MM" 格式的字符串
                    String formattedMonth = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
                    importAttendance.setAttendanceMonth(formattedMonth);
                }
                // 查找并收集要删除的数据
                List<AttendanceInfoDO> existingInfos = infoMapper.selectPage(
                        new AttendanceInfoPageReqVO().setAttendanceDate(importAttendance.getAttendanceDate()).setEmployeeMobile(importAttendance.getEmployeeMobile())
                ).getList();
                toDeleteIds.addAll(existingInfos.stream().map(AttendanceInfoDO::getId).collect(Collectors.toList()));

                // 准备要插入的数据
                AttendanceInfoDO attendanceInfoDO = BeanUtils.toBean(importAttendance, AttendanceInfoDO.class);
                toInsert.add(attendanceInfoDO);

            } catch (ServiceException ex) {
                failedEmployeeNames.add(importAttendance.getEmployeeName());
                respVO.getFailureEmployeeNames().put(importAttendance.getEmployeeName(), ex.getMessage());
            }
        }

        // 批量删除
        if (!toDeleteIds.isEmpty()) {
            infoMapper.deleteBatchIds(toDeleteIds);
            toDeleteIds.forEach(id -> respVO.getDeleteEmployeeNames().add(this.getInfo(id).getEmployeeName())); // 假设有一个findEmployeeNameById方法来获取员工名
        }

        // 批量插入
        if (!toInsert.isEmpty()) {
            infoMapper.insertBatch(toInsert);
            toInsert.forEach(info -> respVO.getCreateEmployeeNames().add(info.getEmployeeName()));
        }
        return respVO;
    }

    @Override
    public PageResult<AttendanceDailyInfoRespVO> getDailyInfoPage(AttendanceDailyInfoPageReqVO pageReqVO) {
        int currentPage = pageReqVO.getPageNo();
        if (currentPage > 0) {
            pageReqVO.setPageNo(currentPage - 1);
        }
        List<AttendanceDailyInfoRespVO> list = infoMapper.getDailyInfoPage(pageReqVO);
        if (list != null && list.size() > 0) {
            for (AttendanceDailyInfoRespVO info : list) {
                // 查询该员工考勤规则
                AttendanceEmployeeSettingRespVO respVO = attendanceEmployeeSettingService.getByEmployeeId(info.getEmployeeId());
                if (respVO != null && respVO.getStartTime() != null && respVO.getEndTime() != null
                        && info.getWorkStartTime() != null && info.getWorkEndTime() != null) {

                    LocalTime startTime = respVO.getStartTime();
                    LocalTime endTime = respVO.getEndTime();
                    LocalTime workStartTime = info.getWorkStartTime();
                    LocalTime workEndTime = info.getWorkEndTime();

                    // 计算迟到分钟数
                    long lateMinute = Duration.between(startTime, workStartTime).toMinutes();
                    if (lateMinute < 0) { // 如果上班时间早于开始时间，则视为不迟到
                        lateMinute = 0;
                    }

                    // 计算早退分钟数
                    long leaveEarlyMinute = Duration.between(workEndTime, endTime).toMinutes();
                    if (leaveEarlyMinute < 0) { // 如果下班时间晚于结束时间，则视为不早退
                        leaveEarlyMinute = 0;
                    }

                    // 计算总工作分钟数
                    long totalWorkingMinute = Duration.between(workStartTime, workEndTime).toMinutes();

                    // 设置结果
                    info.setLateMinute(String.format("%d", lateMinute));
                    info.setEarlyMinute(String.format("%d", leaveEarlyMinute));
                    info.setTotalWorkingMinute(String.format("%d", totalWorkingMinute));
                }
            }
        }
        return new PageResult<>(list, (long) list.size());
    }

    @Override
    public PageResult<AttendanceMonthlyInfoRespVO> getMonthlyInfoPage(AttendanceMonthlyInfoPageReqVO pageReqVO) {
        int currentPage = pageReqVO.getPageNo();
        if (currentPage > 0) {
            pageReqVO.setPageNo(currentPage - 1);
        }
        // 获取每日考勤信息
        List<AttendanceInfoDO> dos = infoMapper.selectPage(pageReqVO).getList();
        List<AttendanceDailyInfoRespVO> dailyInfoList = BeanUtils.toBean(dos, AttendanceDailyInfoRespVO.class);
        // 创建一个空的月度考勤信息列表
        List<AttendanceMonthlyInfoRespVO> monthlyInfoList = new ArrayList<>();

        // 查询指定月份的工作日
        List<AttendanceWorkdaySettingDO> workDays = workdaySettingService.getWorkdays(pageReqVO.getAttendanceMonth());

        // 按员工ID和月份分组每日考勤信息
        Map<String, List<AttendanceDailyInfoRespVO>> groupedDailyInfo = new HashMap<>();
        for (AttendanceDailyInfoRespVO dailyInfo : dailyInfoList) {
            String key = dailyInfo.getEmployeeId() + "-" + pageReqVO.getAttendanceMonth();
            groupedDailyInfo.computeIfAbsent(key, k -> new ArrayList<>()).add(dailyInfo);
        }

        // 遍历每个员工的每日考勤信息
        for (Map.Entry<String, List<AttendanceDailyInfoRespVO>> entry : groupedDailyInfo.entrySet()) {
            List<AttendanceDailyInfoRespVO> employeeDailyInfoList = entry.getValue();
            if (employeeDailyInfoList.isEmpty()) continue;

            // 创建一个新的月度考勤信息对象
            AttendanceMonthlyInfoRespVO monthlyInfo = new AttendanceMonthlyInfoRespVO();
            monthlyInfo.setEmployeeId(employeeDailyInfoList.get(0).getEmployeeId());
            monthlyInfo.setEmployeeName(employeeDailyInfoList.get(0).getEmployeeName());
            monthlyInfo.setDeptId(employeeDailyInfoList.get(0).getDeptId());
            monthlyInfo.setDeptName(employeeDailyInfoList.get(0).getDeptName());
            monthlyInfo.setEmployeeMobile(employeeDailyInfoList.get(0).getEmployeeMobile());
            monthlyInfo.setAttendanceMonth(pageReqVO.getAttendanceMonth());

            // 计算月度数据
            Map<String, Object> monthlyDataMap = getMonthlyData(employeeDailyInfoList, workDays);

            // 设置月度考勤统计数据
            monthlyInfo.setAttendanceDays(((BigDecimal) monthlyDataMap.get("cq")).intValue());
            monthlyInfo.setNormalClockCount(((BigDecimal) monthlyDataMap.get("zc")).intValue());
            monthlyInfo.setLateCount(((BigDecimal) monthlyDataMap.get("cd")).intValue());
            monthlyInfo.setAbsenteeismCount(((BigDecimal) monthlyDataMap.get("kg")).intValue());
            monthlyInfo.setEarlyCount(((BigDecimal) monthlyDataMap.get("zt")).intValue());
            monthlyInfo.setMissingClockCount(((BigDecimal) monthlyDataMap.get("qk")).intValue());
            monthlyInfo.setLeaveCount(((BigDecimal) monthlyDataMap.get("qj")).intValue());

            // 添加到月度考勤信息列表
            monthlyInfoList.add(monthlyInfo);
        }
        return new PageResult<>(monthlyInfoList, (long) monthlyInfoList.size());
    }

    private boolean validateEmployeeExists(String employeeName, String employeeMobile, Long tenantId) {
        // 关闭数据权限，避免因为没有数据权限，查询不到数据，进而导致唯一校验不正确
        return DataPermissionUtils.executeIgnore(() -> {
            List<EmployeeInfoDO> list = employeeInfoService.getInfoPage(new EmployeeInfoPageReqVO().setName(employeeName).setPhone(employeeMobile).setTenantId(tenantId)).getList();
           if (CollUtil.isEmpty(list)) {
               throw exception(EMPLOYEE_INFO_NOT_EXISTS);
           }
            return true;
        });
    }


    // 计算月度数据的方法
    private Map<String, Object> getMonthlyData(List<AttendanceDailyInfoRespVO> dailyInfoList,
                                               List<AttendanceWorkdaySettingDO> workDays) {
        Map<String, Object> map = new HashMap<>();
        map.put("cq", BigDecimal.ZERO); // 出勤天数
        map.put("zc", BigDecimal.ZERO); // 正常打卡
        map.put("cd", BigDecimal.ZERO); // 迟到次数
        map.put("kg", BigDecimal.ZERO); // 矿工次数
        map.put("zt", BigDecimal.ZERO); // 早退次数
        map.put("qk", BigDecimal.ZERO); // 缺卡次数
        map.put("qj", BigDecimal.ZERO); // 请假次数

        // 查询该员工考勤规则
        AttendanceEmployeeSettingRespVO respVO = attendanceEmployeeSettingService.getByEmployeeId(dailyInfoList.get(0).getEmployeeId());
        if (respVO == null) {
            return map;
//            throw exception(ATTENDANCE_EMPLOYEE_SETTING_NOT_EXISTS);
        }
        LocalTime ruleStartTime = respVO.getStartTime();
        LocalTime ruleEndTime = respVO.getEndTime();
        if (ruleStartTime == null || ruleEndTime == null) {
            throw exception(ATTENDANCE_EMPLOYEE_SETTING_NOT_EXISTS);
        }
        for (AttendanceDailyInfoRespVO dailyInfo : dailyInfoList) {
            LocalDate date = dailyInfo.getAttendanceDate();
            LocalTime start = dailyInfo.getWorkStartTime();
            LocalTime end = dailyInfo.getWorkEndTime();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 或者 "yyyy-MM"，根据你的需求
            String dateString = date.format(formatter);
            boolean isWorkDay = workDays.stream().anyMatch(wd -> wd.getWorkDate().equals(dateString));

            if (isWorkDay) {
                AttendanceBusinessDO businessDO = attendanceBusinessService
                        .selectByDateAndEmployeeId(date, dailyInfo.getEmployeeId());
                List<AttendanceLeaveDO> leaveDOs = attendanceLeaveService
                        .selectByDateAndEmployeeId(date, dailyInfo.getEmployeeId());

                if (start == null && end == null) {
                    handleNoClock(map, businessDO, leaveDOs);
                } else if (start == null || end == null) {
                    handleSingleClock(map, start, end, ruleStartTime, ruleEndTime, businessDO, leaveDOs, date);
                } else {
                    handleBothClocks(map, start, end, ruleStartTime, ruleEndTime, businessDO, leaveDOs, date);
                }
            }
        }

        return map;
    }

    // 处理未打卡情况的方法 工作日
    private void handleNoClock(Map<String, Object> map, AttendanceBusinessDO businessDO, List<AttendanceLeaveDO> leaveDOs) {
        if (businessDO != null) {
            map.put("qj", ((BigDecimal) map.get("qj")).add(BigDecimal.ONE));
        } else if (!leaveDOs.isEmpty()) {
            double day = calculateLeaveDays(leaveDOs);
            map.put("qj", ((BigDecimal) map.get("qj")).add(BigDecimal.valueOf(day)));
            if (day == 0.5) {
                map.put("qk", ((BigDecimal) map.get("qk")).add(BigDecimal.ONE));
            }
        } else {
            map.put("qk", ((BigDecimal) map.get("qk")).add(new BigDecimal(2)));
            map.put("kg", ((BigDecimal) map.get("kg")).add(BigDecimal.ONE));
        }
    }

    // 处理一次打卡情况的方法
    private void handleSingleClock(Map<String, Object> map, LocalTime start, LocalTime end,
                                   LocalTime ruleStartTime, LocalTime ruleEndTime,
                                   AttendanceBusinessDO businessDO, List<AttendanceLeaveDO> leaveDOs, LocalDate date) {
        double day = 0.0;
        if (businessDO != null) {
            map.put("qj", ((BigDecimal) map.get("qj")).add(new BigDecimal(0.5)));
        } else if (!leaveDOs.isEmpty()) {
            day = calculateLeaveDays(leaveDOs);
            map.put("qj", ((BigDecimal) map.get("qj")).add(BigDecimal.valueOf(day)));
        } else {
            map.put("qk", ((BigDecimal) map.get("qk")).add(BigDecimal.ONE));
        }
        if (day != 1.0) {
            if (start != null) {
                boolean isLate = start.isAfter(ruleStartTime);
                updateAttendanceCounts(map, isLate, true);
            } else if (end != null) {
                boolean isEarly = end.isBefore(ruleEndTime);
                updateAttendanceCounts(map, isEarly, false);
            }
        }
    }

    // 处理两次打卡情况的方法
    private void handleBothClocks(Map<String, Object> map, LocalTime start, LocalTime end,
                                  LocalTime ruleStartTime, LocalTime ruleEndTime,
                                  AttendanceBusinessDO businessDO, List<AttendanceLeaveDO> leaveDOs, LocalDate date) {
        boolean isLate = start.isAfter(ruleStartTime);
        boolean isEarly = end.isBefore(ruleEndTime);
        updateAttendanceCounts(map, isLate, isEarly);
        if (businessDO != null) {
            map.put("qj", ((BigDecimal) map.get("qj")).add(BigDecimal.ONE));
        } else if (!leaveDOs.isEmpty()) {
            double day = calculateLeaveDays(leaveDOs);
            map.put("qj", ((BigDecimal) map.get("qj")).add(BigDecimal.valueOf(day)));
        }
    }

    // 计算请假天数的方法
    private double calculateLeaveDays(List<AttendanceLeaveDO> leaveDOs) {
        double totalDays = 0.0;
        for (AttendanceLeaveDO leaveDO : leaveDOs) {
            totalDays += getLeaveDays(leaveDO.getStartDate(), leaveDO.getEndDate(), leaveDO.getStartTime(), leaveDO.getEndTime());
        }
        return totalDays;
    }

    // 更新考勤计数的方法
    private void updateAttendanceCounts(Map<String, Object> map, boolean isLate, boolean isEarly) {
        if (isLate) {
            map.put("cd", ((BigDecimal) map.get("cd")).add(BigDecimal.ONE));
            map.put("cq", ((BigDecimal) map.get("cq")).add(BigDecimal.valueOf(0.5)));
        } else {
            map.put("zc", ((BigDecimal) map.get("zc")).add(BigDecimal.ONE));
            map.put("cq", ((BigDecimal) map.get("cq")).add(BigDecimal.valueOf(0.5)));
        }
        if (isEarly) {
            map.put("zt", ((BigDecimal) map.get("zt")).add(BigDecimal.ONE));
            map.put("cq", ((BigDecimal) map.get("cq")).add(BigDecimal.valueOf(0.5)));
        } else {
            map.put("zc", ((BigDecimal) map.get("zc")).add(BigDecimal.ONE));
            map.put("cq", ((BigDecimal) map.get("cq")).add(BigDecimal.valueOf(0.5)));
        }
    }

    // 获取请假天数的方法
    private Double getLeaveDays(String startDateStr, String endDateStr, String startTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date startDate = null;
        Date endDate = null;
        try {
            startDate = sdf.parse(startDateStr);
            endDate = sdf.parse(endDateStr);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);
        Double day = 0.0;
//        String[] remarks = remark.split(":");
        Boolean isSameDay = DateUtil.isSameDay(endDate, startDate);
        long size = ((endDate.getTime() - startDate.getTime()) / 1000 / 24 / 60 / 60) + 1;
        for (int j = 0; j < size; j++) {
//            String time =sdf.format(cal.getTime());
            if (isSameDay) {//请假开始时间和结束时间是同一天
                if (startTime.equals(endTime)) {
                    day += 0.5;
                } else {
                    day += 1;
                }
            } else {
                if (j == 0) {
                    if (startTime.equals(endTime)) {
                        day += 1;
                    } else {
                        day += 0.5;
                    }
                } else if (j == size - 1) {
                    if (startTime.equals(endTime)) {
                        day += 0.5;
                    } else {
                        day += 1;
                    }
                } else {
                    day += 1;
                }
            }
            cal.add(Calendar.DATE, 1);
        }
        return day;
    }

}