import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {EnvProperties} from '../../../utils/properties/env-properties';
import {ClaimEntity, ClaimResult} from '../claimHelper.class';
import {map} from "rxjs/operators";
import {StringUtils} from "../../../utils/string-utils.class";
import {properties} from "../../../../../environments/environment";


@Injectable()
export class SearchOrcidService {
  constructor( private http: HttpClient ) {}


  searchOrcidAuthor(term: string, authorIds: string[], authors, properties: EnvProperties, addId): any {

    //var headers = new Headers();
    //headers.append('Accept', 'application/orcid+json');
    let headers = new HttpHeaders({'Accept': 'application/orcid+json'});

    let url = properties.searchOrcidURL + term + '/record';

    return this.http.get(url, { headers: headers })
      //.map(res => res.json()['person'])
      .pipe(map(res => res['person']))
      .pipe(map(res => [res['name']['given-names'],
        res['name']['family-name'],
        res['name'], res['name']['institution-name']]))

      .pipe(map(res => SearchOrcidService.parseOrcidAuthor(res, authorIds, authors, addId)));
  }
  searchOrcidSingleAuthor(term: string, properties: EnvProperties, addId): any {

    //var headers = new Headers();
    //headers.append('Accept', 'application/orcid+json');
    let headers = new HttpHeaders({'Accept': 'application/orcid+json'});

    let url ="https://pub.orcid.org/v3.0/expanded-search/?q=orcid:" + term + '&start=0&rows=50';
    return this.http.get(url, {headers: headers})
      .pipe(map(res => res['expanded-result']))
      .pipe(map(res => {
        if(res) {
          for (let auth_result of res) {
            const author = {};
            author['id'] = auth_result['orcid-id'];
            author['authorGivenName'] = auth_result['given-names'];
            author['authorFamilyName'] = auth_result['family-names'];
            author['institutions'] = auth_result['institution-name'];
            return author;
          }
        }
        return null;

      }));
  }
  searchOrcidAuthors(term: string,
                     properties: EnvProperties): any {

    let headers = new HttpHeaders({'Accept': 'application/orcid+json'});

    // let url = properties.searchOrcidURL+'search?defType=edismax&q='+term+'&qf=given-name^1.0+family-name^2.0+other-names^1.0+credit-name^1.0&start=0&rows=10';
    let url = properties.searchOrcidURL+'search?q='+StringUtils.URIEncode('{!edismax qf="given-and-family-names^50.0 family-name^10.0 given-names^5.0 credit-name^10.0 other-names^5.0 text^1.0" pf="given-and-family-names^50.0" mm=1}')+term+'&start=0&rows=10';

    //q={!edismax qf="given-and-family-names^50.0 family-name^10.0 given-names^5.0 credit-name^10.0 other-names^5.0 text^1.0" pf="given-and-family-names^50.0" mm=1}alessia bardi&start=0&rows=10
    let key = url;
    return this.http.get(url, {headers: headers})
      .pipe(map(res => res['result']))
      .pipe(map(res => SearchOrcidService.parseOrcidAuthors(res)));

  }

  searchOrcidAuthorsNew(term: string,
                        properties: EnvProperties, size = 10): any {
    let headers = new HttpHeaders({'Accept': 'application/orcid+json'});
    // let url = properties.searchOrcidURL+'search?defType=edismax&q='+term+'&qf=given-name^1.0+family-name^2.0+other-names^1.0+credit-name^1.0&start=0&rows=10';
    let url = /*properties.searchOrcidURL +*/ 'https://pub.orcid.org/v3.0/expanded-search?q=' + StringUtils.URIEncode('{!edismax qf="given-and-family-names^50.0 family-name^10.0 given-names^10.0 credit-name^10.0 other-names^5.0 text^1.0" pf="given-and-family-names^50.0" bq="current-institution-affiliation-name:[* TO *]^100.0 past-institution-affiliation-name:[* TO *]^70" mm=1}') + term + '&start=0&rows=' + size;
    // given-and-family-names^50.0 family-name^10.0 given-names^10.0 credit-name^10.0 other-names^5.0 text^1.0" pf="given-and-family-names^50.0" bq="current-institution-affiliation-name:[* TO *]^100.0 past-institution-affiliation-name:[* TO *]^70" mm=1}
    // https://pub.orcid.org/v3.0/expanded-search/?q=%7B!edismax%20qf%3D%22given-and-family-names%5E50.0%20family-name%5E10.0%20given-names%5E10.0%20credit-name%5E10.0%20other-names%5E5.0%20text%5E1.0%22%20pf%3D%22given-and-family-names%5E50.0%22%20bq%3D%22current-institution-affiliation-name%3A%5B*%20TO%20*%5D%5E100.0%20past-institution-affiliation-name%3A%5B*%20TO%20*%5D%5E70%22%20mm%3D1%7Dpaolo%20manghi&start=0&rows=50

    //q={!edismax qf="given-and-family-names^50.0 family-name^10.0 given-names^5.0 credit-name^10.0 other-names^5.0 text^1.0" pf="given-and-family-names^50.0" mm=1}alessia bardi&start=0&rows=10
    let key = url;
    return this.http.get(url, {headers: headers})
      .pipe(map(res => res['expanded-result']))
      .pipe(map(res => {
        let authors = [];
        if(res) {
          for (let auth_result of res) {
            const author = {};
            author['id'] = auth_result['orcid-id'];
            author['authorGivenName'] = auth_result['given-names'];
            author['authorFamilyName'] = auth_result['family-names'];
            author['institutions'] = auth_result['institution-name'];
            authors.push(author);
          }
        }
        return authors;

      }));
  }

