package br.gov.sigefp.rh.service;

import br.gov.sigefp.common.exception.BusinessException;
import br.gov.sigefp.rh.api.dto.PerformanceEvaluationDTO;
import br.gov.sigefp.rh.domain.Agent;
import br.gov.sigefp.rh.domain.CareerEventType;
import br.gov.sigefp.rh.domain.PerformanceEvaluation;
import br.gov.sigefp.rh.repository.PerformanceEvaluationRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * Serviço para gestão de avaliações de desempenho e automação de carreira.
 * Implementa regras do Decreto nº 12-A/94.
 */
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class PerformanceEvaluationService {

    private final PerformanceEvaluationRepository evaluationRepository;
    private final CareerEventService careerEventService;

    /**
     * Finaliza uma avaliação e verifica elegibilidade para promoção.
     */
    public void finalizeEvaluation(UUID evaluationId) {
        PerformanceEvaluation evaluation = evaluationRepository.findById(evaluationId)
                .orElseThrow(() -> new BusinessException("Avaliação não encontrada", "NOT_FOUND",
                        org.springframework.http.HttpStatus.NOT_FOUND));

        if (!"DRAFT".equals(evaluation.getStatus())) {
            throw new BusinessException("Apenas avaliações em DRAFT podem ser finalizadas", "INVALID_STATUS",
                    org.springframework.http.HttpStatus.BAD_REQUEST);
        }

        evaluation.setStatus("FINAL");
        evaluation.updateMentionFromScore();
        evaluationRepository.save(evaluation);

        // Verifica requisitos para promoção (3 anos de BOM ou MUITO_BOM)
        checkPromotionEligibility(evaluation.getAgent());
    }

    /**
     * Busca todas as avaliações com paginação.
     */
    @Transactional(readOnly = true)
    public Page<PerformanceEvaluationDTO> findAll(Pageable pageable) {
        return evaluationRepository.findAll(pageable)
                .map(this::toDTO);
    }

    /**
     * Converte entidade para DTO.
     */
    private PerformanceEvaluationDTO toDTO(PerformanceEvaluation evaluation) {
        Agent agent = evaluation.getAgent();
        return PerformanceEvaluationDTO.builder()
                .id(evaluation.getId())
                .agentId(agent != null ? agent.getId() : null)
                .agentName(agent != null ? agent.getFullName() : null)
                .agentMatricula(agent != null ? agent.getMatricula() : null)
                .referenceYear(evaluation.getReferenceYear())
                .score(evaluation.getScore())
                .status(evaluation.getStatus())
                .mention(evaluation.getMention())
                .observations(evaluation.getObservations())
                .evaluationDate(evaluation.getEvaluationDate())
                .build();
    }

    /**
     * Verifica se o agente atingiu os requisitos para promoção automática.
     */
    private void checkPromotionEligibility(Agent agent) {
        // Busca as últimas 3 avaliações
        List<PerformanceEvaluation> lastEvaluations = evaluationRepository
                .findByAgentIdOrderByReferenceYearDesc(agent.getId());

        if (lastEvaluations.size() < 3) {
            return; // Requer pelo menos 3 anos
        }

        boolean eligible = lastEvaluations.stream()
                .limit(3)
                .allMatch(e -> "BOM".equals(e.getMention()) || "MUITO_BOM".equals(e.getMention()));

        if (eligible) {
            log.info("Agente {} elegível para promoção automática conforme Decreto 12-A/94", agent.getMatricula());
            // Aqui poderíamos disparar um evento ou criar um CareerEvent sugerido
            // Por enquanto, apenas registramos no log ou enviamos notificação
        }
    }
}
