package it.micegroup.gestioneferie.pianificazioneferie.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.gestioneferie.pianificazioneferie.entity.DrichPianifFerieAmmto;

import it.micegroup.gestioneferie.pianificazioneferie.entity.DrichPianifFerieAmmtoKey;

import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiRichiestaPfAmmto;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DpianificFerieAmmto;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiRichiestaPfAmmtoKey;

import it.micegroup.gestioneferie.pianificazioneferie.entity.DpianificFerieAmmtoKey;

import it.micegroup.gestioneferie.pianificazioneferie.entity.DrichPianifFerieAmmto_;
import it.micegroup.gestioneferie.pianificazioneferie.criteria.DrichPianifFerieAmmtoCriteria;
import it.micegroup.gestioneferie.pianificazioneferie.repository.DrichPianifFerieAmmtoRepository;
import it.micegroup.voila2runtime.specification.FilterService;

import it.micegroup.gestioneferie.pianificazioneferie.entity.DrichPianifFerieAmmto_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DrichPianifFerieAmmtoKey_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiRichiestaPfAmmto_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiRichiestaPfAmmtoKey_;

import it.micegroup.gestioneferie.pianificazioneferie.entity.DpianificFerieAmmto_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DpianificFerieAmmtoKey_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiPianificFerie_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiPianificFerieKey_;

import it.micegroup.gestioneferie.pianificazioneferie.entity.DesitiRichAdesionePf_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DesitiRichAdesionePfKey_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiAdesionePf_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiAdesionePfKey_;

import it.micegroup.gestioneferie.pianificazioneferie.entity.DrichAdesionePf_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DrichAdesionePfKey_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiRichAdesionePf_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiRichAdesionePfKey_;

import it.micegroup.gestioneferie.pianificazioneferie.entity.DpianiFerie_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiPianoFerie_;
import it.micegroup.gestioneferie.pianificazioneferie.entity.DstatiPianoFerieKey_;

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

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

@RequiredArgsConstructor
@Service
@Transactional
public class DrichPianifFerieAmmtoServiceImpl extends BaseServiceImpl implements DrichPianifFerieAmmtoService {

	private final DrichPianifFerieAmmtoRepository drichPianifFerieAmmtoRepository;
	private final FilterService<DrichPianifFerieAmmto> filterService;

	// CHILD SERVICES

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

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

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

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

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

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.micegroup.gestioneferie.pianificazioneferie.service.GenericEntityService#
	 * findById(java.lang. Object)
	 */
	@Override
	@Transactional(readOnly = true)
	public Optional<DrichPianifFerieAmmto> findById(DrichPianifFerieAmmtoKey id) {
		return drichPianifFerieAmmtoRepository.findByDrichPianifFerieAmmtoKey(id);
	}

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

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

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

	@Override
	public void delete(DrichPianifFerieAmmto entity) {
		drichPianifFerieAmmtoRepository.delete(entity);
	}

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

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

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

