package it.micegroup.gestioneferie.configurazionepf.service;

import java.util.Map;
import java.util.List;
import java.util.Locale;
import java.util.HashMap;
import java.util.Optional;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ResourceBundle;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;

import org.springframework.context.i18n.LocaleContextHolder;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

import it.micegroup.voila2runtime.filter.LongFilter;

import it.micegroup.gestioneferie.configurazionepf.entity.DpercAutPianFerieH;

import it.micegroup.gestioneferie.configurazionepf.entity.DpercAutPianFeriePk;
import it.micegroup.gestioneferie.configurazionepf.entity.DconfigPaPianiFerie;

import it.micegroup.gestioneferie.configurazionepf.entity.DpercAutPianFerieH_;
import it.micegroup.gestioneferie.configurazionepf.criteria.DpercAutPianFerieHCriteria;
import it.micegroup.gestioneferie.configurazionepf.repository.DpercAutPianFerieHRepository;
import it.micegroup.voila2runtime.specification.FilterService;

import it.micegroup.gestioneferie.configurazionepf.entity.DpercAutPianFerieH_;
import it.micegroup.gestioneferie.configurazionepf.entity.DpercAutPianFeriePk_;

import it.micegroup.gestioneferie.configurazionepf.entity.DconfigPaPianiFerie_;

import org.springframework.data.domain.PageImpl;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import it.micegroup.gestioneferie.libs.service.BaseServiceImpl;

import it.micegroup.voila2runtime.exception.BusinessException;
import net.sf.jasperreports.engine.JRException;

@RequiredArgsConstructor
@Service
@Transactional
public class DpercAutPianFerieHServiceImpl extends BaseServiceImpl implements DpercAutPianFerieHService {

	private final DpercAutPianFerieHRepository dpercAutPianFerieHRepository;
	private final FilterService<DpercAutPianFerieH> filterService;

	// CHILD SERVICES

