import {ChangeDetectorRef, Component, ElementRef, Input, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Meta, Title} from '@angular/platform-browser';


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

import {DataProviderInfo} from '../../utils/entities/dataProviderInfo';
import {DataProviderService} from './dataProvider.service';
import {FetchResearchResults} from '../../utils/fetchEntitiesClasses/fetchResearchResults.class';
import {SearchResearchResultsService} from '../../services/searchResearchResults.service';
import {FetchProjects} from '../../utils/fetchEntitiesClasses/fetchProjects.class';
import {SearchProjectsService} from '../../services/searchProjects.service';
import {FetchDataproviders} from '../../utils/fetchEntitiesClasses/fetchDataproviders.class';
import {SearchDataprovidersService} from '../../services/searchDataproviders.service';
import {ErrorCodes} from '../../utils/properties/errorCodes';
import {RouterHelper} from '../../utils/routerHelper.class';
import {PiwikService} from '../../utils/piwik/piwik.service';
import {SEOService} from '../../sharedComponents/SEO/SEO.service';
import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {HelperService} from "../../utils/helper/helper.service";
import {Location} from "@angular/common";
import {Identifier, StringUtils} from "../../utils/string-utils.class";
import {SearchResult} from "../../utils/entities/searchResult";
import {ResultPreview} from "../../utils/result-preview/result-preview";
import {IndexInfoService} from "../../utils/indexInfo.service";
import {properties} from "../../../../environments/environment";
import {Subscriber, Subscription, zip} from "rxjs";
import {OpenaireEntities} from "../../utils/properties/searchFields";
import {MetricsService} from '../../services/metrics.service';
import {NumberUtils} from '../../utils/number-utils.class';
import {LayoutService} from '../../dashboard/sharedComponents/sidebar/layout.service';
import {FullScreenModalComponent} from '../../utils/modal/full-screen-modal/full-screen-modal.component';

declare var ResizeObserver;

@Component({
  selector: 'dataprovider',
  templateUrl: 'dataProvider.component.html',

})

export class DataProviderComponent {
  public referrer: string;
  public prevPath: string;

  @Input() type: string = "dataprovider";
  private typeQueryPathParam: string = "datasources";
  @Input() communityId = null;
  public dataProviderInfo: DataProviderInfo;
  public datasourceId: string;
  public identifier: Identifier = null;
  public provenanceUrls: string[] = null;

  // Links for SEO
  public linkToLandingPage: string = null;
  public linkToSearchPage: string = null;
  public canonicalUrl: string = null;

  // Message variables
  public warningMessage = "";
  public errorMessage = "";
  public showLoading: boolean = true;

  // Metrics tab variables
  public metricsClicked: boolean;
  public viewsFrameUrl: string;
  public downloadsFrameUrl: string;
  /** @deprecated*/
  public totalViews: number = null;
  /** @deprecated*/
  public totalDownloads: number = null;
  public hasViews: boolean = false;
  public hasDownloads: boolean = false;
  // public pageViews: number;

  // Statistics tab variables
  public statsClicked: boolean = false;

  // @ViewChild('statisticsModal') statisticsModal;
  // @ViewChild('relatedDatasourcesModal') relatedDatasourcesModal;
  @ViewChild('addThisModal') addThisModal;
	@ViewChild('addThisFsModal') addThisFsModal: FullScreenModalComponent;

  // Variables for publications, research data, projects, datasources, related datasources tabs
  public fetchPublications: FetchResearchResults;
  public fetchDatasets: FetchResearchResults;
  public fetchSoftware: FetchResearchResults;
  public fetchOrps: FetchResearchResults;
  public fetchProjects: FetchProjects;
  public fetchDataproviders: FetchDataproviders;
  public fetchAggregatorsResults: FetchResearchResults;
  public searchNumber: number = 5;

  public aggregationStatusIsInitialized: boolean = false;

  public loadingRelatedDatasources: boolean = true;

  // Active tab variable for responsiveness - show tabs only if main request is completed
  public activeTab: string = "";
  public showTabs: boolean = false;

  public _numberOfTabs: number = 0;
  public tabsAreInitialized: boolean = false;

  public routerHelper: RouterHelper = new RouterHelper();
  public errorCodes: ErrorCodes = new ErrorCodes();
  public pageContents = null;
  public divContents = null;

  // Request results of each tab only the one time (first time tab is clicked)
  private reloadPublications: boolean = true;
  private reloadDatasets: boolean = true;
  private reloadSoftware: boolean = true;
  private reloadOrps: boolean = true;
  private reloadProjects: boolean = true;
  private reloadDataproviders: boolean = true;
  private reloadRelatedDatasources: boolean = true;

  // Organizations variables for view more/less functionality
  public viewAllOrganizations: boolean = false;
  public lessBtnOrganizations: boolean = false;
  public thresholdOrganizations: number = 20;
  @ViewChild('organizationsModal') organizationsModal;


  // Subjects variables for view more/less functionality
  public viewAllSubjects: boolean = false;
  public lessBtnSubjects: boolean = false;
  public thresholdSubjects: number = 20;
  @ViewChild('subjectsModal') subjectsModal;


  // Description variables for view more/less functionality
  public thresholdDescription: number = 670;
  public showNumDescription: number = 670;

  public indexUpdateDate: Date;
  public showFeedback: boolean = false;
  public feedbackFields: string [] = ['Name', 'Organizations', 'Country', 'Other'];

