package com.eyrolles.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.eyrolles.model.Auteur;
import com.eyrolles.model.Categorie;
import com.eyrolles.model.Livre;
import com.eyrolles.model.Publieur;
import com.eyrolles.model.SousCategorie;
import com.eyrolles.repository.AuteurRepository;
import com.eyrolles.repository.LivreRepository;
import com.eyrolles.repository.PublieurRepository;
import com.eyrolles.util.LivresByDateComparator;
import com.eyrolles.util.LivresByPriceComparator;

@Service
public class LivreService implements ILivreService{
	
	@Autowired
	LivreRepository livreRepository;
	@Autowired
	PublieurRepository publieurRepository;
	@Autowired
	AuteurRepository auteurRepository;
	public com.eyrolles.model.Livre add(Livre nouveau){
		return livreRepository.save(nouveau);
	}
	public void delete(int idLivre){
		livreRepository.delete(idLivre);
	}
	public List<Livre> all(){
		List<Livre> livres=livreRepository.findAll();
		return livres;
	}
	
	public Page<Livre> searchByTheme(int idTheme,int page,int size){
		Pageable pageable=new PageRequest(page, size);
		return livreRepository.getAll(idTheme, pageable);
	}
	
	public Page<Livre> searchByCategory(int idCategory,int page,int size){
		Pageable pageable=new PageRequest(page, size);
		return livreRepository.getByCategorie(idCategory, pageable);
	}
	
	public Page<Livre> searchBySubCategory(int idSubCategory,int page,int size){
		Pageable pageable=new PageRequest(page, size);
		return livreRepository.getBySubCategorie(idSubCategory, pageable);
	}
	public Page<Livre> searchByMC(String mc,int page,int size){
		Pageable pageable=new PageRequest(page, size);
		return livreRepository.getByMC(mc, pageable);
	}
	public Livre details(int idLivre){
		Livre livre=livreRepository.findOne(idLivre);
		return livre;
	}
	public Livre updateDetails(Livre modified){
		return null;
	}
	public List<Livre> search(List<Livre> livres,String keyWord){
		List<Livre> result=new ArrayList<Livre>();
		for(Livre l:livres)
			if(l.getTitre().toLowerCase().contains(keyWord.toLowerCase()))
				result.add(l);
		return result;
	}
	public List<Livre> search(List<Livre> livres,double prixInf,double prixSup){
		List<Livre> result=new ArrayList<Livre>();
		for(Livre l:livres)
			if(l.getPrix()>=prixInf&&l.getPrix()<=prixSup)
				result.add(l);
		return result;
	}
	public List<Livre> searchByTheme(List<Livre> livres,int idTheme){
		List<Livre> result=new ArrayList<Livre>();
		if(livres==null)
			return result;
		for(Livre l:livres)
			if(l.getTheme().getId()==idTheme)
				result.add(l);
		return result;
	}
	
	public List<Livre> searchByCategorie(List<Livre> livres,Categorie categorie){
		List<Livre> result=new ArrayList<Livre>();
		if(livres==null)
			return result;
		for(Livre l:livres)
			if(l.getCategorie().equals(categorie))
				result.add(l);
		return result;
	}
	public List<Livre> searchBySousCategorie(List<Livre> livres,SousCategorie sousCategorie){
		List<Livre> result=new ArrayList<Livre>();
		if(livres==null)
			return result;
		for(Livre l:livres)
			if(l.getSousCategorie().equals(sousCategorie))
				result.add(l);
		return result;
	}
	public List<Livre> orderByPriceDESC(List<Livre> livres){
		Comparator<Livre> livresByPriceComparator=new LivresByPriceComparator();
		Collections.sort(livres,Collections.reverseOrder(livresByPriceComparator));
		return livres;
	}
	public List<Livre> orderByDateDESC(List<Livre> livres){
		Comparator<Livre> livresByDateComparator=new LivresByDateComparator();
		Collections.sort(livres,Collections.reverseOrder(livresByDateComparator));
		return livres;
	}
	public List<Livre> orderByPriceASC(List<Livre> livres){
		Comparator<Livre> livresByPriceComparator=new LivresByPriceComparator();
		Collections.sort(livres,livresByPriceComparator);
		return livres;
	}
	public List<Livre> orderByDateASC(List<Livre> livres){
		Comparator<Livre> livresByDateComparator=new LivresByDateComparator();
		Collections.sort(livres,livresByDateComparator);
		return livres;
	}
	@SuppressWarnings("deprecation")
	public List<Livre> yearNews(List<Livre> livres){
		List<Livre> result=new ArrayList<Livre>();
		if(livres==null)
			return result;
		for(Livre l:livres)
			if(l.getDateParution().getYear()==new Date().getYear())
				result.add(l);
		return result;
	}
	@SuppressWarnings("deprecation")
	public List<Livre> monthNews(List<Livre> livres){
		List<Livre> result=new ArrayList<Livre>();
		if(livres==null)
			return result;
		for(Livre l:livres)
			if(l.getDateParution().getMonth()==new Date().getMonth())
				result.add(l);
		return result;
	}
	public Livre change(Livre l,Publieur p){
		publieurRepository.save(p);
		l.setPublieur(p);
		return livreRepository.save(l);
	}
	public Livre add(Livre l,Auteur a){
		auteurRepository.save(a);
		if (l.getAuteurs() == null)
			l.setAuteurs(new ArrayList<Auteur>());
		l.getAuteurs().add(a);
		return livreRepository.save(l);	
	}
	public Livre change(Livre l,Auteur a){
		for(Auteur auteur : l.getAuteurs())
		if(auteur.getId() == a.getId())
			{
			l.getAuteurs().remove(auteur);
			l.getAuteurs().add(a);
			}
		return livreRepository.save(l);	
	}
	public Livre delete(Livre l,Auteur a){
		l.getAuteurs().remove(a);
		return livreRepository.save(l);	
	}
}