	@SuppressWarnings("unused")
	private static final Logger LOGGER = LogManager.getLogger(DpercAutPianFerieHServiceImpl.class);

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * findAll(org. springframework.data.domain.Pageable)
	 */
	@Override
	@Transactional(readOnly = true)
	public Page<DpercAutPianFerieH> findAll(Pageable pageable) {
		return dpercAutPianFerieHRepository.findAll(pageable);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * findAll()
	 */
	@Override
	@Transactional(readOnly = true)
	public List<DpercAutPianFerieH> findAll() {
		return dpercAutPianFerieHRepository.findAll();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * findByCriteria(java. lang.Object, org.springframework.data.domain.Pageable)
	 */
	@Override
	@Transactional(readOnly = true)
	public Page<DpercAutPianFerieH> findByCriteria(DpercAutPianFerieHCriteria criteria, Pageable pageable) {
		final Specification<DpercAutPianFerieH> specification = createSpecification(criteria);
		return dpercAutPianFerieHRepository.findAll(specification, pageable);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * findByCriteria(java. lang.Object)
	 */
	@Override
	@Transactional(readOnly = true)
	public List<DpercAutPianFerieH> findByCriteria(DpercAutPianFerieHCriteria criteria) {
		final Specification<DpercAutPianFerieH> specification = createSpecification(criteria);
		return dpercAutPianFerieHRepository.findAll(specification);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * findById(java.lang. Object)
	 */
	@Override
	@Transactional(readOnly = true)
	public Optional<DpercAutPianFerieH> findById(Long id) {
		return dpercAutPianFerieHRepository.findBySequIdPercAutPianFerieH(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * exists(java.lang. Object)
	 */
	@Override
	public boolean exists(Long id) {
		return dpercAutPianFerieHRepository.existsById(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * insert(java. lang.Object)
	 */
	@Override
	public DpercAutPianFerieH insert(@Valid DpercAutPianFerieH entity) {
		return dpercAutPianFerieHRepository.save(entity);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * update(java. lang.Object)
	 */
	@Override
	public DpercAutPianFerieH update(@Valid DpercAutPianFerieH entity) {
		return dpercAutPianFerieHRepository.save(entity);
	}

	@Override
	public void delete(DpercAutPianFerieH entity) {
		dpercAutPianFerieHRepository.delete(entity);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * deleteById(java.lang. Object)
	 */
	@Override
	public void deleteById(Long id) {
		dpercAutPianFerieHRepository.deleteById(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * deleteByIdIn(java.lang. Object)
	 */
	@Override
	public void deleteByIdIn(Collection<Long> ids) {
		dpercAutPianFerieHRepository.deleteByIdIn(ids);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.GenericEntityService#
	 * findByObjectKey(java.lang.String)
	 */
	@Override
	@Transactional(readOnly = true)
	public Optional<DpercAutPianFerieH> findByObjectKey(String id) {
		DpercAutPianFerieH dpercAutPianFerieH = new DpercAutPianFerieH(id);

		return findById(dpercAutPianFerieH.getSequIdPercAutPianFerieH());
	}

	@Override
	public Page<DpercAutPianFerieH> findByTheDpercAutPianFeriePk(DpercAutPianFeriePk parentEntity, Pageable pageable) {
		return dpercAutPianFerieHRepository.findByTheDpercAutPianFeriePk(parentEntity, pageable);
	}

	@Override
	public Page<DpercAutPianFerieH> findByTheDconfigPaPianiFerie(DconfigPaPianiFerie parentEntity, Pageable pageable) {
		return dpercAutPianFerieHRepository.findByTheDconfigPaPianiFerie(parentEntity, pageable);
	}

	/**
	 * Convert DpercAutPianFerieHCriteria to a {@link Specification}
	 * 
	 * @param criteria
	 * @return
	 */
	private Specification<DpercAutPianFerieH> createSpecification(DpercAutPianFerieHCriteria criteria) {
		Specification<DpercAutPianFerieH> specification = Specification.where(null);

		if (criteria != null) {
			// Attribute filters
			if (criteria.getSequIdPercAutPianFerieH() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getSequIdPercAutPianFerieH(), DpercAutPianFerieH_.sequIdPercAutPianFerieH));
			}
			if (criteria.getFkConfigPaPianoFerie() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getFkConfigPaPianoFerie(), DpercAutPianFerieH_.fkConfigPaPianoFerie));
			}
			if (criteria.getFkPercorso() != null) {
				specification = specification.and(filterService.generateRangeSpecification(criteria.getFkPercorso(),
						DpercAutPianFerieH_.fkPercorso));
			}
			if (criteria.getFkPercAutPianFeriePk() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getFkPercAutPianFeriePk(), DpercAutPianFerieH_.fkPercAutPianFeriePk));
			}
			if (criteria.getDataUltimaModifica() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getDataUltimaModifica(), DpercAutPianFerieH_.dataUltimaModifica));
			}
			if (criteria.getDataFineValidita() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getDataFineValidita(), DpercAutPianFerieH_.dataFineValidita));
			}
			if (criteria.getDataInizioValidita() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getDataInizioValidita(), DpercAutPianFerieH_.dataInizioValidita));
			}
			if (criteria.getUtenteUltimaModifica() != null) {
				specification = specification.and(filterService.generateStringSpecification(
						criteria.getUtenteUltimaModifica(), DpercAutPianFerieH_.utenteUltimaModifica));
			}
			if (criteria.getFlagEliminato() != null) {
				specification = specification.and(filterService.generateStringSpecification(criteria.getFlagEliminato(),
						DpercAutPianFerieH_.flagEliminato));
			}

			if (criteria.getTheDpercAutPianFeriePkObjectKey() != null) {
				DpercAutPianFeriePk dpercAutPianFeriePk = new DpercAutPianFeriePk(
						criteria.getTheDpercAutPianFeriePkObjectKey());

				specification = specification.and(
						filterService.generateEqualsSpecification(dpercAutPianFeriePk.getSequIdPercAutPianFeriePk(),
								r -> r.get(DpercAutPianFerieH_.theDpercAutPianFeriePk)
										.get(DpercAutPianFeriePk_.sequIdPercAutPianFeriePk)));
			}
			if (criteria.getTheDconfigPaPianiFerieObjectKey() != null) {
				DconfigPaPianiFerie dconfigPaPianiFerie = new DconfigPaPianiFerie(
						criteria.getTheDconfigPaPianiFerieObjectKey());

				specification = specification.and(
						filterService.generateEqualsSpecification(dconfigPaPianiFerie.getSequIdConfigPaPianoFerie(),
								r -> r.get(DpercAutPianFerieH_.theDconfigPaPianiFerie)
										.get(DconfigPaPianiFerie_.sequIdConfigPaPianoFerie)));
			}

		}
		return specification;
	}

	/*
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.DpercAutPianFerieHService
	 * #findDpercAutPianFeriePkBytheDconfigPaPianiFerie(it.micegroup.gestioneferie.
	 * configurazionepf.entity.DconfigPaPianiFerie,
	 * org.springframework.data.domain.Pageable)
	 */
	@Override
	@Transactional(readOnly = true)
	public Page<DpercAutPianFeriePk> findDpercAutPianFeriePkByTheDconfigPaPianiFerie(
			DconfigPaPianiFerie dconfigPaPianiFerie, Pageable pageable) {
		Page<DpercAutPianFerieH> dpercAutPianFerieHPage = dpercAutPianFerieHRepository
				.findByTheDconfigPaPianiFerie(dconfigPaPianiFerie, pageable);
		List<DpercAutPianFeriePk> content = dpercAutPianFerieHPage.getContent().stream()
				.map(DpercAutPianFerieH::getTheDpercAutPianFeriePk).collect(Collectors.toList());
		Page<DpercAutPianFeriePk> result = new PageImpl<DpercAutPianFeriePk>(content, pageable,
				dpercAutPianFerieHPage.getTotalElements());
		return result;
	}

	/*
	 * 
	 * @see
	 * it.micegroup.gestioneferie.configurazionepf.service.DpercAutPianFerieHService
	 * #findDconfigPaPianiFerieBytheDpercAutPianFeriePk(it.micegroup.gestioneferie.
	 * configurazionepf.entity.DpercAutPianFeriePk,
	 * org.springframework.data.domain.Pageable)
	 */
	@Override
	@Transactional(readOnly = true)
	public Page<DconfigPaPianiFerie> findDconfigPaPianiFerieByTheDpercAutPianFeriePk(
			DpercAutPianFeriePk dpercAutPianFeriePk, Pageable pageable) {
		Page<DpercAutPianFerieH> dpercAutPianFerieHPage = dpercAutPianFerieHRepository
				.findByTheDpercAutPianFeriePk(dpercAutPianFeriePk, pageable);
		List<DconfigPaPianiFerie> content = dpercAutPianFerieHPage.getContent().stream()
				.map(DpercAutPianFerieH::getTheDconfigPaPianiFerie).collect(Collectors.toList());
		Page<DconfigPaPianiFerie> result = new PageImpl<DconfigPaPianiFerie>(content, pageable,
				dpercAutPianFerieHPage.getTotalElements());
		return result;
	}

	@Override
	@Transactional()
	public DpercAutPianFerieH bulkUpdate(DpercAutPianFerieH dpercAutPianFerieH) {

		DpercAutPianFerieH update = this.update(dpercAutPianFerieH);

		return update;
	}
}
