import {Injectable} from '@angular/core';
import {HttpClient, HttpErrorResponse} from "@angular/common/http";
import {throwError} from 'rxjs';



import{EnvProperties} from '../properties/env-properties';

import {catchError, map} from "rxjs/operators";
@Injectable()
export class EntitiesSearchService {
    public ready:boolean = false;
    constructor(private http: HttpClient ) {}

    /*searchProjectsByFunder(keyword:string, funderId:string, properties:EnvProperties ):any {
      this.ready = false;
      let url = properties.searchResourcesAPIURL;
      //console.log("Funder is " + funderId);
      url = url+"?query=(oaftype exact project and deletedbyinference=false) ";
      if(keyword!= null && keyword != ''  ) {
        url +=  'and ((projectcode_nt exact "'+keyword+'" )or('+keyword+')) ' ;
        url+=((funderId && funderId.length > 0 )?("&fq=funder exact " + '"'+funderId+ '"'):"");
      }

      url += "&page=0&size=10";
      url += "&format=json";
      //console.log("URL " + url);
      // let url =  properties.searchAPIURLLAst+"projects?"+((keyword && keyword.length > 0)?("q=" +keyword):"")+((funderId && funderId.length > 0 )?"&fq=funder exact " + '"'+funderId+ '"':"")+"&size=10&page=0&format=json";
      return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url).toPromise()
      .then(request =>
        {
          //request = request.json().results;
          request = request['results'];
          this.ready = true;
          return this.parse(request,"oaf:project","project");
        }).catch((ex) => {
          console.error('An error occured', ex);
          return  [{id:'-2',label:'Error'}];
        });
      }*/

      // not used
      /**
       * @deprecated
       */
      searchByDepositType(keyword:string, DepositType:string, properties:EnvProperties ):any {
        this.ready = false;

        let link = properties.searchResourcesAPIURL;

        let url = link+"?query=";
        if(keyword!= null && keyword != ''  ) {
          /*url += "((oaftype exact organization and deletedbyinference=false and "+
            "(reldatasourcecompatibilityid=driver or reldatasourcecompatibilityid=driver-openaire2.0 or reldatasourcecompatibilityid=openaire2.0 or reldatasourcecompatibilityid=openaire3.0 or reldatasourcecompatibilityid=openaire2.0_data or reldatasourcecompatibilityid=hostedBy or relprojectid=* or reldatasourcecompatibilityid = native))"+
            " and ((organizationlegalname all "+'"'+keyword+'"'+") or (organizationlegalshortname all "+'"'+keyword+'"'+")) " +
            // "and " + this.quote(params) + " " +
            "and (collectedfrom exact "+StringUtils.quote(StringUtils.URIEncode(DepositType))+")) "*/

            // in search there is this filter:
            //reldatasourcecompatibilityid exact driver or reldatasourcecompatibilityid exact driver-openaire2.0 or reldatasourcecompatibilityid exact openaire2.0 or reldatasourcecompatibilityid exact openaire3.0 or reldatasourcecompatibilityid exact openaire2.0_data or reldatasourcecompatibilityid exact hostedBy or relproject=*


          //url += "((oaftype exact organization and deletedbyinference=false )"+
          url += "((oaftype exact organization and deletedbyinference=false and"+
            "(reldatasourcecompatibilityid=driver or reldatasourcecompatibilityid=driver-openaire2.0 or reldatasourcecompatibilityid=openaire2.0 or reldatasourcecompatibilityid=openaire3.0 or reldatasourcecompatibilityid=openaire4.0 or reldatasourcecompatibilityid=openaire2.0_data or reldatasourcecompatibilityid=hostedBy or relprojectid=* or reldatasourcecompatibilityid = native))"+
            " and ((organizationlegalname all "+'"'+keyword+'"'+") or (organizationlegalshortname all "+'"'+keyword+'"'+")) " +
            // "and " + this.quote(params) + " " +
            //"and (collectedfrom exact "+StringUtils.quote(StringUtils.URIEncode(DepositType))+")) "
            ")";
        }

        url += "&page=0&size=10";
        url += "&format=json";

        // let url =  properties.searchAPIURLLAst+"projects?"+((keyword && keyword.length > 0)?("q=" +keyword):"")+((funderId && funderId.length > 0 )?"&fq=funderid exact " + '"'+funderId+ '"':"")+"&size=10&page=0&format=json";
        return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url).toPromise()
        .then(request =>
          {
            //request = request.json().results;
            request = request['results'];
            //console.log(request);
            this.ready = true;
            return this.parse(request,"oaf:organization","organization");
          }).catch((ex) => {
            console.error('An error occured', ex);
            return  [{id:'-2',label:'Error'}];
          });
        }

    searchByType(keyword:string,type:string, properties:EnvProperties ){
       if (type == "project"){
         return  this.searchEntity(keyword,"projects","oaf:project","project", properties);
      }else if (type == "dataset"){
        return  this.searchEntity(keyword,"datasets","oaf:result","dataset", properties);
      }else if (type == "datasource" || type == "hostedBy" || type== "collectedFrom"){
        return  this.searchEntity(keyword,"datasources","oaf:datasource","datasource", properties);
      }else if (type == "publication"){
        return  this.searchEntity(keyword,"publications","oaf:result","publication", properties);
      }else if (type == "organization"){
        return  this.searchEntity(keyword,"organizations","oaf:organization","organization", properties);

      }

    }
    fetchByType(id:string,type:string, properties:EnvProperties ){
       if (type == "project"){
         return  this.fetchEntity(id,"projects","oaf:project","project", properties);
      }else if (type == "dataset"){
        return  this.fetchEntity(id,"datasets","oaf:result","dataset", properties);
      }else if (type == "datasource"  || type == "hostedBy" || type== "collectedFrom"){
        return  this.fetchEntity(id,"datasources","oaf:datasource","datasource", properties);
      }else if (type == "publication"){
        return  this.fetchEntity(id,"publications","oaf:result","publication", properties);
      }else if (type == "organization"){
        return  this.fetchEntity(id,"organizations","oaf:organization","organization", properties);

      }

    }
