package br.gov.sigefp.rh.service;

import br.gov.sigefp.rh.domain.*;
import br.gov.sigefp.rh.repository.CareerEventRepository;
import br.gov.sigefp.rh.repository.SalaryGridRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.UUID;

/**
 * Serviço centralizado para registro de eventos estruturados na vida laboral
 * (carreira).
 */
@Service
@RequiredArgsConstructor
@Transactional
public class CareerEventService {

    private final CareerEventRepository careerEventRepository;
    private final SalaryGridRepository salaryGridRepository;

    /**
     * Registra um evento de carreira com snapshots e cálculos financeiros.
     */
    public void recordEvent(Agent agent, CareerEventType type, String reason, String docRef,
            LocalDate effectiveDate, LocalDate publicationDate,
            UUID newCategory, UUID newGrade, UUID newStep, UUID newOrg, UUID newPos,
            UUID prevCategory, UUID prevGrade, UUID prevStep, UUID prevOrg, UUID prevPos) {

        CareerEvent event = CareerEvent.builder()
                .agent(agent)
                .eventType(type)
                .effectiveDate(effectiveDate != null ? effectiveDate : LocalDate.now())
                .publicationDate(publicationDate)
                .documentRef(docRef)
                .reason(reason)
                // Snapshots atuais
                .previousCategory(prevCategory)
                .newCategory(newCategory != null ? newCategory : agent.getSalaryCategory())
                .previousGrade(prevGrade)
                .newGrade(newGrade != null ? newGrade : agent.getSalaryGrade())
                .previousStep(prevStep)
                .newStep(newStep != null ? newStep : agent.getSalaryStep())
                // Snapshots organizacionais
                .previousOrgUnit(prevOrg)
                .newOrgUnit(newOrg != null ? newOrg : agent.getOrgUnit())
                .previousPosition(prevPos)
                .newPosition(newPos != null ? newPos : agent.getPosition())
                .createdByUser("system")
                .build();

        // Cálculo financeiro retroativo ou atual
        UUID finalStepId = event.getNewStep();
        if (finalStepId != null) {
            SalaryGrid grid = salaryGridRepository.findByStepIdAndDate(finalStepId, event.getEffectiveDate());
            if (grid != null) {
                event.calculateFinancialSplit(grid.getBaseAmount());
            }
        }

        careerEventRepository.save(event);
    }

    /**
     * Versão simplificada para eventos que não alteram carreira (ex: apenas mudança
     * de referência legal ou situação funcional).
     */
    public void recordSimpleEvent(Agent agent, CareerEventType type, String reason, String docRef,
            LocalDate effectiveDate) {
        recordEvent(agent, type, reason, docRef, effectiveDate, null,
                null, null, null, null, null,
                agent.getSalaryCategory(), agent.getSalaryGrade(), agent.getSalaryStep(),
                agent.getOrgUnit(), agent.getPosition());
    }
}
