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

import io.gmss.fiscad.entities.rfu.metier.ImpositionsTfu;
import io.gmss.fiscad.enums.StatusAvis;
import io.gmss.fiscad.exceptions.BadRequestException;
import io.gmss.fiscad.exceptions.NotFoundException;
import io.gmss.fiscad.interfaces.rfu.metier.ImpositionsTfuService;
import io.gmss.fiscad.repositories.rfu.metier.ImpositionsTfuRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

@Service
public class ImpositionsTfuServiceImpl implements ImpositionsTfuService {

    private final ImpositionsTfuRepository impositionsTfuRepository;

    public ImpositionsTfuServiceImpl(ImpositionsTfuRepository impositionsTfuRepository) {
        this.impositionsTfuRepository = impositionsTfuRepository;
    }

    @Override
    public ImpositionsTfu createImpositionsTfu(ImpositionsTfu impositionsTfu) throws BadRequestException {
        if (impositionsTfu.getId() != null) {
            throw new BadRequestException("Impossible de créer une nouvelle unité de logement ayant un id non null.");
        }
         List<ImpositionsTfu> impositionsTfus=impositionsTfuRepository.getImpositionsTfuByCommuneAndExercice(impositionsTfu.getCommune().getCode(),impositionsTfu.getExercice().getAnnee());
        if (!impositionsTfus.isEmpty()) {
            throw new BadRequestException("Une Imposition non annulée existe déjà");
        }
        impositionsTfu.setStatusAvis(StatusAvis.CREE);
        impositionsTfu.setDateGeneration(LocalDate.now());
        return impositionsTfuRepository.save(impositionsTfu);
    }

    @Override
    public ImpositionsTfu annulerImpositionsTfu(ImpositionsTfu impositionsTfu) throws BadRequestException {
        if (impositionsTfu.getId() == null) {
            throw new BadRequestException("Impossible d'annuler une imposition ayant un id null.");
        }
        if (!impositionsTfuRepository.existsById(impositionsTfu.getId())) {
            throw new NotFoundException("Impossible de trouver la nouvelle unité de logement spécifiée dans notre base de données.");
        }
        impositionsTfu.setStatusAvis(StatusAvis.ANNULE);
        return impositionsTfuRepository.save(impositionsTfu);
    }

    @Override
    public ImpositionsTfu validerImpositionsTfu(ImpositionsTfu impositionsTfu) throws BadRequestException {
        if (impositionsTfu.getId() == null) {
            throw new BadRequestException("Impossible de valider une imposition ayant un id null.");
        }
        if (!impositionsTfuRepository.existsById(impositionsTfu.getId())) {
            throw new NotFoundException("Impossible de trouver la nouvelle unité de logement spécifiée dans notre base de données.");
        }
        impositionsTfu.setStatusAvis(StatusAvis.VALIDE);
        return impositionsTfuRepository.save(impositionsTfu);
    }

    @Override
    public ImpositionsTfu updateImpositionsTfu(Long id, ImpositionsTfu impositionsTfu) throws NotFoundException {
        if (impositionsTfu.getId() == null) {
            throw new BadRequestException("Impossible de mettre à jour une nouvelle unité de logement ayant un id null.");
        }
        if (!impositionsTfuRepository.existsById(impositionsTfu.getId())) {
            throw new NotFoundException("Impossible de trouver la nouvelle unité de logement spécifiée dans notre base de données.");
        }
        return impositionsTfuRepository.save(impositionsTfu);
    }

    @Override
    public void deleteImpositionsTfu(Long id) throws NotFoundException {
        Optional<ImpositionsTfu> impositionsTfuOptional = impositionsTfuRepository.findById(id);
        if (impositionsTfuOptional.isPresent()) {
            impositionsTfuRepository.deleteById(impositionsTfuOptional.get().getId());
        } else {
            throw new NotFoundException("Impossible de trouver la nouvelle unité de logement spécifiée dans notre base de données.");
        }
    }

    @Override
    public Page<ImpositionsTfu> getImpositionsTfuList(Pageable pageable) {
        return impositionsTfuRepository.findAll(pageable);
    }

    @Override
    public List<ImpositionsTfu> getImpositionsTfuList() {
        return impositionsTfuRepository.findAll();
    }


    @Override
    public Optional<ImpositionsTfu> getImpositionsTfuById(Long id) {
        if (impositionsTfuRepository.existsById(id)) {
            return impositionsTfuRepository.findById(id);
        } else {
            throw new NotFoundException("Impossible de trouver la nouvelle unité de logement spécifiée dans la base de données.");
        }
    }
}
