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

import dev.lions.unionflow.server.api.dto.culte.DonReligieuxDTO;
import dev.lions.unionflow.server.api.enums.wave.StatutTransactionWave;
import dev.lions.unionflow.server.entity.Membre;
import dev.lions.unionflow.server.entity.Organisation;
import dev.lions.unionflow.server.entity.culte.DonReligieux;
import dev.lions.unionflow.server.mapper.culte.DonReligieuxMapper;
import dev.lions.unionflow.server.repository.MembreRepository;
import dev.lions.unionflow.server.repository.OrganisationRepository;
import dev.lions.unionflow.server.repository.culte.DonReligieuxRepository;

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

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

@ApplicationScoped
public class DonReligieuxService {

    @Inject
    DonReligieuxRepository donReligieuxRepository;

    @Inject
    MembreRepository membreRepository;

    @Inject
    OrganisationRepository organisationRepository;

    @Inject
    DonReligieuxMapper donReligieuxMapper;

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

        DonReligieux don = donReligieuxMapper.toEntity(dto);
        don.setInstitution(organisation);

        if (dto.getFideleId() != null) {
            Membre membre = membreRepository.findByIdOptional(UUID.fromString(dto.getFideleId()))
                    .orElseThrow(() -> new NotFoundException("Membre non trouvé avec l'ID: " + dto.getFideleId()));
            don.setFidele(membre);
        }

        don.setDateEncaissement(LocalDateTime.now());

        donReligieuxRepository.persist(don);
        return donReligieuxMapper.toDto(don);
    }

    public DonReligieuxDTO getDonById(UUID id) {
        DonReligieux don = donReligieuxRepository.findByIdOptional(id)
                .orElseThrow(() -> new NotFoundException("Don religieux non trouvé avec l'ID: " + id));
        return donReligieuxMapper.toDto(don);
    }

    public List<DonReligieuxDTO> getDonsByOrganisation(UUID organisationId) {
        return donReligieuxRepository.find("institution.id = ?1 and actif = true", organisationId)
                .stream()
                .map(donReligieuxMapper::toDto)
                .collect(Collectors.toList());
    }
}
