#include <iostream>
#include <string>
#include <map>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <vector>

#include "Entreprise.h"
#include "Pays.h"

using namespace std;

template <class M>
void lire(M& map, const string filename) {
	using V = typename M::mapped_type;
	using K = typename M::key_type;

	ifstream f(filename);

	if (!f.is_open()) {
		cout << "Erreur lors de la lecture du fichier " << filename << endl;
		return;
	}

	//f.ignore(200, '\n');
	while (!f.eof()) {
		V a;
		a.saisie(f);
		
		// a.affichage();
		// map[a.key()] = a;
		map.insert(make_pair(a.key(), a));

//		f.ignore(2000, '\n');
	}
}

template <class M>
void affichage_el(M el) {
	el.affichage();
}

void affichage_el(float el) {
	cout << el;
}

template <class Start, class Stop>
void affichage_range(Start start, Stop stop) {
	cout << left << setw(30) << "Key" << "Value\n";
	for (; start != stop; start++) {
		cout << left << setw(30) << start->first;
		affichage_el(start->second);
		cout << '\n';
	}
	cout << endl;
}

template <class M>
void affichage(M& map) {
	affichage_range(map.begin(), map.end());
}

void chercher(const map<string, Entreprise>& entreprises) {
	string r;

	cout << "Entrez le nom de l'entreprise à rechercher : ";
	getline(cin, r);

	auto it = entreprises.find(r);
	if (it == entreprises.end()) {
		cout << "L'entreprise n'a pas été trouvée" << endl;
	}
	else {
		cout << "Entreprise trouvée!" << endl;
		Entreprise e = it->second;
		e.affichage();
		cout << endl;
	}

}

bool cmp_progression_classement(const pair<string, Entreprise>& e1, const pair<string, Entreprise>& e2) {
	return e1.second.rank_progress() < e2.second.rank_progress();
}

void ranking_progress(const map<string, Entreprise>& entreprise) {
	auto it_max = max_element(entreprise.begin(), entreprise.end(), cmp_progression_classement);
	auto it_min = min_element(entreprise.begin(), entreprise.end(), cmp_progression_classement);

	cout << "L'entreprise avec la plus grosse chute est " << it_min->first << " (" << it_min->second.rank_progress() << ")" << endl;
	cout << "L'entreprise avec la plus grosse progression est " << it_max->first << " (+" << it_max->second.rank_progress() << ")" << endl;
}

bool cmp_ranking(const pair<string, float> &p1, const pair<string, float>& p2) {
	return p1.second > p2.second;
}

bool cmp_turnover(const pair<string, Entreprise>& e1, const pair<string, Entreprise>& e2) {
	return e1.second.getTurnover() < e2.second.getTurnover();
}

void entreprises_ranking(const map<string, Entreprise>& entreprises) {
	vector<pair<string, float>> ranking;

	for (auto& e : entreprises) {
		float turnover = e.second.turnover_empl();
		ranking.push_back(make_pair(e.first, turnover));
	}

	sort(ranking.begin(), ranking.end(), cmp_ranking);

	affichage(ranking);

	auto e_max = max_element(entreprises.begin(), entreprises.end(), cmp_turnover);
	cout << "Le turnover maximum est : " << e_max->second.getTurnover() << " pour l'entreprise " << e_max->first << endl;
}

void toupper(string& s) {
	for (int i = 0; i < s.size(); i++)
		s[i] = toupper(s[i]);
}

void pays_region( const multimap<string, Pays>& pays) {
	string recherche;

	cout << "Entrez le nom de la région cherchée: ";
	getline(cin, recherche);
	toupper(recherche);

	auto range = pays.equal_range(recherche);

	if (range.first == pays.end()) {
		cout << "La région n'a pas été trouvée" << endl;
		return;
	}

	//for (auto it = range.first; it != range.second; it++) {
	affichage_range(range.first, range.second);
	//}
}

int menu() {
	int choix;

	cout << "1. Lire le fichier Entreprises et affichage" << endl
		<< "2. Lire le fichier Pays et affichage" << endl
		<< "3. Chercher une entreprise par son nom et affichage" << endl
		<< "4. Cherchez les entreprises ayant réalisé la plus grosse progression / chute et affichage" << endl
		<< "5. Calculez le Turnover / Employee, le chiffre d’affaire moyen généré par employé, de toutes les entreprises, et trouver le max" << endl
		<< "6. Pour une région donnée, affichez tous les pays dans cette région" << endl
		<<  "7. Quitter" << endl;

	cout << "Votre choix : ";
	
	cin >> choix; cin.ignore();
	return choix;
}

int main() {
	map<string, Entreprise> entreprises;
	multimap<string, Pays> pays;

	setlocale(LC_ALL, "");

	while (true) {
		switch (menu()) {
		case 1:
			lire(entreprises, "entreprises.txt");
			affichage(entreprises);
			break;
		case 2:
			lire(pays, "countries.txt");
			affichage(pays);
			break;
		case 3:
			chercher(entreprises);
			break;
		case 4:
			ranking_progress(entreprises);
			break;
		case 5:
			entreprises_ranking(entreprises);
			break;
		case 6:
			pays_region(pays);
			break;
		case 7:
			return 0;
		}
	}

	affichage(pays);

	cout << entreprises.size() << endl;

	return 0;
}


