package fr.iutfbleau.projetIHM2021FI2.Model;

import fr.iutfbleau.projetIHM2021FI2.API.*;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Predicate;
import java.sql.*;

/**
 * La classe PrereservationFactoryModel permet de gérer les préréservations.
 *  
 * @version 1.0
 * @author Anice TAJGALT, Gianni MANZARI, Alban DUMAS
 */
public class PrereservationFactoryModel implements PrereservationFactory {
    private HashMap<String,Prereservation> map =new HashMap<String,Prereservation>();

    /** Constructeur */
    public PrereservationFactoryModel() {

        try {
			PreparedStatement pst = ConnexionBDD.getSQLco().prepareStatement(
			"SELECT DISTINCT client, reference, debut, nuits, categorie FROM Reservation JOIN Client c ON c.id = client");

            pst.executeUpdate();

			ResultSet rs = pst.executeQuery();

            // On ajoute toutes les préreservations au map
			while (rs.next()) {
				RecupClient c = RecupClient.byId(rs.getInt("client"));
				this.map.put(rs.getString("reference"), new PrereservationModel(rs.getString("reference"), LocalDate.parse(rs.getString("debut")), rs.getInt("nuits"), TypeChambre.values()[rs.getInt("categorie") - 1], c));
			}

			rs.close();
			pst.close();
		}

		catch(SQLException e) {
			System.err.println("Problème lors de la récupération des préréservations.");
		}
    }

    /**
     * Recherche par référence
     * Ne devrait pas retourner un objet null.
     */
    public Prereservation getPrereservation(String r){
        Objects.requireNonNull(r,"La référence recherchée est vide.");
        if (this.map.containsKey(r)){
            return this.map.get(r);
        }
        else {
            throw new IllegalStateException("Il n'existe pas de préréservation avec la référence : " + r);
        }
    }
    /**
     * Recherche par nom et prénom
     * Ne devrait pas retourner un objet null ou un ensemble vide.
     */
    public Set<Prereservation> getPrereservations(String n, String p){
        Objects.requireNonNull(n,"Le nom est vide.");
        Objects.requireNonNull(p,"Le prénom est vide.");


        Collection<Prereservation> c = this.map.values();
        Predicate<Prereservation> filtre = preresa -> !preresa.getClient().getNom().equals(n) || !preresa.getClient().getPrenom().equals(p);
        //          COLLECTION
        c.removeIf(filtre);
        if (c.isEmpty()){
            throw new IllegalStateException("Pas de préréservation au nom de : " + n + p);
        }
        // on fabrique un ensemble.
        Set<Prereservation> found = new HashSet<Prereservation>(c);
        return found;
    }

    /**
     * Récupération de toutes les préréservations.
     */
    public Set<Prereservation> getAllPrereservations() {
        return new HashSet<Prereservation>(this.map.values());
    } 
}
