import {SearchDataprovidersService} from '../../services/searchDataproviders.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 {Subscriber} from "rxjs";
import {OpenaireEntities} from "../properties/searchFields";

export class FetchDataproviders {
  private errorCodes: ErrorCodes;
  private errorMessages: ErrorMessagesComponent;
  
  public results = [];
  public searchUtils: SearchUtilsClass = new SearchUtilsClass();
  subscriptions = [];
  public CSV: any = {
    "columnNames": ["Title", "Type", "Coutries", "Compatibility"],
    "export": []
  };
  public CSVDownloaded = false;
  public csvParams: string;
  public loadPaging: boolean = true;
  public oldTotalResults: number = 0;
  
  constructor(private _searchDataprovidersService: SearchDataprovidersService) {
    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._searchDataprovidersService.searchDataproviders(parameters, refineParams, page, size, [], properties).subscribe(
      data => {
        this.searchUtils.totalResults = data[0];
        this.results = data[1];
        
        //ar 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.DATASOURCES+" for keyword: " + keyword, err);
        this.searchUtils.status = this.errorMessages.getErrorCode(err.status);
      }
    ));
  }
  
  public getResultsForHome(size: number, properties: EnvProperties) {
    let page = 1;
    var parameters = "&sortBy=resultdateofacceptance,descending";//"orderby=date";
    
    this.searchUtils.status = this.errorCodes.LOADING;

    this.subscriptions.push(this._searchDataprovidersService.searchDataproviders(parameters, null, page, size, [], properties).subscribe(
      data => {
        this.searchUtils.totalResults = data[0];
        this.results = data[1];
        
        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(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.DATASOURCES+" with parameters: " + parameters + " for Home", 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._searchDataprovidersService.numOfEntityDataproviders(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 "+OpenaireEntities.DATASOURCES+" for " + entity + " with id: " + id, err);
          this.searchUtils.status = this.errorMessages.getErrorCode(err.status);
        }
      ));
    }
  }
  
  public getNumForSearch(keyword: string, properties: EnvProperties, refineParams: string = null) {
    //var errorCodes:ErrorCodes = new ErrorCodes();
    this.searchUtils.status = this.errorCodes.LOADING;

    this.subscriptions.push(this._searchDataprovidersService.numOfSearchDataproviders(keyword, properties, refineParams).subscribe(
      data => {
        this.searchUtils.totalResults = data;
        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.DATASOURCES+" for keyword: " + keyword, err);
        this.searchUtils.status = this.errorMessages.getErrorCode(err.status);
      }
    ));
  }
  
  public getResultsForDeposit(id: string, type: string, page: number, size: number, properties: EnvProperties) {
    //var errorCodes:ErrorCodes = new ErrorCodes();
    this.searchUtils.status = this.errorCodes.LOADING;
    this.results = [];
    this.searchUtils.totalResults = 0;
    this.loadPaging = false;
    
    if (id != "") {

      this.subscriptions.push(this._searchDataprovidersService.searchDataprovidersForDeposit(id, type, page, size, properties).subscribe(
        data => {
          this.searchUtils.totalResults = data[0];
          //console.info("search Dataproviders forDeposit: [id:"+id+", type:"+type+" ]  [total results:"+this.searchUtils.totalResults+"]");
          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;
          }
          
          if (this.searchUtils.status == this.errorCodes.DONE) {
            // Page out of limit!!!
            let totalPages: any = this.searchUtils.totalResults / (this.searchUtils.size);
            if (!(Number.isInteger(totalPages))) {
              totalPages = (parseInt(totalPages, 10) + 1);
            }
            if (totalPages < page) {
              this.searchUtils.totalResults = 0;
              this.searchUtils.status = this.errorCodes.OUT_OF_BOUND;
            }
          }
          this.loadPaging = true;
          this.oldTotalResults = this.searchUtils.totalResults;
        },
        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.DATASOURCES+" in share " + type + " for "+OpenaireEntities.ORGANIZATION+" with id: " + id, err);
          this.searchUtils.status = this.errorMessages.getErrorCode(err.status);
          
          this.loadPaging = true;
          this.oldTotalResults = 0;
        }
      ));
    }
  }
  
  public getResultsForEntity(entity: string, id: string, page: number, size: number, properties: EnvProperties) {
    //var errorCodes:ErrorCodes = new ErrorCodes();
    this.searchUtils.status = this.errorCodes.LOADING;
    
    var parameters = "";
    
    if (entity == "organization") {
      parameters = "organizations/" + id;
    }
    
    if (parameters != "") {

      this.subscriptions.push(this._searchDataprovidersService.searchDataprovidersForEntity(parameters, page, size, properties).subscribe(
        data => {
          this.searchUtils.totalResults = data[0];
          //console.info("search Dataproviders for "+entity+": [Parameters:"+parameters+" ]  [total results:"+this.searchUtils.totalResults+"]");
          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.DATASOURCES+" for " + entity + " with id: " + id, 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._searchDataprovidersService.getDataProvidersforEntityRegistry(id, page, size, properties).subscribe(
      data => {
        this.searchUtils.totalResults = data[0];
        //console.info("search Dataproviders for Entity Registry: [Id:"+id+" ]  [total results:"+this.searchUtils.totalResults+"]");
        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.DATASOURCES+" for entity registry with id: " + id, err);
        this.searchUtils.status = this.errorMessages.getErrorCode(err.status);
      }
    ));
  }
  
  private handleError(message: string, error) {
    console.error("Fetch "+OpenaireEntities.DATASOURCES+" (class): " + message, error);
  }
}
