package eu.dnetlib.data.db;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.jdbc.core.JdbcTemplate;

import eu.dnetlib.data.mdstore.plugins.EnrichLabsPlugin;

public class DbPersonsDao {

	private JdbcTemplate jdbcTemplate;

	public List<DbPerson> listPersonsWithAffiliations() {

		final Map<String, DbPerson> temp = new HashMap<>();

		for (final Map<String, Object> map : jdbcTemplate.queryForList("select * from affiliations_view")) {
			final String pid = (String) map.get("pid");
			final Integer year = (Integer) map.get("year");
			final DbGroup group = new DbGroup((String) map.get("gid"), (String) map.get("gname"), (String) map.get("gtype"));

			temp.putIfAbsent(pid, new DbPerson(pid, (String) map.get("pfullname"), (String) map.get("orcid")));

			if (year != null) {
				temp.get(pid).getGroups().putIfAbsent(year, new TreeSet<>((g1, g2) -> {
					final int n1 = calculateIntegerForGroup(g1.getType());
					final int n2 = calculateIntegerForGroup(g2.getType());
					return (n1 == n2) ? g1.getId().compareTo(g2.getId()) : Integer.compare(n1, n2);
				}));
				temp.get(pid).getGroups().get(year).add(group);
			}
		}

		return temp.values()
				.stream()
				.sorted((p1, p2) -> p1.getFullname().compareTo(p2.getFullname()))
				.collect(Collectors.toList());

	}

	public Map<String, String> obtainRawPersonToMasterRels() {
		final Map<String, String> res = new HashMap<>();
		for (final Map<String, Object> map : jdbcTemplate.queryForList("select raw_id, master_id from raw_persons where master_id is not null")) {
			final String rawId = (String) map.get("raw_id");
			final String masterId = EnrichLabsPlugin.DNET_PERSON_PREFIX + map.get("master_id");
			res.put(rawId, masterId);
		}
		return res;
	}

	private int calculateIntegerForGroup(final String type) {
		if (type.equalsIgnoreCase("Laboratorio")) {
			return 0;
		} else if (type.equalsIgnoreCase("Servizio")) {
			return 10;
		} else if (type.equalsIgnoreCase("Centro")) {
			return 20;
		} else {
			return 100;
		}
	}

	public void registerRawPerson(final String code, final String name, final String surname, final String suffix, final String orcid) {
		jdbcTemplate.update("INSERT IGNORE INTO raw_persons(raw_id, name, surname, suffix, orcid) VALUES (?, ?, ?, ?, ?)", code, name, surname, suffix, orcid);
	}

	public void registerAffiliation(final String pid, final String gid, final int year) {
		jdbcTemplate.update("INSERT IGNORE INTO affiliations(pid, gid, year) VALUES (?, ?, ?)", pid, gid, year);
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	@Required
	public void setJdbcTemplate(final JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

}
