package pkg;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class OrokbefogadasKezeloImpl implements OrokbefogadasKezelo {

	@Override
	public int legtobbetKedvencetOrokbefogado(List<Orokbefogadas<Kedvenc, Orokbefogado>> lista) {
		return (int) lista.stream()
			.collect(Collectors.groupingBy(Orokbefogadas::getOrokbefogado, Collectors.counting()))
			.values()
			.stream()
			.mapToLong(Long::longValue)
			.max()
			.getAsLong();
	}

	@Override
	public List<Orokbefogado> megbizhatoOrokbefogadok(List<Orokbefogadas<Kedvenc, Orokbefogado>> lista) {
		return lista.stream()
			.map(o -> o.getOrokbefogado()).filter(o -> o.getMegbizhatosag() >= 5)
			.distinct()
			.collect(Collectors.toList());
	}

	@Override
	public Orokbefogadas<Kedvenc, Orokbefogado> legkorabbiOrokbefogadas(
			List<Orokbefogadas<Kedvenc, Orokbefogado>> lista) {
		return lista.stream()
			.min(Comparator.comparing(Orokbefogadas::getIdopont))
			.get();
	}

	@Override
	public List<Kedvenc> kedvencekMikrochipNelkul(List<Orokbefogadas<Kedvenc, Orokbefogado>> lista) {
		return lista.stream()
			.map(o -> o.getKedvenc()).filter(k -> k.getMicroChipSzama() == null)
			.distinct()
			.collect(Collectors.toList());
	}

	@Override
	public List<Kedvenc> orokbefogadottKedvencekNevSzerintRenezve(List<Orokbefogadas<Kedvenc, Orokbefogado>> lista) {
		return lista.stream()
			.map(o -> o.getKedvenc()).sorted(Comparator.comparing(Kedvenc::getNev))
			.distinct()
			.collect(Collectors.toList());
	}

	@Override
	public Map<Orokbefogado, List<Orokbefogadas<Kedvenc, Orokbefogado>>> orokbefogadasokOrokbefogadokent(
			List<Orokbefogadas<Kedvenc, Orokbefogado>> lista) {
		return lista.stream().collect(Collectors.groupingBy(Orokbefogadas::getOrokbefogado));
	}

	@Override
	public List<Kedvenc> visszaVittKedvencek(List<Orokbefogadas<Kedvenc, Orokbefogado>> lista) {
		return lista.stream()
			.collect(Collectors.groupingBy(Orokbefogadas::getKedvenc, Collectors.counting()))
			.entrySet()
			.stream()
			.filter(e -> e.getValue() > 1)
			.map(e -> e.getKey())
			.collect(Collectors.toList());
	}

	// Segédmetódus, mely minden egyes kedvenchez meghatározza a legutóbbi örökbefogadását.
	private List<Orokbefogadas<Kedvenc, Orokbefogado>> utolsoOrokbefogadas(List<Orokbefogadas<Kedvenc, Orokbefogado>> lista){
		return lista.stream()
			.collect(Collectors.groupingBy(Orokbefogadas::getKedvenc, Collectors.maxBy(Comparator.comparing(Orokbefogadas::getIdopont))))
			.values()
			.stream()
			.map(m->m.get())
			.collect(Collectors.toList());
	}

	@Override
	public List<Orokbefogado> feketeLista(List<Orokbefogadas<Kedvenc, Orokbefogado>> lista) {
		lista.removeAll(utolsoOrokbefogadas(lista)); // Töröljük minden egyes kedvenc legutóbbi örökbefogadását.
		return lista.stream()
			.collect(Collectors.groupingBy(Orokbefogadas::getOrokbefogado, Collectors.counting()))
			.entrySet().stream()
			.filter(e -> e.getValue() > 3)
			.map(e -> e.getKey())
			.collect(Collectors.toList());
	}

	@Override
	public List<Kedvenc> veglegesOrokbefogadas(List<Orokbefogadas<Kedvenc, Orokbefogado>> lista) {
		return lista.stream()
			.collect(Collectors.groupingBy(Orokbefogadas::getKedvenc, Collectors.maxBy(Comparator.comparing(Orokbefogadas::getIdopont))))
			.entrySet()
			.stream()
			.filter(e -> e.getValue().get().getIdopont().until(LocalDateTime.now(), ChronoUnit.DAYS) > 60)
			.map(e -> e.getKey())
			.collect(Collectors.toList());
	}

}