  public offset: number;
  public stickyHeader: boolean = false;
  public graph_offset: number = 0;
  public graph_height: number = 0;
  @ViewChild("graph_and_feedback") graph_and_feedback;

	@ViewChild("descriptionDiv") descriptionDiv: ElementRef;
	@ViewChild('descriptionModal') descriptionModal;

  // public shouldSticky: boolean = true;

  subscriptions = [];
	private sub: Subscription;
  properties: EnvProperties = properties;
  public openaireEntities = OpenaireEntities;

	public isMobile: boolean = false;
	public mobileContent: "info" | "metrics" | "actions" = "info";
	public tabMobile: string = "";
	public viewAllMobile: string = "";
	// Full screen modals for small screens (mobile)
	@ViewChild('summaryFsModal') summaryFsModal: FullScreenModalComponent;
	@ViewChild('projectsFsModal') projectsFsModal: FullScreenModalComponent;
	@ViewChild('dataprovidersFsModal') dataprovidersFsModal: FullScreenModalComponent;
	@ViewChild('publicationsFsModal') publicationsFsModal: FullScreenModalComponent;
	@ViewChild('datasetsFsModal') datasetsFsModal: FullScreenModalComponent;
	@ViewChild('softwareFsModal') softwareFsModal: FullScreenModalComponent;
	@ViewChild('otherFsModal') otherFsModal: FullScreenModalComponent;
	@ViewChild('relatedDatasourcesFsModal') relatedDatasourcesFsModal: FullScreenModalComponent;
	@ViewChild('statisticsFsModal') statisticsFsModal: FullScreenModalComponent;

