package eu.eudat.models.rda.mapper;

import java.util.*;
import java.util.stream.Collectors;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.logic.utilities.json.JavaToJson;
import eu.eudat.models.rda.Cost;
import eu.eudat.models.rda.PidSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CostRDAMapper {
	private static final Logger logger = LoggerFactory.getLogger(DatasetRDAMapper.class);
	
	public static Cost toRDA(Map<String, Object> cost) {
		Cost rda = new Cost();
		Map<String, Object> code = new org.json.JSONObject((String) cost.get("code")).toMap();
		rda.setCurrencyCode(Cost.CurrencyCode.fromValue((String) code.get("value")));
		rda.setDescription((String) cost.get("description"));
		if (cost.get("title") == null) {
			throw new IllegalArgumentException("Cost Title is missing");
		}
		rda.setTitle((String) cost.get("title"));
		rda.setValue(((Integer) cost.get("value")).doubleValue());
		return rda;
	}

	public static List<Cost> toRDAList(List<JsonNode> nodes) throws JsonProcessingException {
		Map<String, Cost> rdaMap = new HashMap<>();
		for(JsonNode node: nodes){
			String rdaProperty = node.get("rdaProperty").asText();
			String rdaValue = node.get("value").asText();
			if(rdaValue == null || (rdaValue.isEmpty() && !node.get("value").isArray())){
				continue;
			}
			String key = node.get("numbering").asText();
			if(!key.contains("mult")){
				key = "0";
			}
			else{
				key = "" + key.charAt(4);
			}
			Cost rda;
			if(rdaMap.containsKey(key)){
				rda = rdaMap.get(key);
			}
			else{
				rda = new Cost();
				rdaMap.put(key, rda);
			}
			if(rdaProperty.contains("value")){
				rda.setValue(Double.valueOf(rdaValue));
			}
			else if(rdaProperty.contains("currency_code")){
				HashMap<String,String> result =
						new ObjectMapper().readValue(rdaValue, HashMap.class);
				rda.setCurrencyCode(Cost.CurrencyCode.fromValue(result.get("value")));
			}
			else if(rdaProperty.contains("title")){
				Iterator<JsonNode> iter = node.get("value").elements();
				StringBuilder title = new StringBuilder();
				while(iter.hasNext()){
					String next = iter.next().asText();
					if(!next.equals("Other")) {
						title.append(next).append(", ");
					}
				}
				if(title.length() > 2){
					rda.setTitle(title.substring(0, title.length() - 2));
				}
				else{
					String t = rda.getTitle();
					if(t == null){ // only other as title
						rda.setTitle(rdaValue);
					}
					else{ // option + other
						rda.setTitle(t + ", " + rdaValue);
					}
				}
			}
			else if(rdaProperty.contains("description")){
				rda.setDescription(rdaValue);
			}
		}
		List<Cost> rdaList = rdaMap.values().stream()
				.filter(cost -> cost.getTitle() != null)
				.collect(Collectors.toList());
		return rdaList;

	}

}