private searchEntity (keyword: string,APIname:string,oafEntityType:string, type:string, properties:EnvProperties ):any {
      let link = properties.searchAPIURLLAst+APIname;
      return this.search(link,keyword,oafEntityType,type, properties)

}
private fetchEntity (id: string,APIname:string,oafEntityType:string, type:string, properties:EnvProperties ):any {
    let link = properties.searchAPIURLLAst+APIname;
    return this.fetch(link,id,oafEntityType,type, properties)
}
private fetch (link,id,oafEntityType,type, properties:EnvProperties ){
  this.ready = false;
  let url = link+"/"+id+"?format=json";
  return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url)
    //.map(request => <any> request.json())
    // .do(res => console.info(res))
    .pipe(map(request => {
      this.ready = true;
      return this.parse(request,oafEntityType,type);
    }))
    .pipe(catchError((ex) => {
      console.error('An error occured', ex);
      return  [{id:'-2',label:'Error'}];
    }));

}
    private search (link,keyword,oafEntityType,type, properties:EnvProperties ){
      this.ready = false;
      let url = link+"?";
      if(keyword!= null && keyword != ''  ) {
          if(type=="project") {
            //name, title, acronym, grantid
            url += "fq="+'(projectcode_nt="'+keyword+'" ) or (fundershortname='+'"'+keyword+ '"'+') or (projectacronym="'+keyword+'" ) or (projecttitle="'+keyword+'")';
          } else if(type=="organization") {
            //name fields
            url += "fq="+'(organizationlegalname="'+keyword+'" ) or (organizationlegalshortname='+'"'+keyword+ '")';
          } else {
            url += "q="+ keyword;
          }
      }

      url += "&page=0&size="+10+"&format=json";
      return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url).toPromise()
                 .then(request =>
                   {
                     //request = request.json().results;
                     request = request['results'];
                     this.ready = true;
                     return this.parse(request,oafEntityType,type);
                   }).catch((ex) => {
                     console.error('An error occured', ex);
                     return [{id:'-2',label:'Error'}];
                   });


    }

    private parse(data: any,oafEntityType:string, type:string){
      var array:any =[]
      let length = Array.isArray(data) ? data.length : 1;

      for(let i=0; i<length; i++) {
            let resData = Array.isArray(data) ? data[i]['result']['metadata']['oaf:entity'][oafEntityType] : data['result']['metadata']['oaf:entity'][oafEntityType];

            var value:any={} ;
            if(resData['title']){
              if(Array.isArray(resData['title'])) {
                    value.label = resData['title'][0];
              } else {
                    value.label = resData['title'];
              }
              if(oafEntityType=="oaf:result"){
                value.label = value.label.content;
                value.result = resData;
              }
            }else if(resData["fullname"]){
              if(Array.isArray(resData["fullname"])) {
                    value.label = resData["fullname"][0];
              } else {
                    value.label = resData["fullname"];
              }
            }else if(resData["legalname"]){

              if(Array.isArray(resData["legalname"])) {
                    value.label = resData["legalname"][0];
              } else {
                    value.label = resData["legalname"];
              }
              if(resData["legalshortname"]){

                if(Array.isArray(resData["legalshortname"])) {
                      value.label += " (" + resData["legalshortname"][0] +")";
                } else {
                      value.label += " (" +  resData["legalshortname"] +")";
                }
              }

            }else if(resData["officialname"]){

              if(Array.isArray(resData["officialname"])) {
                    value.label = resData["officialname"][0];
              } else {
                    value.label = resData["officialname"];
              }
            }

           value.id = Array.isArray(data) ? data[i]['result']['header']['dri:objIdentifier'] : data['result']['header']['dri:objIdentifier'];

             if(type=="project"){
                  value.projectAcronym = resData['acronym'];
                  value.projectName = value.label;
                  value.endDate = null;
                  value.startDate = null;
                  value.funderId = "";
                  value.funderName = "";
                  value.jurisdiction = "";
                  value.fundingLevel0 = "";
                  value.code =  resData['code'];

                  if(resData['fundingtree'] && resData['fundingtree']['funder']){
                    value.funderId = (resData['fundingtree']['funder']['id'] )?resData['fundingtree']['funder']['id']:"";
                    value.funderName = (resData['fundingtree']['funder']['shortname'] )?resData['fundingtree']['funder']['shortname']:"";
                    value.jurisdiction = (resData['fundingtree']['funder']['jurisdiction'] )?resData['fundingtree']['funder']['jurisdiction']:"";
                    if(resData['fundingtree']['funding_level_2']){
                      value.fundingLevel0 = (resData['fundingtree']['funding_level_2'] && resData['fundingtree']['funding_level_2']['parent'] &&
                       resData['fundingtree']['funding_level_2']['parent']['funding_level_1'] && resData['fundingtree']['funding_level_2']['parent']['funding_level_1']['parent']
                     && resData['fundingtree']['funding_level_2']['parent']['funding_level_1']['parent']['funding_level_0'])?
                      resData['fundingtree']['funding_level_2']['parent']['funding_level_1']['parent']['funding_level_0']['name']:"";
                    }else if(resData['fundingtree']['funding_level_1']){
                      value.fundingLevel0 = (resData['fundingtree']['funding_level_1'] && resData['fundingtree']['funding_level_1']['parent'] && resData['fundingtree']['funding_level_1']['parent']['funding_level_0'])?
                      resData['fundingtree']['funding_level_1']['parent']['funding_level_0']['name']:"";
                    }else if(resData['fundingtree']['funding_level_0']){
                      value.fundingLevel0 = (resData['fundingtree']['funding_level_0']  )?resData['fundingtree']['funding_level_0']['name']:"";
                    }else {
                      value.fundingLevel0="";
                    }
                  }

                  if(resData.hasOwnProperty("startdate")) {
                    value.startDate = resData.startdate.split('-')[0];
                  }
                  if(resData.hasOwnProperty("enddate")) {
                    value.endDate = resData.enddate.split('-')[0];
                  }

             }
            //  console.info("add:"+value.label+"   "+value.id);

              array.push(value);
        }
        if(array.length == 0){
          array.push({id:'-1',label:'No results found'});
        }
        //console.info("Parsing results.... Size:"+array.length);

        return array;
    }

    private handleError (error: HttpErrorResponse) {
      // in a real world app, we may send the error to some remote logging infrastructure
      // instead of just logging it to the console
      console.log(error);
      return throwError(error  || 'Server error');
    }
}
