package service;

import dao.DAOFactory;
import dao.LeaveRequestDAO;
import model.LeaveRequest;
import model.Student;
import model.ApprovalStatus;
import java.util.Date;
import java.util.List;
import java.util.Calendar;

/**
 * 请假申请服务类
 */
public class LeaveRequestService {
    private final LeaveRequestDAO leaveRequestDAO = DAOFactory.getLeaveRequestDAO();
    private final StudentService studentService = new StudentService();

    /**
     * 提交请假申请
     * @param request 请假申请信息
     * @return 是否提交成功
     */
    public boolean submitLeaveRequest(LeaveRequest request) {
        // 检查学生是否存在
        Student student = studentService.getStudentById(request.getStudent().getId());
        if (student == null) {
            System.out.println("提交请假失败：学生不存在，ID=" + request.getStudent().getId());
            return false;
        }

        // 检查请假时间是否合理
        if (!isValidLeaveTime(request.getStartTime(), request.getEndTime())) {
            System.out.println("提交请假失败：请假时间不合理，开始时间=" + request.getStartTime() + "，结束时间=" + request.getEndTime());
            return false;
        }

        // 设置初始状态为待审批
        request.setStatus(ApprovalStatus.PENDING);
        request.setRequestTime(new Date());

        int result = leaveRequestDAO.insert(request);
        if (result == 0) {
            System.out.println("提交请假失败：数据库插入失败");
            return false;
        }
        System.out.println("提交请假成功：ID=" + request.getId());
        return true;
    }

    /**
     * 审批请假申请
     * @param requestId 请假申请ID
     * @param status 审批状态
     * @param comment 审批意见
     * @return 是否审批成功
     */
    public boolean approveLeaveRequest(int requestId, ApprovalStatus status, String comment) {
        // 检查请假申请是否存在
        LeaveRequest request = leaveRequestDAO.findById(requestId);
        if (request == null) {
            return false;
        }

        // 检查是否可以审批
        if (request.getStatus() != ApprovalStatus.PENDING) {
            return false;
        }

        return leaveRequestDAO.updateStatus(requestId, status, comment) > 0;
    }

    /**
     * 获取学生的请假记录
     * @param studentId 学生ID
     * @return 请假记录列表
     */
    public List<LeaveRequest> getStudentLeaveRequests(int studentId) {
        return leaveRequestDAO.findByStudentId(studentId);
    }

    /**
     * 获取指定状态的请假申请
     * @param status 审批状态
     * @return 请假申请列表
     */
    public List<LeaveRequest> getLeaveRequestsByStatus(ApprovalStatus status) {
        return leaveRequestDAO.findByStatus(status);
    }

    /**
     * 获取所有请假申请
     * @return 请假申请列表
     */
    public List<LeaveRequest> getAllLeaveRequests() {
        return leaveRequestDAO.findAll();
    }

    /**
     * 根据ID获取请假申请
     * @param requestId 请假申请ID
     * @return 请假申请信息
     */
    public LeaveRequest getLeaveRequestById(int requestId) {
        return leaveRequestDAO.findById(requestId);
    }

    /**
     * 撤销请假申请
     * @param requestId 请假申请ID
     * @return 是否撤销成功
     */
    public boolean cancelLeaveRequest(int requestId) {
        // 检查请假申请是否存在
        LeaveRequest request = leaveRequestDAO.findById(requestId);
        if (request == null) {
            return false;
        }

        // 检查是否可以撤销（只有待审批状态可以撤销）
        if (request.getStatus() != ApprovalStatus.PENDING) {
            return false;
        }

        // 删除请假申请
        return leaveRequestDAO.deleteById(requestId) > 0;
    }

    /**
     * 检查请假时间是否合理
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 是否合理
     */
    private boolean isValidLeaveTime(Date startTime, Date endTime) {
        // 开始时间和结束时间不能为空
        if (startTime == null || endTime == null) {
            return false;
        }

        // 结束时间必须在开始时间之后
        if (endTime.before(startTime) || endTime.equals(startTime)) {
            return false;
        }

        // 开始时间不能是过去24小时以前的时间
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.HOUR, -24);
        Date oneDayAgo = cal.getTime();
        
        if (startTime.before(oneDayAgo)) {
            return false;
        }

        // 请假时长不能超过30天
        long durationInDays = (endTime.getTime() - startTime.getTime()) / (1000 * 60 * 60 * 24);
        if (durationInDays > 30) {
            return false;
        }

        return true;
    }
}