  constructor(private _dataproviderService: DataProviderService,
              private _piwikService: PiwikService,
              private route: ActivatedRoute,
              private _meta: Meta,
              private _title: Title,
              private _router: Router,
              private _searchResearchResultsService: SearchResearchResultsService,
              private _searchProjectsService: SearchProjectsService,
              private _searchDataprovidersService: SearchDataprovidersService,
              private seoService: SEOService,
              private helper: HelperService,
              private _location: Location,
              private indexInfoService: IndexInfoService,
							private metricsService: MetricsService,
              private cdr: ChangeDetectorRef,
							private layoutService: LayoutService) {
    this.fetchPublications = new FetchResearchResults(this._searchResearchResultsService);
    this.fetchDatasets = new FetchResearchResults(this._searchResearchResultsService);
    this.fetchSoftware = new FetchResearchResults(this._searchResearchResultsService);
    this.fetchOrps = new FetchResearchResults(this._searchResearchResultsService);
    this.fetchProjects = new FetchProjects(this._searchProjectsService);
    this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService);

  }

  ngOnInit() {
		this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
      this.isMobile = isMobile;
    }));
    if (typeof document !== 'undefined') {
      this.subscriptions.push(this.indexInfoService.getLastIndexDate(this.properties).subscribe(lastIndexUpdate => {
        if (lastIndexUpdate) {
          this.indexUpdateDate = new Date(lastIndexUpdate);
        }
      }));
    }
    if(properties.adminToolsPortalType !== "explore") {
      //this.getDivContents();
      this.getPageContents();
    }
    this.updateUrl(this.properties.domain + this.properties.baseLink +  this._router.url);
    this.seoService.createLinkForCanonicalURL(this.properties.domain +this.properties.baseLink +  this._router.url);
    this.subscriptions.push(this.route.queryParams.subscribe(data => {
      this.stickyHeader = false;
      this.updateDescription("");

      if(data["return_path"]) {
        this.prevPath = data["return_path"] + (data["search_params"] ? ("?"+data["search_params"]) : "");
      }
      if((typeof document !== 'undefined') && document.referrer) {
        this.referrer = document.referrer;
      }

      // this.datasourceId = data['datasourceId'];
      if (data['datasourceId']) {
        this.datasourceId = data['datasourceId'];
        this.typeQueryPathParam = "datasources";
        this.initMetaAndLinks("dataprovider");
      } else if (data['serviceId']) {
        this.datasourceId = data['serviceId'];
        this.typeQueryPathParam = "services";
        this.initMetaAndLinks("service");
      } else if (data["pid"]) {
        this.identifier = Identifier.getIdentifierFromString(decodeURIComponent(data["pid"]), false);
        if(this.type == "service") {
          this.typeQueryPathParam = "services";
        }
        this.initMetaAndLinks(this.type);
      }
      if (this.datasourceId && StringUtils.isOpenAIREID(this.datasourceId) || (this.identifier)) {
        this.initializeValues();
        this.getDataProviderInfo(this.datasourceId);
      } else {
        this.showLoading = false;
        this._router.navigate([this.properties.errorLink], {
          queryParams: {
            "page": this._location.path(true),
            "page_type": this.type
          }
        });
      }
    }));
  }

  ngAfterViewInit() {
    if (typeof document !== 'undefined') {
      if(document.getElementById("main-menu")) {
        this.offset = Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--header-height'));
      } else {
        this.offset = 0;
      }
      // let bottom = document.getElementById('bottom');
      // if(bottom) {
      //   let observer = new IntersectionObserver(entries => {
      //     entries.forEach(entry => {
      //       this.shouldSticky = !entry.isIntersecting;
      //     })
      //   });
      //   this.subscriptions.push(observer);
      //   observer.observe(bottom);
      // }
      if(this.graph_and_feedback) {
        this.observeGraphAndFeedback();
      }
    }
  }

  ngAfterContentChecked() {
    if(this.graph_and_feedback && typeof document !== 'undefined') {
      this.graph_offset = this.calcGraphOffset(this.graph_and_feedback.nativeElement);
    }
  }

	get showViewMoreButton():boolean {
		return !!this.descriptionDiv && (this.descriptionDiv.nativeElement.clientHeight >= 10 * 21);
	}

  public observeGraphAndFeedback() {
    let resizeObs = new ResizeObserver(entries => {
      entries.forEach(entry => {
        setTimeout(() => {
          // console.log(entry);
          this.graph_offset = this.calcGraphOffset(entry.target);
          this.cdr.detectChanges();
        });
      })
    });
    this.subscriptions.push(resizeObs);
    resizeObs.observe(this.graph_and_feedback.nativeElement);
  }

  calcGraphOffset(element) {
    this.graph_height = element.offsetHeight;
    return window.innerHeight-this.graph_height;
  }

  private initMetaAndLinks(type: string) {
    if (type == "service") {
      this.type = "service";
      this.updateTitle(this.openaireEntities.SERVICE);
      this.linkToLandingPage = this.properties.searchLinkToService;
      this.linkToSearchPage = this.properties.searchLinkToServices;
    } else if (type == "dataprovider") {
      this.type = "dataprovider";
      this.updateTitle(this.openaireEntities.DATASOURCE);
      this.linkToLandingPage = this.properties.searchLinkToDataProvider;
      this.linkToSearchPage = this.properties.searchLinkToDataProviders;
    }
  }

  public initializeValues() {
    this._numberOfTabs = 0;
    this.tabsAreInitialized = false;
    this.dataProviderInfo = null;
    this.provenanceUrls = null;
    this.aggregationStatusIsInitialized = false;
    this.fetchProjects.searchUtils.status = this.errorCodes.LOADING;
    this.fetchProjects.searchUtils.totalResults = 0;
    this.fetchDataproviders.searchUtils.status = this.errorCodes.LOADING;
    this.fetchDataproviders.searchUtils.totalResults = 0;
    this.fetchPublications.searchUtils.status = this.errorCodes.LOADING;
    this.fetchPublications.searchUtils.totalResults = 0;
    this.fetchDatasets.searchUtils.status = this.errorCodes.LOADING;
    this.fetchDatasets.searchUtils.totalResults = 0;
    this.fetchSoftware.searchUtils.status = this.errorCodes.LOADING;
    this.fetchSoftware.searchUtils.totalResults = 0;
    this.fetchOrps.searchUtils.status = this.errorCodes.LOADING;
    this.fetchOrps.searchUtils.totalResults = 0;
    this.statsClicked = false;
    this.metricsClicked = false;
  }

  private getPageContents() {
    this.subscriptions.push(this.helper.getPageHelpContents(this.properties, this.communityId, this._router.url).subscribe(contents => {
      this.pageContents = contents;
    }));
  }

  private getDivContents() {
    this.subscriptions.push(this.helper.getDivHelpContents(this.properties, this.communityId, this._router.url).subscribe(contents => {
      this.divContents = contents;
    }));
  }

  ngOnDestroy() {
    this.subscriptions.forEach(subscription => {
      if (subscription instanceof Subscriber) {
        subscription.unsubscribe();
      } else if ((typeof ResizeObserver != 'undefined' && subscription instanceof ResizeObserver) ||
          (typeof IntersectionObserver != 'undefined' && subscription instanceof IntersectionObserver)) {
        subscription.disconnect();
      }
    });
    this.fetchDatasets.clearSubscriptions();
    this.fetchPublications.clearSubscriptions();
    this.fetchSoftware.clearSubscriptions();
    this.fetchPublications.clearSubscriptions();
    this.fetchDataproviders.clearSubscriptions();
    this.fetchProjects.clearSubscriptions();
  }

  private getDataProviderInfo(id: string) {
    this.warningMessage = '';
    this.errorMessage = "";
    this.showLoading = true;

    this.dataProviderInfo = null;
    this.provenanceUrls = null;

    this.showTabs = false;
    if ((this.datasourceId == null || this.datasourceId == '') && this.identifier == null) {
      this.showLoading = false;
      this.warningMessage = "No valid "+this.getTypeName()+" id";
    } else {
      this.subscriptions.push(this._dataproviderService.getDataproviderInfo(this.datasourceId, this.identifier, this.properties, this.typeQueryPathParam).subscribe(
        data => {
          this.dataProviderInfo = data;
          this.getProvenanceUrls();
          this.datasourceId = this.dataProviderInfo.objIdentifier;
          let pid:Identifier = Identifier.getPIDFromIdentifiers(this.dataProviderInfo.identifiers);
          this.canonicalUrl = this.properties.domain+ properties.baseLink  + ( pid ? (this.linkToLandingPage.split("?")[0] + "?pid=" + encodeURIComponent(pid.id)):
            (this.linkToLandingPage + this.dataProviderInfo.relcanId));
          this.seoService.createLinkForCanonicalURL(this.canonicalUrl);
          this.updateUrl(this.canonicalUrl);
          this.seoService.createLinkForCanonicalURL(this.properties.domain +this.properties.baseLink +  this._router.url);
          if (typeof document !== 'undefined') {
            // this.getDataProviderAggregationStatus(this.dataProviderInfo.originalId);
            this.getCollectedFulltexts();
            this.countResultsWithFundingInfo();
          } else {
            this.aggregationStatusIsInitialized = true;
          }
          if (typeof document !== 'undefined') {
            this.initTabs();
          }
          this.showTabs = true;
          this.updateTitle(this.dataProviderInfo.title.name?this.dataProviderInfo.title.name:this.dataProviderInfo.officialName);
          this.updateDescription((this.dataProviderInfo.description ? (this.dataProviderInfo.description.substr(0,157)  + (this.dataProviderInfo.description.substr(0,157).length == 157?"...":"")) : (this.dataProviderInfo.title.name?this.dataProviderInfo.title.name:this.dataProviderInfo.officialName)));
          this.subscriptions.push(this._piwikService.trackView(this.properties, this.dataProviderInfo.title.name).subscribe());

          this.showLoading = false;

          this.hasViews = false;
          this.hasDownloads = false;

          // ensure that if the API call to index does not have metrics, we get them from old metrics service call
          if(this.dataProviderInfo && !this.dataProviderInfo.measure) {
            this.getMetrics();
          } else if(this.dataProviderInfo && this.dataProviderInfo.measure && this.dataProviderInfo.measure.counts) {
            this.dataProviderInfo.measure.counts.forEach(measure => {
              if(measure.name == "views" && measure.value > 0) {
                this.hasViews = true;
              }
              if(measure.name == "downloads" && measure.value > 0) {
                this.hasDownloads = true;
              }
            });
          }
          this.cdr.detectChanges();

          // if (this.dataProviderInfo.tabs != undefined && this.dataProviderInfo.tabs.length > 0) {
          //   this.activeTab = this.dataProviderInfo.tabs[0].name;
          // }
        },
        err => {
          //console.log(err);
          this.handleError("Error getting " + this.type + " for " + (this.datasourceId ? ("id: " + this.datasourceId) : ("pid: " + this.identifier.id)), err);
          if (err.status == 404) {
            this._router.navigate([this.properties.errorLink], {
              queryParams: {
                "page": this._location.path(true),
                "page_type": this.type
              }
            });
          }else if(err.name == "TimeoutError"){
            this.errorMessage = 'An error occurred please try again later';
          }else {
            this.errorMessage = 'No '+this.getTypeName()+' found';
            this.seoService.createLinkForCanonicalURL(this.properties.domain + this.properties.baseLink + this.linkToSearchPage);
          }
          this.showLoading = false;
        }
      ));
    }
  }

  // private getDataProviderAggregationStatus(originalId: string) {
  //   this.subscriptions.push(this._dataproviderService.getDataproviderAggregationStatus(originalId, this.properties).subscribe(
  //     data => {
  //       this.dataProviderInfo.aggregationStatus = data;
  //       this.aggregationStatusIsInitialized = true;
  //     },
  //     err => {
  //       //console.log(err);
  //       this.aggregationStatusIsInitialized = true;
  //       this.handleError("Error getting "+this.getTypeName()+" aggregation status for id: " + this.datasourceId, err);
  //     }
  //   ));
  // }

  private getCollectedFulltexts() {
    this.subscriptions.push(this._dataproviderService.getCollectedFulltexts(this.datasourceId).subscribe(
      (data: string) => {
        this.dataProviderInfo.aggregationStatus = {"fulltexts": data};
        this.aggregationStatusIsInitialized = true;
      },
      err => {
        //console.log(err);
        this.aggregationStatusIsInitialized = true;
        this.handleError("Error getting "+this.getTypeName()+" collected fulltexts for id: " + this.datasourceId, err);
      }
    ));
  }

  private countResultsWithFundingInfo() {
    this.subscriptions.push(this._searchResearchResultsService.countCollectedResultsWithFundingInfo(this.datasourceId).subscribe(
      fundedContent => {
        this.dataProviderInfo.fundedContent = fundedContent;
        // console.log(this.dataProviderInfo.fundedContent);
      },
      err => {
        this.handleError("Error getting results with funding information for datasource id: " + this.datasourceId, err);
      }
    ))
  }

  private updateDescription(description: string) {
    // this._meta.updateTag({content: description.substring(0, 160)}, "name='description'");
    // this._meta.updateTag({content: description.substring(0, 160)}, "property='og:description'");

    this._meta.updateTag({content: description}, "name='description'");
    this._meta.updateTag({content: description}, "property='og:description'");
  }

  private updateTitle(title: string) {
    var _prefix = "";
    // if(this.communityId) {
    //   _prefix = "OpenAIRE | ";
    // }
    // var _title = _prefix + ((title.length > 50) ? title.substring(0, 50) : title);
    this._title.setTitle(title);
    this._meta.updateTag({content: title}, "property='og:title'");
  }

  private updateUrl(url: string) {
    this._meta.updateTag({content: url}, "property='og:url'");
  }

  private initTabs() {

    //if (this.dataProviderInfo.tabs != undefined && this.dataProviderInfo.tabs.length > 0) {
    this.reloadPublications = true;
    this.reloadDatasets = true;
    this.reloadSoftware = true;
    this.reloadOrps = true;
    this.reloadProjects = true;
    this.reloadDataproviders = true;
    this.reloadRelatedDatasources = true;
    this.statsClicked = false;

    //this.search(this.dataProviderInfo.tabs[0].content, 1, 10);
    this.count(1, 0);

    this.metricsClicked = false;
    //old
    // this.viewsFrameUrl = this.properties.framesAPIURL + 'merge.php?com=query&data=[{"query":"dtsrcRepoViews","dtsrcName":"' + this.datasourceId + '","table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":"","color":"","type":"chart","size":200,"sort":"xaxis","xStyle":{"r":-30,"s":"6","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[]}]&info_types=["column"]&stacking=&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false';
    // this.downloadsFrameUrl = this.properties.framesAPIURL + 'merge.php?com=query&data=[{"query":"dtsrcRepoDownloads","dtsrcName":"' + this.datasourceId + '","table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":"","color":"","type":"chart","size":200,"sort":"xaxis","xStyle":{"r":-30,"s":"6","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[]}]&info_types=["column"]&stacking=&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false';
    //new
    this.viewsFrameUrl = this.properties.statisticsFrameNewAPIURL + 'chart?json='  + encodeURIComponent('{"library":"HighCharts","chartDescription":{"queries":[{"name":"Monthly views","type":"column","query":{"name":"usagestats.views.monthly", "parameters":["' + this.datasourceId + '"], "profile":"OpenAIRE All-inclusive" }}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"Monthly views"},"subtitle":{},"yAxis":{"title":{"text":""}},"xAxis":{"title":{}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":false},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":false},"credits":{"href":null,"enabled":true,"text":""}}}');
    this.downloadsFrameUrl = this.properties.statisticsFrameNewAPIURL + 'chart?json='  +
      encodeURIComponent('{"library":"HighCharts","chartDescription":{"queries":[{"name":"Monthly downloads","type":"column","query":{"name":"usagestats.downloads.monthly", "parameters":["' + this.datasourceId + '"], "profile":"OpenAIRE All-inclusive" }}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"Monthly downloads"},"subtitle":{},"yAxis":{"title":{"text":""}},"xAxis":{"title":{}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":false},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":false},"credits":{"href":null,"enabled":true,"text":""}}}');
    this.fetchAggregatorsResults = new FetchResearchResults(this._searchResearchResultsService);

  }

  public getParamsForSearchLink(type: string = "") {

    if (type) {
      return this.routerHelper.createQueryParams(['f0', 'fv0', 'f1', 'fv1', 'type', 'qf', 'sortBy'], ["collectedfromdatasourceid", this.datasourceId, "resulthostingdatasourceid,or", this.datasourceId, type, "false", 'resultdateofacceptance,descending']);
    } else {
      return this.routerHelper.createQueryParams(['f0', 'fv0', 'f1', 'fv1'], ["collectedfromdatasourceid", this.datasourceId, "resulthostingdatasourceid,or", this.datasourceId]);
    }
  }

  private count(page: number, size: number) {

    this.countPublications(page, size);
    this.countDatasets(page, size);
    this.countSoftware(page, size);
    this.countOrps(page, size);
    this.countProjects(page, size);
    this.countDatasources(page, size);

  }

  public search(content: string, page: number, size: number) {
    if (content == 'publicationsTab') {
      this.searchPublications(page, size);
    } else if (content == 'datasetsTab') {
      this.searchDatasets(page, size);
    } else if (content == 'softwareTab') {
      this.searchSoftware(page, size);
    } else if (content == 'orpsTab') {
      this.searchOrps(page, size);
    } else if (content == 'projectsTab') {
      this.searchProjects(page, size);
    } else if (content == 'datasourcesTab') {
      this.searchDatasources(page, size);
    } else if (content == 'relatedDatasourcesTab') {
      this.searchRelatedDatasources(1, 0);
    } else if (content == 'metricsTab') {
      this.metricsClicked = true;
    } else if (content == 'statisticsTab') {
      this.statsClicked = !this.statsClicked;
    }
  }

  private searchPublications(page: number, size: number) {
    if (this.reloadPublications &&
      (this.fetchPublications.searchUtils.status == this.errorCodes.LOADING ||
        (this.fetchPublications.searchUtils.status == this.errorCodes.DONE && this.fetchPublications.searchUtils.totalResults > 0)
      )
    ) {
      this.fetchPublications.getResultsForDataproviders("publication", this.datasourceId, this.dataProviderInfo.resultsBy, page, size, this.properties);
    }
    this.reloadPublications = false;
  }

  private countPublications(page: number, size: number) {
    this.fetchPublications.getResultsForDataproviders("publication", this.datasourceId, this.dataProviderInfo.resultsBy, page, size, this.properties);
  }

  private searchDatasets(page: number, size: number) {
    if (this.reloadDatasets &&
      (this.fetchDatasets.searchUtils.status == this.errorCodes.LOADING ||
        (this.fetchDatasets.searchUtils.status == this.errorCodes.DONE && this.fetchDatasets.searchUtils.totalResults > 0)
      )
    ) {
      this.fetchDatasets.getResultsForDataproviders("dataset", this.datasourceId, this.dataProviderInfo.resultsBy, page, size, this.properties);
    }
    this.reloadDatasets = false;
  }

  private countDatasets(page: number, size: number) {
    this.fetchDatasets.getResultsForDataproviders("dataset", this.datasourceId, this.dataProviderInfo.resultsBy, page, size, this.properties);
  }

  private searchSoftware(page: number, size: number) {
    if (this.reloadSoftware &&
      (this.fetchSoftware.searchUtils.status == this.errorCodes.LOADING ||
        (this.fetchSoftware.searchUtils.status == this.errorCodes.DONE && this.fetchSoftware.searchUtils.totalResults > 0)
      )
    ) {
      this.fetchSoftware.getResultsForDataproviders("software", this.datasourceId, this.dataProviderInfo.resultsBy, page, size, this.properties);
    }
    this.reloadSoftware = false;
  }

  private countSoftware(page: number, size: number) {
    this.fetchSoftware.getResultsForDataproviders("software", this.datasourceId, this.dataProviderInfo.resultsBy, page, size, this.properties);
  }

  private searchOrps(page: number, size: number) {
    if (this.reloadOrps &&
      (this.fetchOrps.searchUtils.status == this.errorCodes.LOADING ||
        (this.fetchOrps.searchUtils.status == this.errorCodes.DONE && this.fetchOrps.searchUtils.totalResults > 0)
      )
    ) {
      this.fetchOrps.getResultsForDataproviders("other", this.datasourceId, this.dataProviderInfo.resultsBy, page, size, this.properties);
    }
    this.reloadOrps = false;
  }

  private countOrps(page: number, size: number) {
    this.fetchOrps.getResultsForDataproviders("other", this.datasourceId, this.dataProviderInfo.resultsBy, page, size, this.properties);
  }

  private searchProjects(page: number, size: number) {
    if (this.reloadProjects &&
      (this.fetchProjects.searchUtils.status == this.errorCodes.LOADING ||
        (this.fetchProjects.searchUtils.status == this.errorCodes.DONE && this.fetchProjects.searchUtils.totalResults > 0)
      )
    ) {
      this.fetchProjects.getResultsForDataproviders(this.datasourceId, page, size, this.properties);
    }
    this.reloadProjects = false;
  }

  private countProjects(page: number, size: number) {
    this.fetchProjects.getResultsForDataproviders(this.datasourceId, page, size, this.properties);
  }

  private searchDatasources(page: number, size: number) {
    if (this.reloadDataproviders &&
      (this.fetchDataproviders.searchUtils.status == this.errorCodes.LOADING ||
        (this.fetchDataproviders.searchUtils.status == this.errorCodes.DONE && this.fetchDataproviders.searchUtils.totalResults > 0)
      )
    ) {
      this.fetchDataproviders.getResultsForDataproviders(this.datasourceId, page, size, this.properties);
    }
    this.reloadDataproviders = false;
  }

  private countDatasources(page: number, size: number) {
    this.fetchDataproviders.getResultsForDataproviders(this.datasourceId, page, size, this.properties);
  }

  private searchRelatedDatasources(page: number, size: number) {
    // Currently no counting is done for this tab. Following condition is always false

    // if (this.reloadRelatedDatasources &&
    //   (this.fetchAggregatorsPublications.searchUtils.status == this.errorCodes.LOADING ||
    //     this.fetchAggregatorsPublications.searchUtils.status == this.errorCodes.DONE)
    //   &&
    //   (this.fetchAggregatorsDatasets.searchUtils.status == this.errorCodes.LOADING ||
    //     this.fetchAggregatorsDatasets.searchUtils.status == this.errorCodes.DONE)
    //   &&
    //   (this.fetchAggregatorsSoftware.searchUtils.status == this.errorCodes.LOADING ||
    //     this.fetchAggregatorsSoftware.searchUtils.status == this.errorCodes.DONE)
    //   &&
    //   (this.fetchAggregatorsOrps.searchUtils.status == this.errorCodes.LOADING ||
    //     this.fetchAggregatorsOrps.searchUtils.status == this.errorCodes.DONE)
    // ) {
    //   this.relatedDatasourcesSub = observableMerge(this.fetchAggregatorsPublications.requestComplete, this.fetchAggregatorsDatasets.requestComplete, this.fetchAggregatorsSoftware.requestComplete, this.fetchAggregatorsOrps.requestComplete)
    //     .subscribe(
    //       data => {
    //       },
    //       err => {
    //       },
    //       () => {
    //         this.preprocessRelatedDatasources();
    //       }
    //     );
    //
    //   this.fetchAggregatorsPublications.getAggregatorResults("publication", this.datasourceId, page, size, this.properties);
    //   this.fetchAggregatorsDatasets.getAggregatorResults("dataset", this.datasourceId, page, size, this.properties);
    //   this.fetchAggregatorsSoftware.getAggregatorResults("software", this.datasourceId, page, size, this.properties);
    //   this.fetchAggregatorsOrps.getAggregatorResults("other", this.datasourceId, page, size, this.properties);
    if (this.reloadRelatedDatasources &&
      (this.fetchAggregatorsResults.searchUtils.status == this.errorCodes.LOADING ||
        (this.fetchAggregatorsResults.searchUtils.status == this.errorCodes.DONE && this.fetchAggregatorsResults.searchUtils.totalResults > 0)
      )
    ) {
      this.subscriptions.push(this.fetchAggregatorsResults.requestComplete.subscribe(
        data => {
        },
        err => {
        },
        () => {
          //this.preprocessRelatedDatasources();
          this.dataProviderInfo.relatedDatasources = this.fetchAggregatorsResults.results;
          this.loadingRelatedDatasources = false;
        }
      ));

      this.fetchAggregatorsResults.getAggregatorResults("results", this.datasourceId, page, size, this.properties);
    } else {
      this.loadingRelatedDatasources = false;
    }


    this.reloadRelatedDatasources = false;
  }

  private countRelatedDatasources(page: number, size: number) {
    this.fetchAggregatorsResults.getAggregatorResults("results", this.datasourceId, page, size, this.properties);
  }

  public metricsResults($event) {
    this.totalViews = $event.totalViews;
    this.totalDownloads = $event.totalDownloads;
    // this.pageViews = $event.pageViews;
  }

	private getMetrics() {
		let obs;
		obs = zip(this.metricsService.getMetricsNumber(this.datasourceId, "usagestats.views.repository.local", this.properties),
          this.metricsService.getMetricsNumber(this.datasourceId, "usagestats.downloads.repository.local", this.properties));
		this.sub = obs.subscribe(data => {
      if((data[0] && data[0] > 0) || (data[1] && data[1] > 0)) {
        this.dataProviderInfo.measure = {counts: []};
        if(data[0] && data[0] > 0) {
          this.dataProviderInfo.measure.counts.push({name: 'views', order: 0, icon: 'visibility', value: data[0]});
          this.hasViews = true;
        }
        if(data[1] && data[1] > 0) {
          this.dataProviderInfo.measure.counts.push({name: 'downloads', order: 1, icon: 'downloads', value: data[1]});
          this.hasDownloads = true;
        }
        this.cdr.detectChanges();
      }
		});
	}

  public get hasMetrics(): boolean {
    // return !(this.totalViews != null && this.totalDownloads != null) || this.totalViews > 0 || this.totalDownloads > 0;
    // return (this.totalViews != null &&  this.totalViews > 0) || (this.totalDownloads != null && this.totalDownloads > 0);
    return this.dataProviderInfo.measure?.counts?.length > 0;
  }

  // public openStatistics() {
  //   this.statsClicked = true;
  //   this.statisticsModal.cancelButton = false;
  //   this.statisticsModal.okButton = false;
  //   this.statisticsModal.alertTitle = "Statistics of";
  //   this.statisticsModal.open();
  // }
  //
  // public openRelatedDatasources() {
  //   this.searchRelatedDatasources(1, 0);
  //   this.relatedDatasourcesModal.cancelButton = false;
  //   this.relatedDatasourcesModal.okButton = false;
  //   this.relatedDatasourcesModal.alertTitle = "Related "+this.openaireEntities.DATASOURCES+" of";
  //   this.relatedDatasourcesModal.open();
  // }

  public openAddThisModal() {
    this.addThisModal.cancelButton = false;
    this.addThisModal.okButton = false;
    this.addThisModal.alertTitle = "Share this "+OpenaireEntities.DATASOURCE+" in your social networks";
    this.addThisModal.open();
  }

  public viewAllOrganizationsClick() {
    this.viewAllOrganizations = true;
    if(this.dataProviderInfo.organizations.length <= this.thresholdOrganizations*2) {
      this.lessBtnOrganizations = true;
    } else {
			if(this.isMobile) {
				this.summaryFsModal.title += " - Organizations";
				this.summaryFsModal.back = true;
				this.viewAllMobile = "organizations";
			} else {
				this.openOrganizationsModal();
			}
    }
  }

  public openOrganizationsModal() {
    this.organizationsModal.cancelButton = false;
    this.organizationsModal.okButton = false;
    this.organizationsModal.alertTitle = this.openaireEntities.ORGANIZATIONS;
    this.organizationsModal.open();
  }

  public viewAllSubjectsClick() {
    this.viewAllSubjects = true;
    if(this.dataProviderInfo.subjects.length <= this.thresholdSubjects*2) {
      this.lessBtnSubjects = true;
    } else {
			if(this.isMobile) {
				this.summaryFsModal.title += " - Subjects";
				this.summaryFsModal.back = true;
				this.viewAllMobile = "subjects";
			} else {
				this.openSubjectsModal();
			}
    }
  }

  public openSubjectsModal() {
    this.subjectsModal.cancelButton = false;
    this.subjectsModal.okButton = false;
    this.subjectsModal.alertTitle = "Subjects";
    this.subjectsModal.open();
  }

  public scroll() {
    HelperFunctions.scroll();
  }

  public removeUnknown(array: string[]): string[] {
    return array.filter(value => value.toLowerCase() !== 'unknown');
  }

  private handleError(message: string, error) {
    console.error(this.getTypeName()+" Landing Page: " + message, error);
  }

  public getResultPreview(result: SearchResult, type: string): ResultPreview {
    return ResultPreview.searchResultConvert(result, type);
  }

  public onSelectActiveTab(activeTabId) {
    if (this.activeTab != activeTabId) {   // tab really changed
      if (activeTabId == 'summary') {
        this.activeTab = 'summary';
      } else if (activeTabId == 'publications') {
        this.activeTab = 'publications';
        this.searchPublications(1, this.searchNumber);
      } else if (activeTabId == 'datasets') {
        this.activeTab = 'datasets';
        this.searchDatasets(1, this.searchNumber);
      } else if (activeTabId == 'software') {
        this.activeTab = 'software';
        this.searchSoftware(1, this.searchNumber);
      } else if (activeTabId == 'other') {
        this.activeTab = "other";
        this.searchOrps(1, this.searchNumber);
      } else if (activeTabId == 'projects') {
        this.activeTab = "projects";
        this.searchProjects(1, this.searchNumber);
      } else if (activeTabId == 'datasources') {
        this.activeTab = "datasources";
        this.searchDatasources(1, this.searchNumber);
      } else if (activeTabId == 'relatedDatasources') {
        this.activeTab = "relatedDatasources";
        this.searchRelatedDatasources(1, 0);
      } else if (activeTabId == 'statistics') {
        this.activeTab = 'statistics';
        this.statsClicked = true;
      }
    }
  }

  public get hasAggregationStatusInfo(): boolean {
    // return (!!this.dataProviderInfo.aggregationStatus &&
    //   ((!!this.dataProviderInfo.aggregationStatus.fulltexts && parseInt(this.dataProviderInfo.aggregationStatus.fulltexts) != -1)
    //     || (!!this.dataProviderInfo.aggregationStatus.fundedContent && parseInt(this.dataProviderInfo.aggregationStatus.fundedContent) != -1)
    //     || !!this.dataProviderInfo.aggregationStatus.lastUpdateDate));
    return (!!this.dataProviderInfo.aggregationStatus &&
      ((!!this.dataProviderInfo.aggregationStatus.fulltexts && parseInt(this.dataProviderInfo.aggregationStatus.fulltexts) != -1)));
  }

  public get hasJournalInfo(): boolean {
    return (!!this.dataProviderInfo.journal && (
      !!this.dataProviderInfo.journal['journal'] || !!this.dataProviderInfo.journal['issn'] ||
      !!this.dataProviderInfo.journal['lissn'] || !!this.dataProviderInfo.journal['eissn'] ||
      !!this.dataProviderInfo.journal['volume'] || !!this.dataProviderInfo.journal['issue'] ||
      !!this.dataProviderInfo.journal['start_page'] || !!this.dataProviderInfo.journal['end_page']));
    //return true;
  }

  public get hasPrimaryInfo(): boolean {
    return !!this.dataProviderInfo && (
      (!!this.dataProviderInfo.description && this.dataProviderInfo.description.length > 0) ||
      this.hasJournalInfo ||
      //this.hasAggregationStatusInfo ||
      !!this.dataProviderInfo.countries ||
      (!!this.dataProviderInfo.subjects && this.dataProviderInfo.subjects.length > 0));
  }

  public get hasSecondaryInfo(): boolean {
    return !!this.dataProviderInfo && (
      (!!this.dataProviderInfo.organizations && this.dataProviderInfo.organizations.length > 0)
      || !!this.dataProviderInfo.oaiPmhURL || (this.dataProviderInfo.provenance && this.dataProviderInfo.provenance.size > 0)
    );
  }

  public getKeys( map) {
    return Array.from(map.keys());
  }

  public getProvenanceUrls() {
    this.provenanceUrls = Array.from(this.dataProviderInfo.provenance.values()).map(res => res['url']).reduce((acc, val) => acc.concat(val), []);
  }

  public getTypeName(): string {
    return StringUtils.getEntityName(this.type, false);
  }

	public viewAllDescriptionClicked() {
    if(this.isMobile) {
      this.summaryFsModal.title += " - Description";
      this.summaryFsModal.back = true;
      this.viewAllMobile = "description";
    } else {
      this.openDescriptionModal();
    }
  }

	public openDescriptionModal() {
		this.descriptionModal.alertFooter = false;
		this.descriptionModal.alertTitle = "Description";
		this.descriptionModal.open();
	}

	public clickedUsageMetrics() {
		setTimeout( () => {
      this.metricsClicked = true;
    });
	}

	public formatNumber(num: number | string) {
    let formatted = NumberUtils.roundNumber(+num);
    return formatted.number + formatted.size;
  }

	public cancelSummaryClicked() {
    this.summaryFsModal.title = "Summary";
    this.summaryFsModal.back = false;
    this.lessBtnOrganizations = false;
    this.viewAllMobile = "";
  }

	public openFsModal(fsModal: FullScreenModalComponent, title: string) {
    fsModal.title = title;
    fsModal.okButton = false;
    fsModal.stayOpenInBack = true;
    fsModal.open();
    this.tabMobile = title;
  }

	public getMetricsTooltip(value: string) {
		if (value == 'downloads') {
			return "<div class='uk-flex uk-flex-middle'><a href='https://usagecounts.openaire.eu/' target='_blank'><img src='assets/common-assets/logo-small-usage-counts.png' loading='lazy' alt='OpenAIRE UsageCounts'></a><span class='uk-text-uppercase uk-margin-small-left'>Downloads provided by <a href='https://usagecounts.openaire.eu/' target='_blank' class='uk-link-reset'><strong>UsageCounts</strong></a></div>";
		} else if (value == 'views') {
			return "<div class='uk-flex uk-flex-middle'><a href='https://usagecounts.openaire.eu/' target='_blank'><img class='uk-margin-small-right' src='assets/common-assets/logo-small-usage-counts.png' loading='lazy' alt='OpenAIRE UsageCounts'></a><span class='uk-text-uppercase uk-margin-small-left'>Views provided by <a href='https://usagecounts.openaire.eu/' target='_blank' class='uk-link-reset'><strong>UsageCounts</strong></a></div>";
		}
	}

  public addEoscPrevInParams(obj) {
    if(properties.adminToolsPortalType == "eosc" && this.prevPath) {
      let splitted: string[] = this.prevPath.split("?");
      obj = this.routerHelper.addQueryParam("return_path", splitted[0], obj);
      if(splitted.length > 0) {
        obj = this.routerHelper.addQueryParam("search_params", splitted[1], obj);
      }
    }
    return obj;
  }

  public get eoscBackLink() {
    if(this.prevPath && this.referrer && ((this.referrer == "https://eosc-search-service.grid.cyfronet.pl/") || (this.referrer == "https://beta.search.marketplace.eosc-portal.eu/") || (this.referrer == "https://search.marketplace.eosc-portal.eu/"))) {
      return this.referrer+this.prevPath;
    } else {
      return "https://"+(this.properties.environment == "beta" ? "beta." : "")+"search.marketplace.eosc-portal.eu/";
    }
  }
}