  searchOrcidPublications(id: string, properties: EnvProperties, parse: boolean = false): any {
    let headers = new HttpHeaders({'Accept': 'application/orcid+json'});
    let url = properties.searchOrcidURL + id + '/works';
    return this.http.get(url, { headers: headers })
      .pipe(map(res => res['group']))
      .pipe(map(request => (parse ? SearchOrcidService.parse(id, request) : request)));
  }


  static parseOrcidAuthor(data: any, authorIds: string[], authors, addId): any {
    console.log(data)
    if (data[2] != null) {
      if (addId) {
        authorIds.push(data[2].path);
      }
      const author = {};
      author['id'] = data[2].path;
      if (data[0] != null) {
        author['authorGivenName'] = data[0].value;
      } else {
        author['authorGivenName'] = "";
      }
      if (data[1] != null) {
        author['authorFamilyName'] = data[1].value;
      } else {
        author['authorFamilyName'] = "";
      }
      if (data[3] != null) {
        author['institution'] = data[3];
      }
      console.log(author['institution'])
      authors.push(author);

      return true;
    }
    return false;
  }

  static parseOrcidAuthors(data: any): any {
    let mydata: any;
    let length: number;
    let authorIds: string[] = [];
    if (data != null) {
      length = data.length != undefined ? data.length : 1;
      for (let i = 0; i < length; i++) {
        mydata = data.length != undefined ? data[i] : data;
        if (mydata.hasOwnProperty("orcid-identifier")) {
          authorIds.push(mydata['orcid-identifier'].path);
        }
      }
    }
    return authorIds;
  }

  static parse(authorId, response): ClaimEntity[] {
    const results: ClaimEntity[] = [];
    for (let i = 0; i < response.length; i++) {
      let item = response[i];
      const entity: ClaimEntity = new ClaimEntity();
      entity.result = new ClaimResult();
      entity.result.DOI = null;
      entity.result.url = null;
      entity.result.publisher = null;
      entity.result.journal = null;
      if (item['work-summary'] && item['work-summary'].length > 0) {
        item = item['work-summary'][0];
      } else {
        item = item['work-summary'];
      }
      let handleId = null;
      if (item['external-ids'] && item['external-ids']['external-id']) {
        for (let j = 0; j < item['external-ids']['external-id'].length; j++) {
          const id = item['external-ids']['external-id'][j];
          if (id['external-id-type'] == "doi") {
            entity.result.DOI = id['external-id-value'];
            entity.result.url = properties.doiURL + entity.result.DOI;
            break;
          }else if (id['external-id-type'] == "handle" && !handleId) {
            handleId= id['external-id-value'];
            break;
          }
        }
      }
      if(!entity.result.url && handleId){
        entity.result.url =  handleId;

      }
      entity.id = authorId + "-" + item['put-code'];
      if (item.title && item.title.title) {
        entity.title = item['title']['title'].value;
      }
      entity.result.journal = item['journal-title'];
      entity.result.source = 'orcid';
      entity.type = 'publication';
      if (item['publication-date'] && item['publication-date']['year']) {
        entity.result.date = item['publication-date']['year'].value
      }
      entity.result.accessRights = "OPEN";
      if (item.publisher) {
        entity.result.publisher = item.publisher;
      }
      entity.result.authors = [];
      entity.result.record = item;
      results.push(entity);
    }
    return results;
  }
}
