package br.gov.sigefp.org.service;

import br.gov.sigefp.org.api.dto.MinistryDTO;
import br.gov.sigefp.org.domain.Ministry;
import br.gov.sigefp.org.repository.MinistryRepository;
import lombok.RequiredArgsConstructor;
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.UUID;

/**
 * Serviço de aplicação para gestão de ministérios.
 */
@Service
@RequiredArgsConstructor
@Transactional
public class MinistryService {

    private final MinistryRepository ministryRepository;

    public MinistryDTO create(MinistryDTO dto) {
        if (ministryRepository.existsByCode(dto.getCode())) {
            throw new IllegalArgumentException("Código de ministério já existe: " + dto.getCode());
        }

        Ministry ministry = Ministry.builder()
                .code(dto.getCode())
                .name(dto.getName())
                .acronym(dto.getAcronym())
                .description(dto.getDescription())
                .logo(dto.getLogo())
                .isActive(dto.getIsActive() != null ? dto.getIsActive() : true)
                .build();

        Ministry saved = ministryRepository.save(ministry);
        return toDTO(saved);
    }

    public MinistryDTO update(UUID id, MinistryDTO dto) {
        Ministry ministry = ministryRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + id));

        if (dto.getCode() != null && !dto.getCode().equals(ministry.getCode())) {
            if (ministryRepository.existsByCode(dto.getCode())) {
                throw new IllegalArgumentException("Código de ministério já existe: " + dto.getCode());
            }
            ministry.setCode(dto.getCode());
        }

        if (dto.getName() != null) {
            ministry.setName(dto.getName());
        }
        if (dto.getAcronym() != null) {
            ministry.setAcronym(dto.getAcronym());
        }
        if (dto.getDescription() != null) {
            ministry.setDescription(dto.getDescription());
        }
        if (dto.getLogo() != null) {
            ministry.setLogo(dto.getLogo());
        }
        if (dto.getIsActive() != null) {
            ministry.setIsActive(dto.getIsActive());
        }

        Ministry saved = ministryRepository.save(ministry);
        return toDTO(saved);
    }

    public MinistryDTO activate(UUID id) {
        Ministry ministry = ministryRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + id));
        ministry.setIsActive(true);
        Ministry saved = ministryRepository.save(ministry);
        return toDTO(saved);
    }

    public MinistryDTO deactivate(UUID id) {
        Ministry ministry = ministryRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + id));
        ministry.setIsActive(false);
        Ministry saved = ministryRepository.save(ministry);
        return toDTO(saved);
    }

    @Transactional(readOnly = true)
    public MinistryDTO findById(UUID id) {
        Ministry ministry = ministryRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + id));
        return toDTO(ministry);
    }

    @Transactional(readOnly = true)
    public Page<MinistryDTO> findAll(Pageable pageable) {
        return ministryRepository.findAllByIsActiveTrue(pageable).map(this::toDTO);
    }

    private MinistryDTO toDTO(Ministry ministry) {
        return MinistryDTO.builder()
                .id(ministry.getId())
                .code(ministry.getCode())
                .name(ministry.getName())
                .acronym(ministry.getAcronym())
                .description(ministry.getDescription())
                .logo(ministry.getLogo())
                .isActive(ministry.getIsActive())
                .build();
    }

    public void delete(UUID id) {
        Ministry ministry = ministryRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + id));
        
        ministry.setIsActive(false);
        ministryRepository.save(ministry);
    }
}

