package microfolie.service;

import java.util.List;
import java.util.Optional;
import java.util.Random;

import microfolie.persistance.entity.Frequentation;
import microfolie.persistance.entity.Usager;
import microfolie.persistance.table.FrequentationTable;
import microfolie.persistance.table.UsagerTable;
import microfolie.service.dto.UsagerDTO;
import microfolie.service.transformer.UsagerTransformer;

public class UsagerService {
	
	private static final String ALPHA_NUMERIC_STRING = "abcdefghijqlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
	private static final Random RANDOM = new Random();
	private static UsagerService instance;
	
	private FrequentationTable frequentationTable = FrequentationTable.getInstance();
	private UsagerTable table = UsagerTable.getInstance();
	
	private UsagerService() {
		// Constructeur privé pour singleton
	}
	
	public void add(UsagerDTO usagerDTO) {
		Usager usager = UsagerTransformer.dtoToEntity(usagerDTO);
		usager.code = generateUniqueCode();
		table.save(usager);
		
		List<Usager> l = table.getAll();
		l.forEach(elt -> System.out.println(elt.id + ": " + elt));
	}
	
	public UsagerDTO getUsager(String code) {
		Optional<Usager> optUsager = table.findByCode(code);
		if(optUsager.isPresent()) {
			return UsagerTransformer.entityToDto(optUsager.get());
		}
		return null;
	}
	
	public boolean exist(String code) {
		return table.findByCode(code).isPresent();
	}
	
	public long getTotalNumber() {
		return table.getNumberUsagerInDatabase();
	}
	
	public List<UsagerDTO> getPage(int num, int perPage) {
		List<Usager> usagers = table.getpage(num, perPage);
		return UsagerTransformer.entityToDto(usagers);
	}
	
	public boolean delete(String code) {
		Optional<Usager> opt = table.findByCode(code);
		if (opt.isPresent()) {
			Usager usager = opt.get();
			List<Frequentation> freqs = frequentationTable.getByUsager(usager);
			freqs.forEach(f -> {
				f.usager = null;
				frequentationTable.save(f);
			});
			return table.del(usager);
		}
		return false;
	}
	
	private String generateUniqueCode() {
		String code;
		do {
			StringBuilder builder = new StringBuilder();
			for(int i = 0; i < 4; i++) {
				int pos = RANDOM.nextInt(ALPHA_NUMERIC_STRING.length());
				builder.append(ALPHA_NUMERIC_STRING.charAt(pos));
			}
			code = builder.toString();
		}while(!table.codeIsUnique(code));
		return code;
	}
	
	public static UsagerService getInstance() {
		if (instance == null) {
			instance = new UsagerService();
		}
		return instance;
	}

}
