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

import dev.lions.unionflow.server.api.dto.gouvernance.EchelonOrganigrammeDTO;
import dev.lions.unionflow.server.entity.Membre;
import dev.lions.unionflow.server.entity.Organisation;
import dev.lions.unionflow.server.entity.gouvernance.EchelonOrganigramme;
import dev.lions.unionflow.server.mapper.gouvernance.EchelonOrganigrammeMapper;
import dev.lions.unionflow.server.repository.MembreRepository;
import dev.lions.unionflow.server.repository.OrganisationRepository;
import dev.lions.unionflow.server.repository.gouvernance.EchelonOrganigrammeRepository;

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 EchelonOrganigrammeService {

    @Inject
    EchelonOrganigrammeRepository echelonOrganigrammeRepository;

    @Inject
    MembreRepository membreRepository;

    @Inject
    OrganisationRepository organisationRepository;

    @Inject
    EchelonOrganigrammeMapper echelonOrganigrammeMapper;

    @Transactional
    public EchelonOrganigrammeDTO creerEchelon(EchelonOrganigrammeDTO dto) {
        Organisation organisation = organisationRepository.findByIdOptional(UUID.fromString(dto.getOrganisationId()))
                .orElseThrow(
                        () -> new NotFoundException("Organisation non trouvée avec l'ID: " + dto.getOrganisationId()));

        EchelonOrganigramme echelon = echelonOrganigrammeMapper.toEntity(dto);
        echelon.setOrganisation(organisation);

        if (dto.getEchelonParentId() != null) {
            Organisation parentOrg = organisationRepository.findByIdOptional(UUID.fromString(dto.getEchelonParentId()))
                    .orElseThrow(() -> new NotFoundException(
                            "Organisation parente non trouvée avec l'ID: " + dto.getEchelonParentId()));
            echelon.setEchelonParent(parentOrg);
        }

        echelonOrganigrammeRepository.persist(echelon);
        return echelonOrganigrammeMapper.toDto(echelon);
    }

    public EchelonOrganigrammeDTO getEchelonById(UUID id) {
        EchelonOrganigramme echelon = echelonOrganigrammeRepository.findByIdOptional(id)
                .orElseThrow(() -> new NotFoundException("Échelon d'organigramme non trouvé avec l'ID: " + id));
        return echelonOrganigrammeMapper.toDto(echelon);
    }

    public List<EchelonOrganigrammeDTO> getOrganigrammeByOrganisation(UUID organisationId) {
        return echelonOrganigrammeRepository.find("organisation.id = ?1 and actif = true", organisationId)
                .stream()
                .map(echelonOrganigrammeMapper::toDto)
                .collect(Collectors.toList());
    }
}
