package dev.lions.unionflow.server.service.registre;

import dev.lions.unionflow.server.api.dto.registre.AgrementProfessionnelDTO;
import dev.lions.unionflow.server.entity.Membre;
import dev.lions.unionflow.server.entity.Organisation;
import dev.lions.unionflow.server.entity.registre.AgrementProfessionnel;
import dev.lions.unionflow.server.mapper.registre.AgrementProfessionnelMapper;
import dev.lions.unionflow.server.repository.MembreRepository;
import dev.lions.unionflow.server.repository.OrganisationRepository;
import dev.lions.unionflow.server.repository.registre.AgrementProfessionnelRepository;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.NotFoundException;

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

@ApplicationScoped
public class AgrementProfessionnelService {

    @Inject
    AgrementProfessionnelRepository agrementProfessionnelRepository;

    @Inject
    MembreRepository membreRepository;

    @Inject
    OrganisationRepository organisationRepository;

    @Inject
    AgrementProfessionnelMapper agrementProfessionnelMapper;

    @Transactional
    public AgrementProfessionnelDTO enregistrerAgrement(AgrementProfessionnelDTO dto) {
        Membre membre = membreRepository.findByIdOptional(UUID.fromString(dto.getMembreId()))
                .orElseThrow(() -> new NotFoundException("Membre non trouvé avec l'ID: " + dto.getMembreId()));

        Organisation organisation = organisationRepository.findByIdOptional(UUID.fromString(dto.getOrganisationId()))
                .orElseThrow(() -> new NotFoundException(
                        "Organisation (Ordre/Chambre) non trouvée avec l'ID: " + dto.getOrganisationId()));

        AgrementProfessionnel agrement = agrementProfessionnelMapper.toEntity(dto);
        agrement.setMembre(membre);
        agrement.setOrganisation(organisation);

        agrementProfessionnelRepository.persist(agrement);
        return agrementProfessionnelMapper.toDto(agrement);
    }

    public AgrementProfessionnelDTO getAgrementById(UUID id) {
        AgrementProfessionnel agrement = agrementProfessionnelRepository.findByIdOptional(id)
                .orElseThrow(() -> new NotFoundException("Agrément professionnel non trouvé avec l'ID: " + id));
        return agrementProfessionnelMapper.toDto(agrement);
    }

    public List<AgrementProfessionnelDTO> getAgrementsByMembre(UUID membreId) {
        return agrementProfessionnelRepository.find("membre.id = ?1 and actif = true", membreId)
                .stream()
                .map(agrementProfessionnelMapper::toDto)
                .collect(Collectors.toList());
    }

    public List<AgrementProfessionnelDTO> getAgrementsByOrganisation(UUID organisationId) {
        return agrementProfessionnelRepository.find("organisation.id = ?1 and actif = true", organisationId)
                .stream()
                .map(agrementProfessionnelMapper::toDto)
                .collect(Collectors.toList());
    }
}
