package com.dne.ems.service.impl;

import com.dne.ems.dto.RejectFeedbackRequest;
import com.dne.ems.model.Feedback;
import com.dne.ems.model.enums.FeedbackStatus;
import com.dne.ems.repository.FeedbackRepository;
import com.dne.ems.service.SupervisorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 主管反馈审核服务实现类
 * 
 * <p>该服务负责处理主管对用户提交的反馈进行审核的相关功能，
 * 包括获取待审核的反馈列表、批准有效反馈和拒绝无效反馈。
 * 审核结果将直接影响反馈的后续处理流程。</p>
 *
 * @version 1.0
 * @since 2025-06
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SupervisorServiceImpl implements SupervisorService {

    private final FeedbackRepository feedbackRepository;

    /**
     * 获取所有待审核的反馈
     * 
     * <p>查询状态为PENDING_REVIEW的所有反馈记录，这些反馈已通过AI初步审核，
     * 需要主管进行人工审核确认。</p>
     *
     * @return 待审核的反馈列表
     */
    @Override
    public List<Feedback> getFeedbackForReview() {
        log.info("Fetching feedback for supervisor review with status PENDING_REVIEW.");
        return feedbackRepository.findByStatus(FeedbackStatus.PENDING_REVIEW);
    }

    /**
     * 批准反馈
     * 
     * <p>将指定ID的反馈状态从PENDING_REVIEW更新为PENDING_ASSIGNMENT，
     * 表示该反馈已通过主管审核，可以进入任务分配阶段。</p>
     *
     * @param feedbackId 需要批准的反馈ID
     * @throws IllegalArgumentException 如果找不到指定ID的反馈
     * @throws IllegalStateException 如果反馈状态不是PENDING_REVIEW
     */
    @Override
    @Transactional
    public void approveFeedback(Long feedbackId) {
        log.info("Attempting to approve feedback with ID: {}", feedbackId);
        Feedback feedback = feedbackRepository.findById(feedbackId)
                .orElseThrow(() -> new IllegalArgumentException("Feedback not found with ID: " + feedbackId));

        if (feedback.getStatus() != FeedbackStatus.PENDING_REVIEW) {
            log.warn("Feedback {} cannot be approved because its status is {} instead of PENDING_REVIEW.", feedbackId, feedback.getStatus());
            throw new IllegalStateException("Feedback is not in a PENDING_REVIEW state.");
        }

        feedback.setStatus(FeedbackStatus.PENDING_ASSIGNMENT);
        feedbackRepository.save(feedback);
        log.info("Feedback {} approved successfully. Status changed to PENDING_ASSIGNMENT.", feedbackId);
    }

    /**
     * 拒绝反馈
     * 
     * <p>将指定ID的反馈状态从PENDING_REVIEW更新为CLOSED_INVALID，
     * 表示该反馈未通过主管审核，将被标记为无效并关闭。</p>
     *
     * @param feedbackId 需要拒绝的反馈ID
     * @param request 拒绝反馈的请求
     * @throws IllegalArgumentException 如果找不到指定ID的反馈
     * @throws IllegalStateException 如果反馈状态不是PENDING_REVIEW
     */
    @Override
    @Transactional
    public void rejectFeedback(Long feedbackId, RejectFeedbackRequest request) {
        log.info("Attempting to reject feedback with ID: {}. Reason: {}", feedbackId, request.getNotes());
        Feedback feedback = feedbackRepository.findById(feedbackId)
                .orElseThrow(() -> new IllegalArgumentException("Feedback not found with ID: " + feedbackId));

        if (feedback.getStatus() != FeedbackStatus.PENDING_REVIEW) {
            log.warn("Feedback {} cannot be rejected because its status is {} instead of PENDING_REVIEW.", feedbackId, feedback.getStatus());
            throw new IllegalStateException("Feedback is not in a PENDING_REVIEW state.");
        }

        feedback.setStatus(FeedbackStatus.CLOSED_INVALID);
        // Although we don't have a dedicated field for rejection notes,
        // we can log it for audit purposes. A future enhancement could be to add a field.
        log.info("Feedback {} rejected successfully by user. Reason: {}", feedbackId, request.getNotes());
        feedbackRepository.save(feedback);
        log.info("Feedback {} status changed to CLOSED_INVALID.", feedbackId);
    }
}