import {SearchProjectsService} from '../../services/searchProjects.service';
import {ErrorCodes} from '../../utils/properties/errorCodes';
import {ErrorMessagesComponent} from '../../utils/errorMessages.component';
import {SearchCustomFilter, SearchUtilsClass} from '../../searchPages/searchUtils/searchUtils.class';
import {EnvProperties} from '../../utils/properties/env-properties';
import {StringUtils} from '../../utils/string-utils.class';
import {SearchResult} from "../entities/searchResult";
import {Subscriber} from "rxjs";
import {OpenaireEntities} from "../properties/searchFields";

export class FetchProjects {
  private errorCodes: ErrorCodes;
  private errorMessages: ErrorMessagesComponent;
  
  public results: SearchResult[] = [];
  
  public filters; // for getResultsForOrganizations
  public funders: any = [];  // for getResultsForOrganizations // this is filled with the initial query - before filtering

  subscriptions = [];
  public searchUtils: SearchUtilsClass = new SearchUtilsClass();
  
  
  constructor(private _searchProjectsService: SearchProjectsService) {
    this.errorCodes = new ErrorCodes();
    this.errorMessages = new ErrorMessagesComponent();
    this.searchUtils.status = this.errorCodes.LOADING;
    
  }

  public clearSubscriptions() {

    this.subscriptions.forEach(subscription => {
      if (subscription instanceof Subscriber) {
        subscription.unsubscribe();
      }
    });
  }
  public getResultsByKeyword(keyword: string, page: number, size: number, properties: EnvProperties, customFilter: SearchCustomFilter = null) {
    var parameters = "";
    if (keyword.length > 0) {
      parameters = "q=" + StringUtils.URIEncode(keyword);
    }
    
    //var errorCodes:ErrorCodes = new ErrorCodes();
    this.searchUtils.status = this.errorCodes.LOADING;
    var refineParams = null;
    if (customFilter) {
      refineParams = (refineParams ? (refineParams + '&') : '') + "&fq=" + StringUtils.URIEncode(customFilter.queryFieldName + " exact " + StringUtils.quote((customFilter.valueId)));
    }
    this.subscriptions.push(this._searchProjectsService.searchProjects(parameters, refineParams, page, size, [], properties).subscribe(
      data => {
        this.searchUtils.totalResults = data[0];
        this.results = data[1];
        
        //var errorCodes:ErrorCodes = new ErrorCodes();
        this.searchUtils.status = this.errorCodes.DONE;
        if (this.searchUtils.totalResults == 0) {
          this.searchUtils.status = this.errorCodes.NONE;
        }
      },
      err => {
        /*console.log(err);
         //TODO check erros (service not available, bad request)
        // if( ){
        //   this.searchUtils.status = ErrorCodes.ERROR;
        // }
        //var errorCodes:ErrorCodes = new ErrorCodes();
        //this.searchUtils.status = errorCodes.ERROR;
        if(err.status == '404') {
          this.searchUtils.status = this.errorCodes.NOT_FOUND;
        } else if(err.status == '500') {
          this.searchUtils.status = this.errorCodes.ERROR;
        } else {
          this.searchUtils.status = this.errorCodes.NOT_AVAILABLE;
        }*/
        this.handleError("Error getting "+OpenaireEntities.PROJECTS+" for keyword: " + keyword, err);
        this.searchUtils.status = this.errorMessages.getErrorCode(err.status);
      }
    ));
  }
  
  public getResultsForDataproviders(id: string, page: number, size: number, properties: EnvProperties) {
    //var errorCodes:ErrorCodes = new ErrorCodes();
    this.searchUtils.status = this.errorCodes.LOADING;

    this.subscriptions.push(this._searchProjectsService.getProjectsforDataProvider(id, page, size, properties).subscribe(
      data => {
        this.searchUtils.totalResults = data[0];
        this.results = data[1];
        
        //var errorCodes:ErrorCodes = new ErrorCodes();
        this.searchUtils.status = this.errorCodes.DONE;
        if (this.searchUtils.totalResults == 0) {
          this.searchUtils.status = this.errorCodes.NONE;
        }
      },
      err => {
        /*console.log(err);
         //TODO check erros (service not available, bad request)
        // if( ){
        //   this.searchUtils.status = ErrorCodes.ERROR;
        // }
        //var errorCodes:ErrorCodes = new ErrorCodes();
        //this.searchUtils.status = errorCodes.ERROR;
        if(err.status == '404') {
          this.searchUtils.status = this.errorCodes.NOT_FOUND;
        } else if(err.status == '500') {
          this.searchUtils.status = this.errorCodes.ERROR;
        } else {
          this.searchUtils.status = this.errorCodes.NOT_AVAILABLE;
        }*/
        this.handleError("Error getting "+OpenaireEntities.PROJECTS+" for "+OpenaireEntities.DATASOURCE+" with id: " + id, err);
        this.searchUtils.status = this.errorMessages.getErrorCode(err.status);
      }
    ));
  }
  
