package microfolie.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import microfolie.persistance.entity.Espace;
import microfolie.persistance.entity.Frequentation;
import microfolie.persistance.entity.Usager;
import microfolie.persistance.table.EspaceTable;
import microfolie.persistance.table.FrequentationTable;
import microfolie.persistance.table.UsagerTable;
import microfolie.service.dto.FrequentationDTO;
import microfolie.service.transformer.FrequentationTransformer;
import microfolie.utils.DateUtils;

public class FrequentationService {
	
	private static FrequentationService instance;
	
	private UsagerTable usagerTable = UsagerTable.getInstance();
	private EspaceTable espaceTable = EspaceTable.getInstance();
	private FrequentationTable table = FrequentationTable.getInstance();
	
	private FrequentationService() {
		// Constructeur privé pour singleton
	}
	
	public boolean add(String codeUsager, String codeEspace) {
		Usager usager = usagerTable.getByCode(codeUsager);
		Espace espace = espaceTable.getByCode(codeEspace);
		Frequentation frequentation = table.getByUsagerAndEspaceToday(usager.id, espace.id);
		// Ajout en base si introuvable ou si il ne date pas d'ajourd'hui
		if (frequentation == null) {
			frequentation = new Frequentation();
			frequentation.usager = usager;
			frequentation.espace = espace;
			frequentation.date = new Date();
			table.save(frequentation);
			return true;
		}
		// Retourne faux pour indiquer que deja ajouté
		return false;
	}
	
	public List<FrequentationDTO> getByWeek(int history) {
		Date[] week = DateUtils.getDateOfTheWeek(history);
		List<Frequentation> frequentations = table.getByDate(week[DateUtils.BEGIN_DATE], week[DateUtils.END_DATE]);
		return FrequentationTransformer.entityToDto(frequentations);
	}
	
	public Map<Date, List<FrequentationDTO>> getByDayOfWeek(int history) {
		Map<Date, List<FrequentationDTO>> result = new LinkedHashMap<>();
		List<FrequentationDTO> list = getByWeek(history);
		// Creation clef map
		for(Date d : DateUtils.getAllDateOfTheWeek(history)) {
			result.put(d, new ArrayList<>());
		}
		// Remplissage map
		list.forEach(elt -> {
			List<FrequentationDTO> day = result.get(elt.getDate());
			day.add(elt);
		});
		return result;
	}
	
	public Map<String, Map<Integer, List<FrequentationDTO>>> getByAgeOnEspace(int history) {
		List<Espace> espaces = espaceTable.getAll();
		Date[] month = DateUtils.getDateOfTheMonth(history);
		Map<String, Map<Integer, List<FrequentationDTO>>> result = new LinkedHashMap<>();
		// Remplissage
		espaces.forEach(elt -> {
			// Création map
			Map<Integer, List<FrequentationDTO>> map = new LinkedHashMap<>();
			// Recup information
			List<Frequentation> data = table.getByEspaceAndDate(elt, month[DateUtils.BEGIN_DATE], month[DateUtils.END_DATE]);
			List<FrequentationDTO> freqs = FrequentationTransformer.entityToDto(data);
			// Ajout
			freqs.forEach(freq -> {
				if (map.containsKey(freq.getAge())) {
					List<FrequentationDTO> list = map.get(freq.getAge());
					list.add(freq);
				} else {
					List<FrequentationDTO> list = new ArrayList<>();
					list.add(freq);
					map.put(freq.getAge(), list);
				}
			});
			result.put(elt.code, map);
		});
		return result;
	}
	
	public Map<String, List<FrequentationDTO>> getByEspaceWeek(int history) {
		List<Espace> espaces = espaceTable.getAll();
		Date[] week = DateUtils.getDateOfTheWeek(history);
		Map<String, List<FrequentationDTO>> result = new LinkedHashMap<>();
		// Remplissage
		espaces.forEach(elt -> {
			// Recup information
			List<Frequentation> data = table.getByEspaceAndDate(elt, week[DateUtils.BEGIN_DATE], week[DateUtils.END_DATE]);
			List<FrequentationDTO> freqs = FrequentationTransformer.entityToDto(data);
			// Ajout
			result.put(elt.code, freqs);
		});
		return result;
	}
	
	public Map<String, List<FrequentationDTO>> getByEspaceMonth(int history) {
		List<Espace> espaces = espaceTable.getAll();
		Date[] month = DateUtils.getDateOfTheMonth(history);
		Map<String, List<FrequentationDTO>> result = new LinkedHashMap<>();
		// Remplissage
		espaces.forEach(elt -> {
			// Recup information
			List<Frequentation> data = table.getByEspaceAndDate(elt, month[DateUtils.BEGIN_DATE], month[DateUtils.END_DATE]);
			List<FrequentationDTO> freqs = FrequentationTransformer.entityToDto(data);
			// Ajout
			result.put(elt.code, freqs);
		});
		return result;
	}
	
	public static FrequentationService getInstance() {
		if (instance == null) {
			instance = new FrequentationService();
		}
		return instance;
	}

}