		return findById(drichPianifFerieAmmto.getDrichPianifFerieAmmtoKey());
	}

	@Override
	public Page<DrichPianifFerieAmmto> findByTheDstatiRichiestaPfAmmto(DstatiRichiestaPfAmmto parentEntity,
			Pageable pageable) {
		return drichPianifFerieAmmtoRepository.findByTheDstatiRichiestaPfAmmto(parentEntity, pageable);
	}

	@Override
	public Page<DrichPianifFerieAmmto> findByTheDpianificFerieAmmto(DpianificFerieAmmto parentEntity,
			Pageable pageable) {
		return drichPianifFerieAmmtoRepository.findByTheDpianificFerieAmmto(parentEntity, pageable);
	}

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

		if (criteria != null) {
			// Attribute filters
			if (criteria.getSequIdRichPianFerieAmmto() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getSequIdRichPianFerieAmmto(), DrichPianifFerieAmmto_.sequIdRichPianFerieAmmto));
			}
			if (criteria.getCodiRichiestaPianoFerie() != null) {
				specification = specification.and(filterService.generateStringSpecification(
						criteria.getCodiRichiestaPianoFerie(), DrichPianifFerieAmmto_.codiRichiestaPianoFerie));
			}
			if (criteria.getDescRichiestaPianoFerie() != null) {
				specification = specification.and(filterService.generateStringSpecification(
						criteria.getDescRichiestaPianoFerie(), DrichPianifFerieAmmto_.descRichiestaPianoFerie));
			}
			if (criteria.getFkPianificFerieAmmto() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getFkPianificFerieAmmto(), DrichPianifFerieAmmto_.fkPianificFerieAmmto));
			}
			if (criteria.getFkStatoRichiestaPfAmmto() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getFkStatoRichiestaPfAmmto(), DrichPianifFerieAmmto_.fkStatoRichiestaPfAmmto));
			}
			if (criteria.getFlagEliminato() != null) {
				specification = specification.and(filterService.generateStringSpecification(criteria.getFlagEliminato(),
						DrichPianifFerieAmmto_.flagEliminato));
			}
			if (criteria.getUtenteUltimaModifica() != null) {
				specification = specification.and(filterService.generateStringSpecification(
						criteria.getUtenteUltimaModifica(), DrichPianifFerieAmmto_.utenteUltimaModifica));
			}
			if (criteria.getDataUltimaModifica() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getDataUltimaModifica(), DrichPianifFerieAmmto_.dataUltimaModifica));
			}
			if (criteria.getDataInizioRecord() != null) {
				specification = specification.and(filterService.generateRangeSpecification(
						criteria.getDataInizioRecord(), DrichPianifFerieAmmto_.dataInizioRecord));
			}
			if (criteria.getDataFineRecord() != null) {
				specification = specification.and(filterService.generateRangeSpecification(criteria.getDataFineRecord(),
						DrichPianifFerieAmmto_.dataFineRecord));
			}

			// CompositeKey Filters

			if (criteria.getTheDstatiRichiestaPfAmmtoObjectKey() != null) {
				DstatiRichiestaPfAmmto dstatiRichiestaPfAmmto = new DstatiRichiestaPfAmmto(
						criteria.getTheDstatiRichiestaPfAmmtoObjectKey());

			}
			if (criteria.getTheDpianificFerieAmmtoObjectKey() != null) {
				DpianificFerieAmmto dpianificFerieAmmto = new DpianificFerieAmmto(
						criteria.getTheDpianificFerieAmmtoObjectKey());

			}

		}
		return specification;
	}

	/*
	 * 
	 * @see it.micegroup.gestioneferie.pianificazioneferie.service.
	 * DrichPianifFerieAmmtoService#
	 * findDstatiRichiestaPfAmmtoBytheDpianificFerieAmmto(it.micegroup.gestioneferie
	 * .pianificazioneferie.entity.DpianificFerieAmmto,
	 * org.springframework.data.domain.Pageable)
	 */
	@Override
	@Transactional(readOnly = true)
	public Page<DstatiRichiestaPfAmmto> findDstatiRichiestaPfAmmtoByTheDpianificFerieAmmto(
			DpianificFerieAmmto dpianificFerieAmmto, Pageable pageable) {
		Page<DrichPianifFerieAmmto> drichPianifFerieAmmtoPage = drichPianifFerieAmmtoRepository
				.findByTheDpianificFerieAmmto(dpianificFerieAmmto, pageable);
		List<DstatiRichiestaPfAmmto> content = drichPianifFerieAmmtoPage.getContent().stream()
				.map(DrichPianifFerieAmmto::getTheDstatiRichiestaPfAmmto).collect(Collectors.toList());
		Page<DstatiRichiestaPfAmmto> result = new PageImpl<DstatiRichiestaPfAmmto>(content, pageable,
				drichPianifFerieAmmtoPage.getTotalElements());
		return result;
	}

	/*
	 * 
	 * @see it.micegroup.gestioneferie.pianificazioneferie.service.
	 * DrichPianifFerieAmmtoService#
	 * findDpianificFerieAmmtoBytheDstatiRichiestaPfAmmto(it.micegroup.gestioneferie
	 * .pianificazioneferie.entity.DstatiRichiestaPfAmmto,
	 * org.springframework.data.domain.Pageable)
	 */
	@Override
	@Transactional(readOnly = true)
	public Page<DpianificFerieAmmto> findDpianificFerieAmmtoByTheDstatiRichiestaPfAmmto(
			DstatiRichiestaPfAmmto dstatiRichiestaPfAmmto, Pageable pageable) {
		Page<DrichPianifFerieAmmto> drichPianifFerieAmmtoPage = drichPianifFerieAmmtoRepository
				.findByTheDstatiRichiestaPfAmmto(dstatiRichiestaPfAmmto, pageable);
		List<DpianificFerieAmmto> content = drichPianifFerieAmmtoPage.getContent().stream()
				.map(DrichPianifFerieAmmto::getTheDpianificFerieAmmto).collect(Collectors.toList());
		Page<DpianificFerieAmmto> result = new PageImpl<DpianificFerieAmmto>(content, pageable,
				drichPianifFerieAmmtoPage.getTotalElements());
		return result;
	}

	@Override
	@Transactional()
	public DrichPianifFerieAmmto bulkUpdate(DrichPianifFerieAmmto drichPianifFerieAmmto) {

		DrichPianifFerieAmmto update = this.update(drichPianifFerieAmmto);

		return update;
	}
}
