#include <iostream>
#include "Contact.hpp"
#include <list>
#include <algorithm>

using namespace std;
using namespace reseau;

Contact::Contact(const Personne& Proprietaire): Proprietaire{Proprietaire} {
	// cout << "Contact créé " << Proprietaire << "\n";
}

const Personne& Contact::getProprio() const {
	return this->Proprietaire;
}

bool Contact::ajouterContact(const Personne& unContact){
	if(lesContacts.empty()){
		// cout << "Contact ajouté " << unContact <<"\n";
		lesContacts.push_back(&unContact);
		return true;
	}
	if(unContact==Proprietaire)
	{
		cout << "Erreur : Contact déjà existant (Proprietaire)\n";
		return false;	
	}
	list<const Personne*>::iterator it = find(lesContacts.begin(), lesContacts.end(), &unContact);
	if(it!=lesContacts.end()){
		cout << "Erreur : Personne déjà dans vos contacts : " << unContact << "\n";
		return false;
	}
	else {
		// cout << "Contact ajouté " << unContact <<"\n";
		lesContacts.push_back(&unContact);
		return true;
	}
	return true;
}

bool Contact::rechercher(const Personne& unContact){
	list<const Personne*>::iterator it = find(lesContacts.begin(), lesContacts.end(),&unContact);
	if(it != lesContacts.end())
	{
		cout << "trouvé : " << unContact << "\n";
		return true;
	}
	else 
	{
		cout << "pas trouvé\n";
		return false;
	}
	lesContacts.sort();
}

bool Contact::supprimerContact(const Personne& unContact){
	list<const Personne*>::iterator it = find(lesContacts.begin(), lesContacts.end(), &unContact);
	if(it!=lesContacts.end()){
		lesContacts.erase(it);
		cout << "Contact " << unContact << " supprimé\n";
		return true;
	}
	else {
		cout << "Erreur : le contact n'existe pas\n";
		return false;
	}
}

void Contact::afficherContactDirect() {
	cout << " Les contacts directs de " << this->Proprietaire << " sont : ";
	for(list<const Personne*>::const_iterator it = lesContacts.cbegin(); it != lesContacts.cend(); ++it){
		if(it==lesContacts.cbegin())
			cout << **it;
		else
			cout << ", " << **it;
	}
	if(lesContacts.empty())
		cout << "Aucun contact ";
	cout << "\n";
}

void Contact::Recursive(list<Contact*> Contacts, set<const Personne*>* set) {
	for(const Personne* Personne : lesContacts) {
		if(set->find(Personne)!=set->end())
			continue;
		set->insert(Personne);
		for(Contact* contact : Contacts) {
			if(*Personne == contact->getProprio()) {
				contact->Recursive(Contacts,set);
			}
		}
	}
}

void Contact::afficherContactIndirect(list<Contact*> Contacts) {
	cout << " Les contacts directs et indirects de " << this->Proprietaire << " sont : ";
	set<const Personne*> lesPersonnes{};
	Recursive(Contacts,&lesPersonnes);
	if(lesPersonnes.empty())
		cout << "Aucun contact ";
	for(const Personne* Personne : lesPersonnes)
		cout << *Personne << "  ";
	cout << "\n"; 
}

ostream& reseau::operator<<(ostream& os, Personne p){
	return os << p.getPrenom();
}

bool reseau::operator==(reseau::Personne p1, reseau::Personne p2){
	if(p1.getPrenom()==p2.getPrenom())
		return true;
	return false;
}