  public getNumForEntity(entity: string, id: string, properties: EnvProperties) {
    //var errorCodes:ErrorCodes = new ErrorCodes();
    this.searchUtils.status = this.errorCodes.LOADING;
    
    if (id != "" && entity != "") {

      this.subscriptions.push(this._searchProjectsService.numOfEntityProjects(id, entity, properties).subscribe(
        data => {
          this.searchUtils.totalResults = data;
          
          //var errorCodes:ErrorCodes = new ErrorCodes();
          this.searchUtils.status = this.errorCodes.DONE;
          if (this.searchUtils.totalResults == 0) {
            this.searchUtils.status = this.errorCodes.NONE;
          }
        },
        err => {
          /*console.log(err);
           //TODO check erros (service not available, bad request)
          // if( ){
          //   this.searchUtils.status = ErrorCodes.ERROR;
          // }
          //var errorCodes:ErrorCodes = new ErrorCodes();
          //this.searchUtils.status = errorCodes.ERROR;

          if(err.status == '404') {
            this.searchUtils.status = this.errorCodes.NOT_FOUND;
          } else if(err.status == '500') {
            this.searchUtils.status = this.errorCodes.ERROR;
          } else {
            this.searchUtils.status = this.errorCodes.NOT_AVAILABLE;
          }*/
          this.handleError("Error getting number of "+OpenaireEntities.PROJECTS+" for " + entity + " with id: " + id, err);
          this.searchUtils.status = this.errorMessages.getErrorCode(err.status);
        }
      ));
    }
  }
  
  public getResultsForOrganizations(organizationId: string, filterquery: string, page: number, size: number, refineFields: string[], properties: EnvProperties) {
    //var errorCodes:ErrorCodes = new ErrorCodes();
    this.searchUtils.status = this.errorCodes.LOADING;
    this.subscriptions.push(this._searchProjectsService.getProjectsForOrganizations(organizationId, filterquery, page, size, refineFields, properties).subscribe(
      data => {
        this.searchUtils.totalResults = data[0]; // the results can be filtered so this number can be no total results
        this.results = data[1];
        if (refineFields && refineFields.length > 0) {
          this.filters = data[2];
          filterquery = decodeURIComponent(filterquery);
          for (var i = 0; i < this.filters.length; i++) {
            if (filterquery.indexOf(this.filters[i].filterId) !== -1) {
              //console.log("this.filters[i].filterId:"+this.filters[i].filterId);
              for (var j = 0; j < this.filters[i].values.length; j++) {
                //console.log("this.filters[i].values[j].id:"+this.filters[i].values[j].id);
                if (filterquery.indexOf(this.filters[i].values[j].id) !== -1) {
                  this.filters[i].values[j].selected = true;
                }
              }
            }
            this.filters[i].countAllValues = this.filters[i].values.length;
          }
        }
        if (filterquery == "") {
          this.searchUtils.totalResultsNoFilters = this.searchUtils.totalResults;
          this.funders = [];
          for (var i = 0; i < this.filters.length; i++) {
            //console.log("this.filters[i].filterId:"+this.filters[i].filterId);
            if (this.filters[i].filterId == "funder") {
              this.funders = (this.filters[i].values);
              
            }
            this.filters[i].countAllValues = this.filters[i].values.length;
          }
          //console.log("  this.funders:"+   this.funders);
          
        }
        //var errorCodes:ErrorCodes = new ErrorCodes();
        this.searchUtils.status = this.errorCodes.DONE;
        if (this.searchUtils.totalResults == 0) {
          this.searchUtils.status = this.errorCodes.NONE;
        }
      },
      err => {
        this.handleError("Error getting "+OpenaireEntities.PROJECTS+" for "+OpenaireEntities.ORGANIZATION+" with id: " + organizationId, err);
        this.searchUtils.status = this.errorMessages.getErrorCode(err.status);
      }
    ));
  }
  
  private handleError(message: string, error) {
    console.error("Fetch "+OpenaireEntities.PROJECTS+" (class): " + message, error);
  }
}
