import {Component, Input, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {EnvProperties} from '../../utils/properties/env-properties';
import {ClaimEntity, ClaimProject, ShowOptions} from '../claim-utils/claimHelper.class';
import {EntitiesSearchService} from '../../utils/entitiesAutoComplete/entitySearch.service';
import {SearchResearchResultsService} from '../../services/searchResearchResults.service';
import {LinkingGenericComponent} from "../linking/linkingGeneric.component";
import {ClaimResultSearchFormComponent} from "../claim-utils/claimResultSearchForm.component";
import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {StringUtils} from "../../utils/string-utils.class";
import {ClaimProjectsSearchFormComponent} from "../claim-utils/claimProjectSearchForm.component";


@Component({
  selector: 'directLinking',
  templateUrl: 'directLinking.component.html'
})
export class DirectLinkingComponent {
  @ViewChild(LinkingGenericComponent) linking: LinkingGenericComponent;

  results: ClaimEntity[] = [];

  // linkType: string = "project"; // link type (selected in home page) : project, context, software, etc
  /* url Parameters for inline linking */
  id: string = null; //entity id
  type: string = null; // entity type (publication or dataset)
  // linkTo: string = null; // entity type (project or context or entity)
  // linkToEntities: string[] = [];
  showOptions:ShowOptions = new ShowOptions();
  validEntityTypes = ["dataset", "publication", "software", "other", "project", "context"];
  sources: ClaimEntity[] = [];
  inlineEntity: ClaimEntity = null;
  validInput: boolean = null;//'true;
  properties: EnvProperties;
  @Input() communityId: string = null;
  localStoragePrefix: string = "";
  constructor(private _router: Router, private route: ActivatedRoute,private entitySearch:EntitiesSearchService,
              private _searchResearchResultsService: SearchResearchResultsService) {}
  subscriptions = [];
  ngOnDestroy() {
    this.subscriptions.forEach(subscription => {
      if (subscription instanceof Subscriber) {
        subscription.unsubscribe();
      }
    });
  }
  ngOnInit() {
    this.properties = properties;

    this.subscriptions.push(this.route.queryParams.subscribe(params => {
      this.id = params['id'];
      this.type = params['type'];
      this.showOptions.linkTo = params['linkTo'];
      if (this.type != null && this.showOptions.linkTo != null) {
        this.type = (this.validEntityTypes.indexOf(this.type) != -1) ? this.type : 'publication';
        this.showOptions.linkTo = (this.validEntityTypes.indexOf(this.showOptions.linkTo) != -1 || this.showOptions.linkTo == "result") ? this.showOptions.linkTo : 'project';
        this.localStoragePrefix = (this.communityId ? (this.communityId + "_") : '') + this.type.substr(0, 3) + "_" + this.showOptions.linkTo.substr(0, 3) + "_";

        if (localStorage.getItem(this.localStoragePrefix + "results")) {
          this.results = JSON.parse(localStorage.getItem(this.localStoragePrefix + "results"));
        }
        if (localStorage.getItem(this.localStoragePrefix + "sources")) {
          this.sources = JSON.parse(localStorage.getItem(this.localStoragePrefix + "sources"));
        }
        //console.log("\n\nGetting inline entity "+this.type+"\n\n");
        if (this.type == "project") {
          // this.linkType = "project";
          this.getProjectById(this.id);
        } else if (this.type == "publication") {
          this.getResearchResultById("publication", this.id);
        } else if (this.type == "dataset") {
          this.getResearchResultById("dataset", this.id);
        } else if (this.type == "software") {
          this.getResearchResultById("software", this.id);
        } else if (this.type == "other") {
          this.getResearchResultById("other", this.id);
        } else {
          this.validInput = this.isValidInput(null);
        }
        //set which entities it is allowed to link to.
        // add first the
        if(this.type == "project"){
          this.showOptions.linkToEntities = ["result"];
          this.showOptions.linkTo = "result";
        }else{
          // entity type (project or context or entity)
          if(this.showOptions.linkTo == "project"){
            this.showOptions.linkToEntities = ["project","context" ,"result"];
          }else if(this.showOptions.linkTo == "context"){
            this.showOptions.linkToEntities = ["context","project", "result" ];
          }else{
            this.showOptions.linkTo = "result";
            this.showOptions.linkToEntities = ["result","project","context" ];
          }

        }

      } else {
        this.validInput = this.isValidInput(null);

      }

    }));
  }

  isValidInput(result: ClaimEntity) {
    if (result == null) {
      return false;
    } else if (this.type == "project" && this.showOptions.linkTo != "result") {
      return false;
    } else if (["dataset", "publication", "software", "other"].indexOf(this.type) != -1 && (["project", "context", "result"].indexOf(this.showOptions.linkTo) == -1)) {
      return false;
    } else if (["project", "dataset", "publication", "software", "other"].indexOf(this.type) == -1) {
      return false;
    } else {
      return true;
    }
  }

  getProjectById(id: string) {
    this.subscriptions.push(this.entitySearch.fetchByType(id,"project", this.properties).subscribe(
      data => {
        this.createClaimEntity(data, "project");
      },
      err => {
        this.validInput = this.isValidInput(null);
        //console.log("An error occured")
        this.handleError("Error getting project by id: " + id, err);
      }));
  }

  getResearchResultById(resultType: string, id: string) {
    this.subscriptions.push(this._searchResearchResultsService.searchById(resultType, id, this.properties).subscribe(data => {
        this.createClaimEntity(data, resultType);
      },
      err => {
        this.validInput = this.isValidInput(null);
        //console.log("An error occured")
        this.handleError("Error getting "+this.getEntityName(resultType, false)+" by id: " + id, err);
      }));
  }

  createClaimEntity(data, type: string) {
    let results: ClaimEntity[] =[] ;
     if(type =="project"){
       let project = data[0];
       let entity:ClaimEntity = new ClaimEntity();
       entity.id = project.id;
       entity.type = "project";
       entity.title = project.projectName;
       entity.project = new ClaimProject();
       entity.project.url = properties.searchLinkToProject + entity.id;
       entity.project.acronym = project.projectAcronym;
       entity.project.code = project.code;
       entity.project.endDate = project.endDate;
       entity.project.funderId = project.funderId;
       entity.project.funderName = project.funderName;
       entity.project.fundingLevel0 = project.fundingLevel0;
       entity.project.jurisdiction = project.jurisdiction;
       entity.project.startDate = project.startDate;
       this.inlineEntity = entity;
     }else{
      results = ClaimResultSearchFormComponent.openaire2ClaimResults(data, this.properties);
     }

    if (results.length > 0) {
      this.inlineEntity = results[0]
    }
    this.validInput = this.isValidInput(this.inlineEntity);
  }

  private handleError(message: string, error) {
    console.error("Direct Linking Page: " + message, error);
  }

  private getEntityName (entityType:string, plural:boolean) {
    return StringUtils.getEntityName(entityType, plural);
  }
}
