package io.gmss.fiscad.implementations.infocad.metier;


import io.gmss.fiscad.entities.infocad.parametre.Personne;
import io.gmss.fiscad.exceptions.BadRequestException;
import io.gmss.fiscad.exceptions.NotFoundException;

import io.gmss.fiscad.interfaces.infocad.metier.PersonneService;
import io.gmss.fiscad.paylaods.dto.*;
import io.gmss.fiscad.repositories.infocad.metier.MembreGroupeRepository;
import io.gmss.fiscad.repositories.infocad.metier.PieceRepository;
import io.gmss.fiscad.repositories.infocad.metier.UploadRepository;
import io.gmss.fiscad.repositories.infocad.parametre.PersonneRepository;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class PersonneServiceImpl implements PersonneService {

    private final PersonneRepository personneRepository;
    private final UploadRepository uploadRepository;
    private final PieceRepository pieceRepository;
    private final MembreGroupeRepository membreGroupeRepository;

    @Override
    public Personne createPersonne(Personne personne) throws BadRequestException {
        return null;
    }

    @Override
    public Personne updatePersonne(Long id, Personne personne) throws NotFoundException {
        return null;
    }

    @Override
    public void deletePersonne(Long id) throws NotFoundException {

    }

    @Override
    public Page<Personne> getPersonneList(Pageable pageable) {
        return null;
    }

    @Override
    public List<Personne> getPersonneList() {
        return null;
    }

    @Override
    public Optional<Personne> getPersonneById(Long id) {
        return Optional.empty();
    }

    @Override
    public PersonneCompletDTO getPersonneComplete(Long id) {
        // 1. Charger la personne
        Personne personne = personneRepository.findById(id)
                            .orElseThrow(() -> new EntityNotFoundException("Personne non trouvée."));

        // 2. Uploads liés directement
        List<UploadDTO> uploadsDirects = uploadRepository
                .findByPersonne_IdAndPieceIsNullAndMembreGroupeIsNull(id)
                .stream()
                .map(u -> new UploadDTO(u.getId(), u.getExternalKey(), u.getObservation(), u.isSynchronise(), u.getFileName(), u.getOriginalFileName(), u.getURIFile(), u.getCheckSum(), u.getSize(), u.getMimeType()))
                .toList();
        System.out.println(uploadsDirects.size());
        // 3. Pièces et leurs Uploads
        List<PieceDTO> pieces = pieceRepository.findByPersonne_IdAndActeurConcerneIsNull(id)
                .stream().map(piece -> {
                    List<UploadDTO> uploads = piece.getUploads().stream()
                            .map(u -> new UploadDTO(u.getId(), u.getExternalKey(), u.getObservation(), u.isSynchronise(), u.getFileName(), u.getOriginalFileName(), u.getURIFile(), u.getCheckSum(), u.getSize(), u.getMimeType()))
                            .toList();
                    return new PieceDTO(
                            piece.getId(),
                            piece.getTypePiece() != null ? piece.getTypePiece().getLibelle() : "",
                            piece.getUrl(),
                            uploads
                    );
                }).toList();

        // 4. MembreGroupe
        List<MembreGroupeDTO> membres = membreGroupeRepository
                .findByPersonneRepresantee_Id(id)
                .stream().map(mg -> {
                    List<UploadDTO> uploads = mg.getUploads().stream()
                            .map(u -> new UploadDTO(u.getId(), u.getExternalKey(), u.getObservation(), u.isSynchronise(), u.getFileName(), u.getOriginalFileName(), u.getURIFile(), u.getCheckSum(), u.getSize(), u.getMimeType()))
                            .toList();

                    Personne pRep = mg.getPersonneRepresantante();

                    if(mg.getTypeRepresentation() == null){
                        return new MembreGroupeDTO(
                                mg.getId(),
                                new PersonneSimpleDTO(pRep.getId(), pRep.getNomOuSigle(), pRep.getPrenomOuRaisonSociale()),
                                null,
                                new PositionRepresentationDTO(mg.getPositionRepresentation().getId(), mg.getPositionRepresentation().getLibelle()),
                                uploads
                        );
                    }else{
                        return new MembreGroupeDTO(
                                mg.getId(),
                                new PersonneSimpleDTO(pRep.getId(), pRep.getNomOuSigle(), pRep.getPrenomOuRaisonSociale()),
                                new TypeRepresentationDTO(mg.getTypeRepresentation().getId(), mg.getTypeRepresentation().getLibelle()),
                                new PositionRepresentationDTO(mg.getPositionRepresentation().getId(), mg.getPositionRepresentation().getLibelle()),
                                uploads
                        );
                    }


                }).toList();

        // 5. Construction finale
        return new PersonneCompletDTO(
                personne.getId(),
                personne.getIfu(),
                personne.getNomOuSigle(),
                personne.getPrenomOuRaisonSociale(),
                personne.getNumRavip(),
                personne.getNpi(),
                personne.getDateNaissanceOuConsti(),
                personne.getLieuNaissance(),
                personne.getTel1(),
                personne.getTel2(),
                personne.getAdresse(),
                personne.getCategorie(),
                personne.getSituationMatrimoniale(),
                personne.getNationalite(),
                personne.getTypePersonne(),
                personne.getProfession(),
                personne.getCommune(),
                personne.getTerminal(),
                personne.getHaveRepresentant(),
                personne.getRavipQuestion(),
                personne.getAge(),
                personne.getNomJeuneFille(),
                personne.getNomMere(),
                personne.getPrenomMere(),
                personne.getIndicatifTel1(),
                personne.getIndicatifTel2(),
                personne.getSexe(),
                personne.getMustHaveRepresentant(),
                personne.getFilePath(),
                personne.getObservation(),
                personne.isSynchronise(),
                uploadsDirects,
                pieces,
                membres
        );
    }
}

