package eu.dnetlib.data.claims.utils;

import com.google.gson.Gson;
import eu.dnetlib.data.claims.entity.Context;
import eu.dnetlib.data.claims.handler.ClaimHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.List;

/**
 * Created by kiatrop on 27/1/2016.
 */
public class ContextUtils {
    private static final Logger logger = LogManager.getLogger(ClaimHandler.class);
    private SearchUtils searchUtils;

    public Context fetchContextById(String openaireId) {
        Context context = new Context();
        if(openaireId == null ){
            return null;
        }
        context.setOpenaireId(openaireId);
        try {
            context.setTitle(extractLabel(context.getOpenaireId()));

        } catch (Exception e) {
            logger.error("ContextUtils: Couldn't get Egi label for id " + context.getOpenaireId(),e);
        }
        return context;

    }
    public String extractLabel(String code) throws Exception {
        String[] codeParts = code.split("::");
        String level0 = "";
        String level1 = "";
        String level2 = "";
        String level3 = "";
        if (codeParts.length >0) {
            String json = searchUtils.fetchContext("s/");
            level0 = getLabel(json, codeParts[0]);
        }
        if (codeParts.length >1) {
            String json = searchUtils.fetchContext("/"+codeParts[0]);
            level1 = getLabel(json, codeParts[0]+"::"+codeParts[1]);
        }
        if (codeParts.length >2) {
            String json = searchUtils.fetchContext("/category/"+codeParts[0]+"::"+codeParts[1]);
            level2 = getLabel(json, codeParts[0]+"::"+codeParts[1]+"::"+codeParts[2]);
        }
        if (codeParts.length >3) {
            String json = searchUtils.fetchContext("/category/concept/"+codeParts[0]+"::"+codeParts[1]+"::"+codeParts[2]);
            level3 = getSubLabel(json, codeParts[0]+"::"+codeParts[1]+"::"+codeParts[2], codeParts[0]+"::"+codeParts[1]+"::"+codeParts[2]+"::"+codeParts[3],((codeParts.length>4)?(codeParts[0]+"::"+codeParts[1]+"::"+codeParts[2]+"::"+codeParts[3]+"::"+codeParts[4]):null));
        }


        return level0+(level1.length()>0?("> "+level1+ (level3.length()>0?("> "+level3):((level2.length()>0)?("> "+level2 ):""))):"");

    }

    public static String getLabel(String json, String  id) {
         if (json == null) {
            return null;
        }
        Gson gson = new Gson();
        Concept[] concepts = gson.fromJson(json, Concept[].class);

        if (concepts != null && concepts.length > 0) {
            for (int i = 0; i < concepts.length; i++) {

                Concept concept = concepts[i];
                if(concept.type !=null && (concept.type.equals("funding"))){
                    continue;
                }

                    if (concept.id.equals(id)) {
                        return concept.label;
                    }

                }
            }

        return "";

    }
    private static String getSubLabel(String json, String  id, String subId, String subsubId) {
        if (json == null) {
            return null;
        }
        Gson gson = new Gson();
        Concept[] concepts = gson.fromJson(json, Concept[].class);

        if (concepts != null && concepts.length > 0) {
            for (int i = 0; i < concepts.length; i++) {

                Concept concept = concepts[i];
                if(concept.type !=null && (concept.type.equals("funding"))){
                    continue;
                }

                    if (concept.id.equals(id)) {
                        if (concept.getConcepts() != null) {
                            for (int j = 0; j < concept.getConcepts().size(); j++) {
                                Concept subConcept = concept.getConcepts().get(j);
                                if (subConcept.id.equals(subId)){
                                    if(subsubId == null ||subConcept.concepts ==null) {
                                        return subConcept.label;
                                    }else{
                                        for (int k = 0; k < subConcept.getConcepts().size(); k++) {
                                            Concept subSubConcept = subConcept.getConcepts().get(k);
                                            if (subSubConcept.id.equals(subsubId)) {
                                                return subSubConcept.label;
                                            }
                                        }
                                    }
                                    break;
                                }

                            }
                        }
                    }

            }
        } else {
            return null;
        }
        return "";

    }



        class Concept{
            String id;
            String label;
            String type;
            Boolean hasSubConcept;
            List<Concept> concepts;

            public String getId() {
                return id;
            }

            public void setId(String id) {
                this.id = id;
            }

            public String getLabel() {
                return label;
            }

            public void setLabel(String label) {
                this.label = label;
            }

            public String getType() {
                return type;
            }

            public void setType(String type) {
                this.type = type;
            }

            public Boolean getHasSubConcept() {
                return hasSubConcept;
            }

            public void setHasSubConcept(Boolean hasSubConcept) {
                this.hasSubConcept = hasSubConcept;
            }

            public List<Concept> getConcepts() {
                return concepts;
            }

            public void setConcepts(List<Concept> concepts) {
                this.concepts = concepts;
            }

            @Override
            public String toString() {
                return "Concept{" +
                        "id='" + id + '\'' +
                        ", label='" + label + '\'' +
                        ", type='" + type + '\'' +
                        ", hasSubConcept=" + hasSubConcept +
                        ", concepts=" + concepts +
                        '}';
            }
        }

    public SearchUtils getSearchUtils() {
        return searchUtils;
    }

    public void setSearchUtils(SearchUtils searchUtils) {
        this.searchUtils = searchUtils;
    }
}
