// Angular Core
import { EventEmitter, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

// RxJs
import { Subscription } from 'rxjs';

// Pipes
import { StripNDCPipe } from '../../filters/strip-ndc.pipe';

// Services
import { ApiService } from '../api/api.service';

// Interfaces
import { StaticFilters } from '../../interfaces/user/user-search';

// Utilities
import { UtilitiesService } from '../utilities/utilities.service';

@Injectable({
  providedIn: 'root'
})
export class SearchService {

  resetTypeAheadData = new EventEmitter<string>();
  clearSearchInput = new EventEmitter<boolean>();
  setNDCSpecific = new EventEmitter<string>();
  updateCategoryDropdownByCode = new EventEmitter<string>();
  setSearchInput = new EventEmitter<string>();
  uncheckAllStaticFilters = new EventEmitter<object>();
  checkSupplierFilterListener = new EventEmitter<object>();
  checkShortDataFilter = new EventEmitter<StaticFilters['shortDate']>();
  searchBySearchQuery = new EventEmitter<any>();
  setAdvFilterSelected = new EventEmitter<boolean>();
  supplierSearchBySearchQuery = new EventEmitter<any>();
  shortDatedSearchBySearchQuery = new EventEmitter<object>();
  otcCatagorySearchQuery = new EventEmitter<any>();
  diabeticSuppliesSearchQuery = new EventEmitter<object>();
  setPage = new EventEmitter<number>();
  dealsProductsSearchQuery = new EventEmitter<object>();
  oppBuysSearchBySearchQuery = new EventEmitter<object>();
  brandsSearchBySearchQuery = new EventEmitter<object>();
  setAdvanceFilterOpenFlag = new EventEmitter<object>();
  gpoDealsProductsSearchQuery = new EventEmitter<object>();
  drugShortageSearchQuery = new EventEmitter<object>();
  controlsSearchQuery = new EventEmitter<object>();
  controlsPageQuery = new EventEmitter<object>();
  otcSearchQueryListener = new EventEmitter<object>();



  constructor(
    private http: HttpClient,
    public api: ApiService,
    private stripNDC: StripNDCPipe,
    private utilities: UtilitiesService,
    ) { }

  calculatePagination: boolean = true;
  resetNDCSpecific:boolean = true ;


  private purchasedBefore: boolean = false;

  setPurchasedBefore(value: boolean) {
    this.purchasedBefore = value;
    // sync with searchQuery
    this.searchQuery.searchData.searchOptions.filters['purchasedBefore'] = value;
  }

  getPurchasedBefore() {
    return this.purchasedBefore;
  }
  
  /*
   * create the service instance and set default private search properties
   * @type object
   */
  searchDefaultConfig: any = {
    searchData: {
      searchTerms: {
        categoryCode: 'All',
        searchInput: ''
      },
      searchOptions: {
        type: 'NDCName',// TypeAhead or TopPurchasedNDC or ShortDateNDC
        filters: {
          shortDate: [],
          manufacturer: [],
          supplier: [],
          packsize: [],
          strength: [],
          dosageForm: [],
          vawdOnly: [],
          brandOrGeneric: [],
          cntrlSchedules: [],
          productCategory:[],
          ADR:[],
          purchasedBefore: false
        },
        ndcSpecific: false,
        searchSortColumn: 'price_per_unit',
        searchSortOrder: 'asc',
        searchLimit: 200,
        pageNumber: 0,
        changeInFilter: false
      },
      staticFilters: {
        shortDate: [],
        manufacturer: [],
        supplier: [],
        packsize: [],
        strength: [],
        dosageForm: [],
        vawdOnly: [],
        brandOrGeneric: [],
        cntrlSchedules: [],
        productCategory:[],
        ADR:[],
        purchasedBefore: false
      }
    }
  };

  /**
   * search object
   * @type object
   */
  searchQuery: any = {
    searchData: {
      searchTerms: {
        categoryCode: 'All',
        searchInput: ''
      },
      searchOptions: {
        type: 'NDCName',// TypeAhead or TopPurchasedNDC or ShortDateNDC
        filters: {
          shortDate: [],
          manufacturer: [],
          supplier: [],
          packsize: [],
          strength: [],
          dosageForm: [],
          vawdOnly: [],
          brandOrGeneric: [],
          cntrlSchedules: [],
          productCategory:[],
          ADR:[],
          purchasedBefore: false
        },
        ndcSpecific: false,
        saveOnNdcs: false,
        lowestPrice: '',
        searchSortColumn: 'price_per_unit',
        searchSortOrder: 'asc',
        searchLimit: 200,
        pageNumber: 0,
        changeInFilter: false
      },
      staticFilters: {
        shortDate: [],
        manufacturer: [],
        supplier: [],
        packsize: [],
        strength: [],
        dosageForm: [],
        vawdOnly: [],
        brandOrGeneric: [],
        cntrlSchedules: [],
        productCategory:[],
        ADR:[],
        purchasedBefore: false
      }
    }
  };

  /**
   * Store search label
   */
  searchLabel = '';


  /**
   * Store the advanced filters
   * @param {string} type of search
   */
  getAdvancedFilters(searcType: string) {
    return {
      searchtype: searcType,
      config: {
          show: false,
          keepOpen: false,
          selectAllFilter:[
            {
                filter: -1,
                name: ' Select All',
                count: 0
            },
            {
                filter: -2,
                name: ' Select All',
                count: 0
            },
            {
                filter: -3,
                name: ' Select All',
                count: 0
            },
            {
                filter: -4,
                name: ' Select All',
                count: 0
            },
            {
                filter: -5,
                name: ' Select All',
                count: 0
            },
            {
                filter: -6,
                name: ' Select All',
                count: 0
            },
            {
                filter: -7,
                name: ' Select All',
                count: 0
            },
            {
                filter: -8,
                name: ' Select All',
                count: 0
            }
        ]
      },
      staticFilters: this.getDefaultStaticFilters()
    };
  }

  /**
   * Sets Ndc specific flag
   * @param {boolean} ndcSpecific
   * @returns {undefined}
   */
  setNdcSpecific(ndcSpecific: boolean) {
    if (typeof (ndcSpecific) === 'boolean') {
      this.searchQuery.searchData.searchOptions.ndcSpecific = ndcSpecific;
    }
  };

  /**
   * Sets Save on NDC flag
   * @param {boolean} saveOnNdcs
   * @returns {undefined}
   */
  setSaveOnNdcs(saveOnNdcs: boolean) {
    if (typeof (saveOnNdcs) === 'boolean') {
      this.searchQuery.searchData.searchOptions.saveOnNdcs = saveOnNdcs;
    }
  };


  /**
   * Sets Lowest price value from results
   * @param {boolean} lowestPrice
   * @returns {undefined}
   */
  setLowestPrice(lowestPrice: number | string) {
    this.searchQuery.searchData.searchOptions.lowestPrice = lowestPrice;
  };


  /**
   * sets category code in search service
   * @param {string} code
   */
  setCategoryCode(code: string) {
    if (code) {
      this.searchQuery.searchData.searchTerms.categoryCode = code;
    }
  };


  /**
   * sets search input term
   * @param {string} term
   */
  setSearchTerm(term: string) {
    if (term) {
      // TRX-8003
      let transform_term = decodeURIComponent(encodeURIComponent(term));
      this.searchQuery.searchData.searchTerms.searchInput = transform_term;
    }
  };

  /**
   * Sets search type: NDCName/TypeAhead etc...
   * @param {string} type
   */
  setSearchType(type: string) {
    if (type) {
      this.searchQuery.searchData.searchOptions.type = type;
    }
  };

  /**
   * sets search result limit from the backend
   * @param {number} limit
   */
  setSearchLimit(limit: number) {
    if (limit) {
      this.searchQuery.searchData.searchOptions.searchLimit = limit;
    }
  };

  /**
   * Sets Search Sort Column
   * @param {type} col
   * @returns {undefined}
   */
  setSearchSortColumn(col: any) {
    if (typeof (col) === 'string') {
      this.searchQuery.searchData.searchOptions.searchSortColumn = col;
    }
  };

  /**
   * gets current search term
   * @returns {String|searchQuery.searchData.searchTerms.searchInput}
   */
  getSearchTerm() {
    return this.stripNDC.transform(this.searchQuery.searchData.searchTerms.searchInput);
  };

  /**
   * gets current search type
   * @returns {String|searchQuery.searchData.searchOptions.type}
   */
  getSearchType() {
    return this.searchQuery.searchData.searchOptions.type;
  };

  /*
   * gets current search term category code 
   * @returns {String|searchQuery.searchData.searchTerms.categoryCode}
   */
  getCategoryCode() {
    return this.searchQuery.searchData.searchTerms.categoryCode;
  };

  setSearchPageNumber(pageNumber: number) {
    if (pageNumber) {
      this.searchQuery.searchData.searchOptions.pageNumber = pageNumber;
    }
  };

  getSearchPageNumber() {
    return this.searchQuery.searchData.searchOptions.pageNumber;
  };

  setChangeInFilter(value: boolean) {
    if (typeof (value) === 'boolean') {
      this.searchQuery.searchData.searchOptions.changeInFilter = value;
    }
  };

  getchangeInFilter() {
    return this.searchQuery.searchData.searchOptions.changeInFilter;
  };

  /**
   * gets the current search query configuration
   * @returns {object} searchQuery
   */
  getSearchQuery() {
    return this.searchQuery;
  };

  /**
   * resets the current search query to default config
   */
  resetSearchQuery() {
    this.searchQuery = this.searchDefaultConfig;
  };


  /**
   * Gets the array of the filterName
   * @param {string} filterName
   * @returns {Array}
   */



  getFilterArr(filterName: string) {
    var arr: any[] = [];
    const filtersData = Object.keys(this.searchQuery.searchData.searchOptions.filters).map(key => ({key, value: this.searchQuery.searchData.searchOptions.filters[key]}));
    filtersData.forEach((filter: any) => {
      if (filterName === filter.key) {
        arr = filter.value;
      }
    });
    return arr;
  };

  /**
   * sets the filter selection on the specified filter name
   * @param {string} filterName
   * @param {string|int} value
   * @returns {undefined}
   */
  addFilterSelection(filterName: string, value: any) {
    var arr = this.getFilterArr(filterName);
    arr.push(value);
  };

  /**
   * Sets a filter array by name
   * @param {string} filterName
   * @param {object/array} value
   * @returns {undefined}
   */
  setFilterArr(filterName: string, value: any) {
    this.searchQuery.searchData.searchOptions.filters[filterName] = value;
  };

  /**
   * removes the filter seletion from the specified filter name
   * @param {string} filterName
   * @param {string|int} value
   * @returns {undefined}
   */
  removeFilterSelection(filterName: string, value: never) {
    var arr = this.getFilterArr(filterName);
    var index = arr.indexOf(value);
    if (index > -1) {
      arr.splice(index, 1);
    }
  };

  /**
   * Sets the statics filters for a search query
   * @param {object} staticFilters
   * @returns {undefined}
   */
  setStaticFilters(staticFilters: {}) {
    this.utilities.merge(this.searchQuery.searchData.staticFilters, staticFilters);
  };

  /**
   * removes the select all filter from any of the filters
   * @returns {undefined}
   */
  cleanStaticFilters() {
    const staticFiltersData = Object.keys(this.searchQuery.searchData.staticFilters).map(key => ({key, value: this.searchQuery.searchData.staticFilters[key]}));
    staticFiltersData.forEach((filter: any) => {
      if (!Array.isArray(filter.value)) {
        return;
      }
      filter.value.forEach((filterOption: any, key: any) => {
        if (typeof (filterOption.filter) === 'number' && filterOption.filter < 0) {
          filter.value.splice(key, 1);
        }
      });
    });
  };

  /**
   * resets filters for new search
   * @returns {undefined}
   */
  resetFilters() {
    this.searchQuery.searchData.searchOptions.filters = {
      shortDate: [],
      manufacturer: [],
      supplier: [],
      packsize: [],
      strength: [],
      dosageForm: [],
      vawdOnly: [],
      brandOrGeneric: [],
      cntrlSchedules: [],
      productCategory:[],
      ADR:[],
      purchasedBefore: false
    };
    this.searchQuery.searchData.searchOptions.changeInFilter = false;
    this.searchQuery.searchData.staticFilters = {
      shortDate: [],
      manufacturer: [],
      supplier: [],
      packsize: [],
      strength: [],
      dosageForm: [],
      vawdOnly: [],
      brandOrGeneric: [],
      cntrlSchedules: [],
      productCategory:[],
      ADR:[],
      purchasedBefore: false
    };
  };

  /**
   * minimum length for a search
   * @type Number
   */
  minInputLength = 3;

  /**
   * this variable for search method to compare search type
   * @type string
   */
  alphabetSearch = "AlphabetSearch";

  /**
   * Sets changeInFilter: true/false
   * @param {boolean} type
   */
  setAdvFilterSelectedListner: Subscription = this.setAdvFilterSelected.subscribe((data: boolean) => {
    this.searchQuery.searchData.searchOptions.changeInFilter = data;
  });

  /**
   * Search main method to perform a search based on searchQuery object         
   * @returns {object} ajax promise
   */
  search() {
    this.cleanStaticFilters();
    if (this.searchQuery.searchData.searchOptions.filters.shortDate.length === 0) {
      this.searchQuery.searchData.searchOptions.filters.shortDate = this.utilities.getStickyFilters();
    }
    if (this.searchQuery.searchData.searchTerms.searchInput.length >= this.minInputLength || this.getSearchType() === this.alphabetSearch) {
      if(this.searchQuery.searchData.searchOptions.hasOwnProperty('whatsSelling')){
        delete this.searchQuery.searchData.searchOptions['whatsSelling'];
      }
      return this.api.create('/User-Search', this.searchQuery);
    }
    return null;
  };

  resetNDCSpecificCheck(isEnabled : boolean) {
    this.resetNDCSpecific = isEnabled;
  };


  /**
   * main typeahead object instance to avoid overlapping with main search 
   * @type object
   */
  searchTypeAhead:any = {
    searchData: {
      searchTerms: {
        categoryCode: 'All',
        searchInput: ''
      },
      searchOptions: {
        type: 'TypeAheadSearch',// TypeAhead or TopPurchasedNDC or ShortDateNDC
        filters: {
          shortDate: [],
          manufacturer: [],
          supplier: [],
          packsize: [],
          strength: [],
          dosageForm: [],
          vawdOnly: [],
          brandOrGeneric: [],
          cntrlSchedules: [],
          productCategory:[],
          ADR:[],
          purchasedBefore: false
        },
        ndcSpecific: false,
        searchSortColumn: 'price_per_unit',
        searchSortOrder: 'asc',
        searchLimit: 10,
        changeInFilter: false
      },
      staticFilters: {
        shortDate: [],
        manufacturer: [],
        supplier: [],
        packsize: [],
        strength: [],
        dosageForm: [],
        vawdOnly: [],
        brandOrGeneric: [],
        cntrlSchedules: [],
        productCategory:[],
        ADR:[],
        purchasedBefore: false
      }
    }
  };

  /**
   * main typeahead object instance to avoid overlapping with main search 
   * @type object
   */
  searchTypeAheadDefault = {
    searchData: {
      searchTerms: {
        categoryCode: 'All',
        searchInput: ''
      },
      searchOptions: {
        type: 'TypeAheadSearch',// TypeAhead or TopPurchasedNDC or ShortDateNDC
        filters: {
          ADR: [],
          shortDate: [],
          manufacturer: [],
          supplier: [],
          packsize: [],
          strength: [],
          dosageForm: [],
          vawdOnly: [],
          brandOrGeneric: [],
          cntrlSchedules: [],
          productCategory: [],
          purchasedBefore: false
        },
        ndcSpecific: false,
        searchSortColumn: 'price_per_unit',
        searchSortOrder: 'asc',
        searchLimit: 10,
        changeInFilter: false
      },
      staticFilters: {
        ADR: [],
        shortDate: [],
        manufacturer: [],
        supplier: [],
        packsize: [],
        strength: [],
        dosageForm: [],
        vawdOnly: [],
        brandOrGeneric: [],
        cntrlSchedules: [],
        productCategory: [],
        purchasedBefore: false
      }
    }
  };

  /**
   * resets the typeahead to default settings
   * @returns {undefined}
   */
  resetTypeAheadToDefault() {
    this.utilities.merge(this.searchTypeAhead, this.searchTypeAheadDefault)
  };

  /**
   * sets typeahead search category code
   * @param {string} code
   */
  setTypeAheadCategoryCode(code: string) {
    this.searchTypeAhead.searchData.searchTerms.categoryCode = code;
  };
  /**
   * Get current selected category code for typeahead
   * @returns {string} categoryCode
   */
  getTypeAheadCategoryCode() {
    return this.searchTypeAhead.searchData.searchTerms.categoryCode;
  };

  /**
   * Get current search term for typeahead
   * @returns {string} categoryCode
   */
  getTypeAheadSearchTerm() {
    return this.searchTypeAhead.searchData.searchTerms.searchInput;
  };

  /**
   * sets the typeahead serch input term
   * @param {string} term
   */
  setTypeAheadSearchTerm(term: string) {
    this.searchTypeAhead.searchData.searchTerms.searchInput = this.stripNDC.transform(term);
  };

  /**
   * sets the typeahead supplier Id
   * @param Id
   */
  setTypeAheadSupplierId(Id: any) {
    this.searchTypeAhead.searchData.searchOptions.filters.supplier = [Id];
  };

  /**
   * resets the typeahead supplier Id
   * @param Id
   */
  resetTypeAheadSupplierId() {
    this.searchTypeAhead.searchData.searchOptions.filters.supplier.pop();
  };

  setTypeAheadSearchType(type: string) {
    this.searchTypeAhead.searchData.searchOptions.type = type;
  };

  /**
   * Method to get typeahead results
   * @returns {object} promise
   */
  typeahead() {
    return this.api.create('/User-Search', this.searchTypeAhead);
  };

  /**
   * Sets typeahead sort order
   * @returns {object}
   */
  setTypeAheadSortOrder(sortOrder: any) {
    if (sortOrder === 'asc' || sortOrder === 'desc') {
      this.searchTypeAhead.searchData.searchOptions.searchSortOrder = sortOrder;
    }
  };

  /**
   * Sets typeahead sort column
   * @returns {object}
   */
  setTypeAheadSortColumn(column: string) {
    this.searchTypeAhead.searchData.searchOptions.searchSortColumn = column;
  };

  /**
   * Method to get the available categories for the search form
   * @returns {object} ajax promise
   */
  getCategories() {
    return this.api.read('/User-Search?id=getCategories');
  };

  /**
   * sends respose to api service for handling
   * @param {object} response object
   * @returns {undefined}
   */
  errorCallBack(response: any) {
    this.api.inactive = true;
    this.api.errorCallback(response);
  };
  /**
   * For getting the esign url or written message
   * @param {type} args
   * @return {undefined}
   */
  callDocument(args: any) {
    return this.api.create('/ESign-DocumentUrl', args);
  };
  updateEsign(args: any) {
    return this.api.create('/User-ApplicationStatus', args);
  };

  /**
   * Method to add to Favorites.
   * @returns {object} promise
   */
  addToFav(ndc: any) {
    return this.api.create('/User-Favorite', ndc);
  };

  /**
   * Get favorite products of users.
   * @returns {unresolved}
   */
  searchFavorites() {
    return this.api.read('/User-Favorite/getFavorites');
  };

  /**
   * Get NDC specific setting
   */
  getNDCSpecific() {
    return this.searchQuery.searchData.searchOptions.ndcSpecific;
  };

  /**
   * Send a product request when not found in search
   * @param {array} data
   * @returns {unresolved}
   */
  requestProduct(data: any) {
    return this.api.create('/User-ProductRequest', data);
  };

  /**
   * Default specific Search Query object
   * @type object
   */
  specificSearchQuery = Object.assign({}, this.searchDefaultConfig)

  /**
   * Set Specific Search Limit
   * @param {type} limit
   * @returns {undefined}
   */
  setSpecificSearchLimit(limit: number) {
    this.specificSearchQuery.searchData.searchOptions.searchLimit = limit;
  };

  /**
   * Sets Specific Search Sort Column
   * @param {type} col
   * @returns {undefined}
   */
  setSpecificSearchSortColumn(col: string) {
    if (col) {
      this.specificSearchQuery.searchData.searchOptions.searchSortColumn = col;
    }
  };

  /**
   * sets Specific Search Order as asc or desc
   * @param {type} order
   * @returns {undefined}
   */
  setSpecificSearchOrder(order: string) {
    if (order) {
      this.specificSearchQuery.searchData.searchOptions.searchSortOrder = order;
    }
  };

  /**
   * Sets specific search type
   * @param {type} type
   * @returns {undefined}
   */
  setSpecificSearchType(type: string) {
    this.specificSearchQuery.searchData.searchOptions.type = type;
  };

  /**
   * sets search input term for specific search
   * @param {string} term
   */
  setSpecificSearchSearchTerm(term: any) {
    this.specificSearchQuery.searchData.searchTerms.searchInput = this.stripNDC.transform(term);
  };

  /**
   * resets filters for new search
   * @returns {undefined}
   */
  resetSpecificSearchFilters() {
    this.specificSearchQuery.searchData.searchOptions.filters = {
      shortDate: [],
      manufacturer: [],
      supplier: [],
      packsize: [],
      strength: [],
      dosageForm: [],
      vawdOnly: [],
      brandOrGeneric: [],
      cntrlSchedules: [],
      productCategory:[],
      ADR:[],
      purchasedBefore: false
    };
    this.specificSearchQuery.searchData.searchOptions.changeInFilter = false;
    this.specificSearchQuery.searchData.staticFilters = {
      shortDate: [],
      manufacturer: [],
      supplier: [],
      packsize: [],
      strength: [],
      dosageForm: [],
      vawdOnly: [],
      brandOrGeneric: [],
      cntrlSchedules: [],
      productCategory:[],
      ADR:[],
      purchasedBefore: false
    };
  };

  /**
   * Sets Page number for specific search
   * @param {type} number
   * @returns {undefined}
   */
  setSpecificSearchPageNumber(number: number) {
    this.specificSearchQuery.searchData.searchOptions.pageNumber = number;
  };

  /**
   * Returns Specific Search Object Data
   * @returns {Array|@var;stackDest|RegExp|angular-1_3_6_L6.copy.stackDest|Object|Array)=|Date|object}
   */
  getSpecificSearchObject() {
    return this.specificSearchQuery;
  };

  /**
   * gets search term for specific search
   * @returns {.angular@call;copy.searchData.searchTerms.searchInput|object.searchData.searchTerms.searchInput|String}
   */
  getSpecificSearchSearchTerm() {
    return this.stripNDC.transform(this.specificSearchQuery.searchData.searchTerms.searchInput);
  };

  /**
   * Gets the page number
   * @returns {object.searchData.searchOptions.pageNumber|.angular@call;copy.searchData.searchOptions.pageNumber|type}
   */
  getSpecificSearchPageNumber() {
    return this.specificSearchQuery.searchData.searchOptions.pageNumber;
  };

  /**
   * Gets the filters data
   * @returns {Boolean|.angular@call;copy.searchData.searchOptions.changeInFilter|object.searchData.searchOptions.changeInFilter}
   */
  getSpecificSearchChangeInFilter() {
    return this.specificSearchQuery.searchData.searchOptions.changeInFilter;
  };

  /**
   * Sets a filter array by name
   * @param {string} filterName
   * @param {object/array} value
   * @returns {undefined}
   */
  setSpecificSearchFilterArr(filterName: string, value: any) {
    this.specificSearchQuery.searchData.searchOptions.filters[filterName] = value;
  };

  /**
   * set Static Filters for Specific Search
   * @param {type} staticFilters
   * @returns {undefined}
   */
  setSpecificSearchStaticFilters(staticFilters: any) {
    this.utilities.merge(this.specificSearchQuery.searchData.staticFilters, staticFilters)
  };

  /**
   * Sets filter change
   * @param {type} value
   * @returns {undefined}
   */
  setSpecificSearchChangeInFilter(value: boolean) {
    this.specificSearchQuery.searchData.searchOptions.changeInFilter = value;
  };

  /**
   * sets the filter selection on the specified filter name
   * @param {string} filterName
   * @param {string|int} value
   * @returns {undefined}
  */
  addSpecificSearchFilterSelection(filterName: string, value: any) {
    var arr: any = this.getSpecificSearchFilterArr(filterName);
    arr.push(value);
  };

  /**
   * Gets the array of the filterName
   * @param {string} filterName
   * @returns {Array}
   */
  getSpecificSearchFilterArr(filterName: string) {
    let arr: [] = [];
    const filterData = Object.keys(this.specificSearchQuery.searchData.searchOptions.filters).map(key => ({key, value: this.specificSearchQuery.searchData.searchOptions.filters[key]}));
    filterData.forEach((filter: any) => {
      if(filterName === filter.key){
        arr = filter.value;
      }
    });
    return arr;
  };


  /**
   * resets the current search query to default config
   * @returns {undefined}
   */
  resetSpecificSearchQuery() {
    this.specificSearchQuery = this.searchDefaultConfig;
  };

  /**
   * Sets the what's selling status for opportunity buys page
   * @param {type} status
   * @returns {undefined}
   */
  setWhatsSelling(status: boolean) {
    this.specificSearchQuery.searchData.searchOptions.whatsSelling = status;
  };

    /**
     * removes the select all filter from any of the filters
     * @returns {undefined}
     */
    cleanSpecificSearchStaticFilters(staticFilters: any[] = []): void {
        staticFilters.forEach(staticFilter => {
            const value = staticFilter?.value;

            if (Array.isArray(value)) {
                for (let i = value.length - 1; i >= 0; i--) {
                    const filterObj = value[i];
                    if (typeof filterObj?.filter === 'number' && filterObj.filter < 0) {
                        value.splice(i, 1);
                    }
                }
                return;
            }

            if (typeof value === 'boolean') {
                // boolean filters like purchasedBefore
                return;
            }
        });
    }

  /**
   * Sets supplier ID
   * @param Id
   */
  setSupplierCatalogId(Id: any) {
    this.specificSearchQuery.searchData.searchOptions.filters.supplier = [Id];
  };

  /**
   * Returns the type of search.
   * @returns {object.searchData.searchOptions.type|.angular@call;copy.searchData.searchOptions.type|String}
   */
  getSpecificSearchType() {
    return this.specificSearchQuery.searchData.searchOptions.type;
  };

  /**
   * Checks and tells if data is set in the advanced filter
   * @returns {Number}
   */
  checkIfAdvFilterHasData() {
    var arr = [];
    var arrayLength = 0;
    const filterData = Object.keys(this.specificSearchQuery.searchData.searchOptions.filters).map(key => ({key, value: this.specificSearchQuery.searchData.searchOptions.filters[key]}));
    filterData.forEach((filter: any) => {
      if (filter.key !== 'supplier') {
        arrayLength = arrayLength + filter.value.length;
      }
    })
    return arrayLength;
  };

  /**
   * Search Method for specific search requests
   * @returns {unresolved}
   */
  specificSearchRequest() {
    this.cleanSpecificSearchStaticFilters();
    this.setSpecificSearchStickyFilter();
    if(this.specificSearchQuery.searchData.searchOptions.hasOwnProperty('whatsSelling')){
      delete this.specificSearchQuery.searchData.searchOptions['whatsSelling'];
    }
    return this.api.create('/User-Search', this.specificSearchQuery);
  };

  /**
   * Search Opportunity Buys         
   * @returns {object} ajax promise
   */
  searchOppBuys() {
    this.cleanSpecificSearchStaticFilters();
    this.setSpecificSearchStickyFilter();
    return this.api.create('/User-OpportunityBuys', this.specificSearchQuery);
  };

  /**
   * Set short date sticky filter for all specific search requests
   * @returns {undefined}
   */
  setSpecificSearchStickyFilter() {
    if (this.specificSearchQuery.searchData.searchOptions.filters.shortDate.length === 0) {
        this.specificSearchQuery.searchData.searchOptions.filters.shortDate = this.utilities.getStickyFilters();
    }
  };

  /**
   * sets category code in otc service
   * @param {string} code
   */
  setspecificSearchCategoryCode(code: string) {
    this.specificSearchQuery.searchData.searchTerms.categoryCode = code;
  };

  /**
   * Search Method for OTC products
   * @returns {object} ajax
   */
  otcSearch() {
    this.setSpecificSearchStickyFilter();
    return this.api.create('/User-Search', this.specificSearchQuery);
  };

  /**
   * Introduced as per TRX-7700
   * Gets direct url categories
   * 
   * @retruns {array}
  */
  getDirectUrlCategories() {
    return ['FLU', 'TST'];
  };

  /**
  * Returns Default Static Filters
  *
  * @returns {object}
  */
  getDefaultStaticFilters() {
    const staticFilters: StaticFilters = {
      shortDate: [],
      manufacturer: [],
      supplier: [],
      packsize: [],
      strength: [],
      dosageForm: [],
      vawdOnly: [],
      brandOrGeneric: [],
      cntrlSchedules: [],
      productCategory:[],
      ADR:[],
      purchasedBefore: false
    }
    return staticFilters;
  };

  resetAllToInitialState() {
    this.resetSearchQuery();
    this.resetFilters();
    this.resetNDCSpecificCheck(true);
    this.resetTypeAheadToDefault();
    this.resetTypeAheadSupplierId();
    this.resetSpecificSearchFilters();
    this.resetSpecificSearchQuery();
  };

  removeWhatsSelling() {
    if (this.specificSearchQuery.searchData.searchOptions.hasOwnProperty('whatsSelling')) {
        delete this.specificSearchQuery.searchData.searchOptions.whatsSelling;
    }
  }
}
