package com.smartoffice.leave;

import com.smartoffice.common.ApiException;
import com.smartoffice.notification.NotificationService;
import com.smartoffice.notification.NotificationType;
import com.smartoffice.user.User;
import com.smartoffice.user.UserRepository;
import jakarta.transaction.Transactional;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.List;

@Service
public class LeaveService {
    private final LeaveRepository leaveRepository;
    private final UserRepository userRepository;
    private final NotificationService notificationService;

    public LeaveService(LeaveRepository leaveRepository, UserRepository userRepository, NotificationService notificationService) {
        this.leaveRepository = leaveRepository;
        this.userRepository = userRepository;
        this.notificationService = notificationService;
    }

    @Transactional
    public LeaveDto create(String username, LeaveRequestCreate request) {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new ApiException(404, "User not found"));
        if (request.getEndTime().isBefore(request.getStartTime())) {
            throw new ApiException(400, "End time must be after start time");
        }
        LeaveRequest leave = new LeaveRequest();
        leave.setUser(user);
        leave.setType(request.getType());
        leave.setStartTime(request.getStartTime());
        leave.setEndTime(request.getEndTime());
        leave.setReason(request.getReason());
        leaveRepository.save(leave);
        return LeaveDto.from(leave);
    }

    public List<LeaveDto> myRequests(String username) {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new ApiException(404, "User not found"));
        return leaveRepository.findAllByUserOrderByCreatedAtDesc(user)
                .stream().map(LeaveDto::from).toList();
    }

    public List<LeaveDto> pendingRequests() {
        return leaveRepository.findAllByStatusOrderByCreatedAtDesc(LeaveStatus.PENDING)
                .stream().map(LeaveDto::from).toList();
    }

    @Transactional
    public LeaveDto approve(String approverUsername, Long id, String note, boolean approved) {
        User approver = userRepository.findByUsername(approverUsername)
                .orElseThrow(() -> new ApiException(404, "User not found"));
        LeaveRequest leave = leaveRepository.findById(id)
                .orElseThrow(() -> new ApiException(404, "Leave request not found"));
        if (leave.getStatus() != LeaveStatus.PENDING) {
            throw new ApiException(409, "Leave request already processed");
        }
        leave.setApprover(approver);
        leave.setDecidedAt(Instant.now());
        leave.setStatus(approved ? LeaveStatus.APPROVED : LeaveStatus.REJECTED);
        String title = approved ? "请假已批准" : "请假被拒绝";
        String content = title + " - " + note;
        notificationService.notifyUser(leave.getUser(), NotificationType.APPROVAL, title, content);
        return LeaveDto.from(leave);
    }
}
