import { Injectable, Output, EventEmitter, NgZone } from '@angular/core';
import { HttpClient, HttpResponse, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
// import { Observable } from 'rxjs/Observable';
// import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs';
import { BehaviorSubject } from 'rxjs';
import { DatePipe } from '@angular/common';
import { Overlay, OverlayConfig } from '@angular/cdk/overlay';

import { DashboardDatamodelService } from './dashboard-datamodel.service';
import { map } from 'rxjs/operators';
import { HttpRequestService }  from 'base-blocks';
import { throwError } from 'rxjs'

declare var invokeDashboardLink: any;
declare var loadComponent:any;
declare var loadAngularDashboard: any;
declare var destroyComponent: any;
declare var detroyDashboard: any;
//declare var callDataModel: any;
//declare var updateCacheDatamodel: any;

@Injectable()
export class DashboardService {
                
    constructor(private http: HttpClient, public datePipe:DatePipe, public dashboardDatamodelService:DashboardDatamodelService, public overlay: Overlay, private zone: NgZone, public httpRequetService: HttpRequestService) { 
        //this.dateFormat = window as any['e12navigator'] ? (window as any)['e12navigator'].applDateFormat : localStorage.getItem('APPL_DATE_FORMAT');
        this.dateFormat = 'dd/MM/yyyy';
        (window as any)['LAST'] = this.LAST.bind(this);
        (window as any)['NEXT'] = this.NEXT.bind(this);
        (window as any)['QUARTER'] = this.QUARTER.bind(this);
        
        (window as any)['preloadDashboardMetadata'] = this.preloadDashboardMetadata.bind(this);
        (window as any)['preloadDashboardData'] = this.preloadDashboardData.bind(this);
    }
    
    private SERVICE_URL = '/ibase/rest/dashboard/metadata/';  // URL to web service
    
    dashboardDataSource: any={};
    //dashboardData;
    responseSubjects: any={};
    defaultSubtitle = "";
    dateFormat;
    selectedViewId: any;
    dashboardPageNoList: any = {};
    dashboardPageNo = 1;
    overlayRef: any;
    exploreReportSubj = new BehaviorSubject<any>({});
    exploreReportLayout = new BehaviorSubject<any>({});
    @Output() autoRefresh: EventEmitter<any> = new EventEmitter();
    loadedDashboardsList: any = [];
    userInfo: any;    
    
    dataSourcesStatus: any={};
    
    isNetwork = true;
    setNetwork(isNetwork: any)
    {
        this.isNetwork = isNetwork;
    }

    getDashboardMetadata (metadataName:string): Observable<any> 
    {
        var metadataUrl = this.getHostURL() + this.SERVICE_URL + metadataName;  
        var headers = new HttpHeaders({ 'Content-Type': 'application/json' });
        var options = { headers: headers };
        console.log( "getDashboardMetadata>>>>>" + metadataUrl); 
        
        var userName = localStorage.getItem('userName') || '';

        var dashboardMetadata = localStorage.getItem(metadataName+userName);
        this.dashboardPageNoList[metadataName] = this.dashboardPageNo++;
        
        if(dashboardMetadata){
            console.log("dashboard service found data in local storage");
            dashboardMetadata = JSON.parse(dashboardMetadata);
            //this.userInfo = dashboardMetadata['USER_INFO'];
            //Added by Pankaj T. on 24-08-2020 to resolved sensitive information disclosure from local storage vulnerability - start
            // Added by Pankaj R on 30-Sep-20 as trim() was not a function of object [START]
            //if( this.userInfo == null || this.userInfo == undefined || this.userInfo.trim().length == 0)
            if( this.userInfo == null || this.userInfo == undefined || Object.keys(this.userInfo).length === 0)
            // Added by Pankaj R on 30-Sep-20 as trim() was not a function of object [END]
            {
                var serverUrl = this.getHostURL() + "/ibase/rest/dashboard/getDashboardUserDetails";
              
                this.http.get<any>(serverUrl, options).pipe(
                    map((res: any) => this.extractData(res)))
                    .subscribe(
                        (response: any) => {
                            console.log('DASHBOARD_USER_DETAILS in dashboard service : ', response);
                            this.userInfo = response['DASHBOARD_USER_DETAILS'];
                        }
                    );
            }
            //Added by Pankaj T. on 24-08-2020 to resolved sensitive information disclosure from local storage vulnerability - end
            var dataHandler = new BehaviorSubject<any>(dashboardMetadata);
            return dataHandler;
        }
        
        return this.http.get<any>( metadataUrl, options)
                        .pipe(map( (res) => this.extractDashboardData(res, metadataName) ) );
    }
    //Added by sunny soni for native related change for handling server call [Start]
    getDashboardMetadataFromServer(metadataname:string, callBack:any) {
        var metadataUrl = this.getHostURL() + this.SERVICE_URL + metadataname;
        //Added by sunny soni for resolving quick access dashboard not loading issue on 12-JAN-21 [START]
        var httpHeaders = { 'Content-Type': 'application/json' }; 
        var userName = localStorage.getItem('userName') || '';        
        var dashboardMetadata = localStorage.getItem(metadataname+userName);        
        this.dashboardPageNoList[metadataname] = this.dashboardPageNo++;
        if(dashboardMetadata){
            console.log("dashboard data found in local storage");
            dashboardMetadata = JSON.parse(dashboardMetadata);
            if( this.userInfo == null || this.userInfo == undefined || Object.keys(this.userInfo).length === 0){
                var serverUrl = this.getHostURL() + "/ibase/rest/dashboard/getDashboardUserDetails";
                this.httpRequetService.sendHttpRequest('GET', httpHeaders, serverUrl, '', (response: any) => {            
                    var isJsonParsable = (string: any) => {
                    try {
                        JSON.parse(string);
                    } catch (e) {
                        return false;
                        }
                        return true;
                    }
                    if (isJsonParsable(response)) {                
                        response = JSON.parse(response);
                    }
                    console.log('DASHBOARD_USER_DETAILS in dashboard service : ', response);
                    this.userInfo = response['DASHBOARD_USER_DETAILS'];
                });
            }
            callBack(dashboardMetadata);
            return;
        }
        //Added by sunny soni for resolving quick access dashboard not loading issue on 12-JAN-21 [END]
       
        //var httpHeaders = { 'Content-Type': 'application/json' };    
        this.httpRequetService.sendHttpRequest('GET', httpHeaders, metadataUrl, '', (result: any) => {            
            var isJsonParsable = (string: any) => {
               try {
                   JSON.parse(string);
               } catch (e) {
                   return false;
                }
                return true;
            }
            if (isJsonParsable(result)) {                
                result = JSON.parse(result);
            }
            this.setResponseToLocalStrorage(result, metadataname);
            callBack(result);
        });        
    }
    //Modified by sunny soni for resolving quick access dashboard not loading issue on 12-JAN-20 [START]
    setResponseToLocalStrorage(responseData:any, metadataname:string) {
        var userName = localStorage.getItem('userName') || '';
        //console.log('StringInfy JSONData[' + JSON.stringify(responseData) + '] userName:['+userName+']');        
        this.userInfo = responseData['DASHBOARD_USER_DETAILS'];
        //Added by Pankaj T. on 24-08-2020 to resolved vulnerability sensitive information disclosure from local storage - start
        delete responseData['DASHBOARD_USER_DETAILS'];
        //Added by Pankaj T. on 24-08-2020 to resolved vulnerability sensitive information disclosure from local storage - end
        localStorage.setItem(metadataname+userName, JSON.stringify(responseData));
    }
    //Modified by sunny soni for resolving quick access dashboard not loading issue on 12-JAN-20 [END]
    //Added by sunny soni for native related change for handling server call [End]

    createDataSources(dashboardName: any,dataSourcesConfig: any, filters: any)
    {
        console.log('dataSourcesConfig in createDataSources::',dataSourcesConfig,dashboardName,filters);
        var dataSources: any = {};
        var defaultFilterString = "";
        if(filters && filters.filter)
        {
            console.log('dataSourcesConfig in createDataSources filters.filter::',filters.filter);
            var userName = localStorage.getItem('userName') || '';
            var metadataCache: any = localStorage.getItem(dashboardName+userName);
            var metadata = JSON.parse(metadataCache);
            metadata.filters = filters;
            localStorage.setItem(dashboardName+userName, JSON.stringify(metadata));
            
            filters.filter.forEach(
                    (filterVal: any) => {
                        console.log('dataSourcesConfig in createDataSources filterVal::',filterVal);
                        if(filterVal.type == "4" && filterVal.default_value){
                            var defaultDate = this.getDefaultDate(filterVal.default_value);
                            var defaultDateStr = this.formatDate(defaultDate);
                            console.log('Final defaultDateStr:',defaultDateStr);
                            defaultFilterString = defaultFilterString + filterVal.col_name + "=" + defaultDateStr + "&"
                        }
                        else if(filterVal.type == "6"){
                            var defaultYear = this.getDefaultYear(filterVal.default_value);
                            defaultFilterString = defaultFilterString + filterVal.col_name + "=" + defaultYear + "&"
                        }
                        else if(filterVal.type == "5"){
                            var defaultMonth = this.getDefaultMonth(filterVal.default_value);
                            
                            defaultFilterString = defaultFilterString + filterVal.col_name + "=" + defaultMonth + "&"
                        }
                        else if(filterVal.type == "7"){
                            var defaultSite = this.getDefaultSite(filterVal.default_value);
                            
                            defaultFilterString = defaultFilterString + filterVal.col_name + "=" + defaultSite + "&"
                        }
                        else {
                            defaultFilterString = defaultFilterString + filterVal.col_name + "=" + filterVal.default_value + "&"
                        }        
                     }
            );
            if( defaultFilterString.endsWith('&') )
            {
                defaultFilterString = defaultFilterString.slice(0, -1);
            }
            console.log('dataSourcesConfig in createDataSources defaultFilterString::',defaultFilterString);
        }
        
        if( dataSourcesConfig )
        {
            console.log('dataSourcesConfig in createDataSources ::');
            dataSourcesConfig.forEach(
                (dataSource: any) => {
                    console.log('dataSource in createDataSources ::',dataSource);
                    var dataSourceObj: any = {};
                    var id = dataSource.id;
                    dataSourceObj["url"] = "/ibase/"+dataSource.value;
                    dataSourceObj["type"] = dataSource.dataSourceType || dataSource.dataSourcetype;
                    dataSourceObj["defaultFilterString"] = defaultFilterString;
                    dataSourceObj["filterString"] = '';
                    dataSourceObj["value"] = dataSource.value;
                    dataSourceObj["scopeKey"] = dataSource.scopeKey;
                    dataSourceObj["filterKey"] = dataSource.filterKey;
                    dataSourceObj["filterExpr"] = dataSource.filterExpr;
                    dataSourceObj["callbackJSFunction"] = dataSource.callbackJSFunction;
                    dataSourceObj["dependency"] = dataSource.dependency;
                    dataSources[id] = dataSourceObj;
                    console.log('dataSource[id] in createDataSources ::',dataSources[id]);
                    
                    var defaultMsg = {"reponse": "loading"};
                    this.responseSubjects[dashboardName+"_"+id] = new BehaviorSubject<any>(defaultMsg);
                }
            );
        }
        console.log('dataSources in createDataSources::',dataSources);
        this.dashboardDataSource[dashboardName]=dataSources;
    }
    
    getDashboardData(dashboardName: any,datasourceId: any, filterParameter: any, isRefresh: any, isDrillDown: any, isFilterApplied: any): any
    {
        console.log('dataSourceURL in getDataSourceData >>',dashboardName, datasourceId, filterParameter, this.dashboardDataSource);
        var dataSources = this.dashboardDataSource[dashboardName];
        console.log('dataSources in getDataSourceData and responseSubjects>>',dataSources, this.responseSubjects );

        var dataSource = dataSources[datasourceId];
        var datasourceKey = dashboardName+"_"+datasourceId;
        var defaultMsg = {"reponse": "loading"};
        var respSubj: BehaviorSubject<any> = this.responseSubjects[datasourceKey];
        if(respSubj){
            respSubj.next(defaultMsg);
        }
        
        if(!dataSource)
        {
            var errorMsg = {"message": "Data Source Not FOund"};            
            var errorHandler = new BehaviorSubject<any>(errorMsg);
            
            return errorHandler;
        }
        
        if(dataSource.type.toLowerCase() == "servlet")
        {   
            //Changes By Prajyot 09FEB19 - For caching Servlet Datasource data on localstorage -Starts
            /*
            var dataSrcURL = this.buildDatasourceURL(dataSource, filterParameter);
 var headers = new Headers({ 'Content-Type': 'application/json' });
            var options = new RequestOptions({ headers: headers });
            this.http.get( dataSrcURL, options)
                            .map( (res) => this.extractData(res) ).subscribe(
                                       response => { 
                                           respSubj.next(response);
                                       }
                                    );
			*/                                    
            var userName = localStorage.getItem('userName') || '';
            var dataSrcURL = this.buildDatasourceURL(dataSource, filterParameter);
            var _dashboardDataStr: any = localStorage.getItem(dataSrcURL+'_'+userName); //Updated By Saitej D [On 20 June 2019] [To cache dashboard data with datasource parameters]
            var _dashboardData = JSON.parse(_dashboardDataStr);
            if( _dashboardData && !isRefresh && !isFilterApplied) //First Preference to Cache Data
            {
                console.log("For "+ dataSource.value+ " found dashboard data in local storage");
                respSubj.next(_dashboardData);
            }
            else if( this.isNetwork )
            {
                //var dataSrcURL = this.buildDatasourceURL(dataSource, filterParameter);
                //Added by sunny soni for native related change for handling server call [START]                
                var httpHeaders = { 'Content-Type': 'application/json' };
                this.httpRequetService.sendHttpRequest('GET', httpHeaders, dataSrcURL, '', (response: any) => {                    
                    var isJsonParsable = (string: any) => {
                        try {
                            JSON.parse(string);
                        } 
                        catch (e) {
                            return false;
                        }
                        return true;
                    }

                    if (isJsonParsable(response)) {                        
                        response = JSON.parse(response);
                    }                    
                    console.log("Setting data in local storage for "+ dataSource.value+ " datasource ");
                   if ( dashboardName.toLowerCase() == "brand-campaign" || dashboardName.toLowerCase() == "brand-doctor" || dashboardName.toLowerCase() == "ranking" || dashboardName.toLowerCase() == "so-brand-campaign" )
                   { 
                    	//localStorage.setItem(dataSrcURL+'_'+userName, JSON.stringify(response)); //Updated By Saitej D [On 20 June 2019] [To cache dashboard data with datasource parameters]
                   }
                   else
                   {
                   		localStorage.setItem(dataSrcURL+'_'+userName, JSON.stringify(response)); //Updated By Saitej D [On 20 June 2019] [To cache dashboard data with datasource parameters]
                   }
                    	
                    respSubj.next(response);
			        //Added by Prajyot on 230219 - For callback function after Datasource get downloaded
					this.evaluateCallbackFunctionIfExist(dataSource);                    
                });
                /* commented code by sunny soni for native related change for handling server call START
                var headers = new HttpHeaders({ 'Content-Type': 'application/json' });
                var options = { headers: headers };
                this.http.get<any>( dataSrcURL, options).pipe( map( (res) => this.extractData(res) ) ).subscribe(
                    response => { 
                        console.log("Setting data in local storage for "+ dataSource.value+ " datasource ");
                        localStorage.setItem(dataSrcURL+'_'+userName, JSON.stringify(response)); //Updated By Saitej D [On 20 June 2019] [To cache dashboard data with datasource parameters]
                        respSubj.next(response);
			            //Added by Prajyot on 230219 - For callback function after Datasource get downloaded
						this.evaluateCallbackFunctionIfExist(dataSource);
                    }
                );
                commented code by sunny soni for native related change for handling server call END
                */
            }
            else
            {
            	console.log('No Network');
            	respSubj.next(_dashboardData);
            }
            //Changes By Prajyot 09FEB19 - For caching Servlet Datasource data on localstorage -Ends
            
            return respSubj;
            
        }
        else if(dataSource.type.toLowerCase() == "datamodel")
        {
            console.log('dataSource.type >> datamodel ',dataSource.dependency, isRefresh, isDrillDown, isFilterApplied);
            if(dataSource.dependency && !isDrillDown)
            {
                var dependencies = dataSource.dependency.split(',');
                for(var dependency of dependencies)
                {
                    this.dataSourcesStatus[dependency] =  isRefresh || isFilterApplied;
                }
            }
            if( this.dataSourcesStatus[dataSource.value] )
            {
                isRefresh = this.dataSourcesStatus[dataSource.value];
                this.dataSourcesStatus[dataSource.value] = false;
            }
            console.log('this.dataSourcesStatus:', this.dataSourcesStatus);
                        
            this.dashboardDatamodelService.getDataModelData(dataSource.value, filterParameter, dataSource.scopeKey, isRefresh, isDrillDown, isFilterApplied).subscribe(
                    resp => {
                        this.responseSubjects[datasourceKey].next(resp);
			            //Added by Prajyot on 230219 - For callback function after Datasource get downloaded
						//this.evaluateCallbackFunctionIfExist(dataSource);
						this.evaluateCallbackFunctionIfExistDM(dataSource, this.responseSubjects[datasourceKey]);
                    }
            );
            
            return respSubj;
        }
        else if(dataSource.type.toLowerCase() == "jsondata")
        {
            console.log('dataSource.type >> jsondata');
            var _dashboardData = JSON.parse(dataSource.value);
            if(_dashboardData && _dashboardData.preload_functions)
            {
                this.preloadCallback = ((isRefresh: any) => {
                    console.log("For "+ dataSource.type+ " found preload_functions isRefresh["+isRefresh+"]");
                    
					// Added By Saitej D on 7Mar19
					if(isRefresh)
                    {
                        this.autoRefresh.emit();
                    }
					// Added By Saitej D on 7Mar19
                    respSubj.next(_dashboardData);
                });
                (window as any)['preloadCallback'] = this.preloadCallback.bind(this);
                _dashboardData.preload_functions.map( (preload_function: any) => {
                    eval(preload_function);
                } );
            }   
            else
            {
                console.log("For "+ dataSource.type+ " not found preload_functions ");
                respSubj.next(_dashboardData);
            }                            
            return respSubj;
        }
    }
    
    private buildDatasourceURL(dataSource: any, filterParameter: any) : string
    {
        var dataSrcURL = '';
        console.log('buildDatasourceURL >>', dataSource, filterParameter );
        if( filterParameter )
        {
            dataSrcURL = this.getHostURL()+dataSource.url + "?" + filterParameter;
        }
        else if(dataSource.defaultFilterString)
        {
            dataSrcURL = this.getHostURL()+dataSource.url + "?" + dataSource.defaultFilterString;
        } 
        else 
        {
            dataSrcURL = this.getHostURL()+dataSource.url;
        }
        console.log('buildDatasourceURL >>', dataSrcURL);
        return dataSrcURL;
    }
    
    private extractData(res: HttpResponse<any>) 
    {
        console.log('extractData[' + JSON.stringify(res) + ']');
        return res || { };
    }
    
    private extractDashboardData(res: HttpResponse<any> | any, metadataName: any) {
       // var body = res.json();
        var userName = localStorage.getItem('userName') || '';
        console.log('extractData[' + JSON.stringify(res) + '] userName:['+userName+']');
     
        //this.userInfo = res['USER_INFO'];
        this.userInfo = res['DASHBOARD_USER_DETAILS'];
        //Added by Pankaj T. on 24-08-2020 to resolved vulnerability sensitive information disclosure from local storage - start
        delete res['DASHBOARD_USER_DETAILS'];
        //Added by Pankaj T. on 24-08-2020 to resolved vulnerability sensitive information disclosure from local storage - end
        localStorage.setItem(metadataName+userName, JSON.stringify(res));
        return res || { };
    }

    private handleError (error: HttpErrorResponse | any) {
        var errMsg: string;
        if (error instanceof HttpErrorResponse)//(error.error instanceof ErrorEvent)//error instanceof Response
        {
            //const body = error.json() || '';
            //const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''}`; //${err}`;
        }
        else
        {
	    errMsg = error.message ? error.message : error.toString();
           // errMsg = error.message ? error.message : error.toString();
        }
        console.error('Service handleError:' + errMsg);
        // return Observable.throw(errMsg);
        return throwError(errMsg);
    }
    
    public getHostURL(): string {
        // var HOST_URL: string = '';
        var HOST_URL: any = '';
        HOST_URL = localStorage.getItem( 'HOST_URL' );
        //if ( !HOST_URL ) HOST_URL = '';
        //Added by sunny soni for native related change for handling server call[Start]
        if ( !HOST_URL ) {
            HOST_URL = '';
            HOST_URL = localStorage.getItem( 'host_url' );
            //Added for set host url on local storage on 19-JAN-21 [START]
            if (HOST_URL) {                
                localStorage.setItem('HOST_URL', HOST_URL);
            }
            //Added for set host url on local storage on 19-JAN-21 [END]
            if ( !HOST_URL ) HOST_URL = '';  
        }
        //Added by sunny soni for native related change for handling server call[End]
        console.log( 'getHostURL[', HOST_URL, ']' );
        return HOST_URL;
    }
  
    getDashboardSubtitle(dashboardData: any){
          var subTitle = "";
          console.log('dashboardData in getDashboardSubtitle',dashboardData);
          if(dashboardData.sub_title){
              var subTitleOpts = dashboardData.sub_title.split(',');
              subTitle = this.getDefaultSubtitle(subTitleOpts) + " ";
          }
          
          if (dashboardData.filters && dashboardData.filters.filter){
              dashboardData.filters.filter.forEach(
                (filter: any) => {
                    if(filter.default_value && filter.show_ontitle == "1"){
                        if(subTitle){
                            subTitle = subTitle + ", "
                        }
                        if(filter.type == '4')
                        {
                             var defaultDate = this.getDefaultDate(filter.default_value);
                             var defaultDateStr = this.formatDate(defaultDate);
                             subTitle = subTitle + filter.col_descr + " " + defaultDateStr;                 
                        }
                        else if(filter.type == '6')
                        {
                            var defaultYear = this.getDefaultYear(filter.default_value);
                            subTitle = subTitle + filter.col_descr + " " + defaultYear;
                        }
                        else if(filter.type == "5"){
                            var defaultMonth = this.getDefaultMonth(filter.default_value);
                            
                            subTitle = subTitle + filter.col_descr + " " + defaultMonth;
                        }
                        else 
                        {
                            subTitle = subTitle + filter.col_descr + " " + filter.default_value;
                        }
                    }
                }      
              );
          }
      
          return subTitle;
    }
  
    private getDefaultSubtitle(subTitleOpts: any){
      if(subTitleOpts){
      subTitleOpts.forEach(
              (opt: any) => {
                  switch(opt){
                      case "CURRENT_MONTH" :
                          var curr_month = new Date().toLocaleString( "en-us", { month: "long" });
                          this.defaultSubtitle = this.defaultSubtitle + curr_month + " ";
                          break;
                      case "CURRENT_YEAR" :
                          var curr_year = new Date().getFullYear();
                          this.defaultSubtitle = this.defaultSubtitle + curr_year + " ";
                          break;
                      default :
                          this.defaultSubtitle = opt;
                  }
              }
      );
      }
      return this.defaultSubtitle;
   }
    
    formatDate( dateValue: any ): any {
        var changedValue: any = '';
        if ( this.dateFormat ) {
            try {
                changedValue = this.datePipe.transform( dateValue, this.dateFormat );
            }
            catch ( e ) {
                console.log('Inside for data exception ',e);
                //changedValue = this.datePipe.transform( dateValue, 'dd/MM/yyyy' );
                changedValue = this.datePipe.transform( new Date(), this.dateFormat );
                
            }
        }
        else {
            changedValue = this.datePipe.transform( dateValue, 'dd/MM/yyyy' );
        }
        return changedValue;
    }
    
    setSelectedViewId(id: any){
        this.selectedViewId = id;
    }
    
    getSelectedViewId(){
        return this.selectedViewId;
    }
    
    invokeDashboardLink(link: any, feedData: any, obj_name: any) {
        var pkFieldValue = '';
        var jsonStr:string='';
        console.log('invokeDashboardLink ',link, feedData, obj_name);
        if(feedData){
             jsonStr = JSON.stringify(feedData);
             jsonStr = jsonStr.replace(/[{}]/g, "").trim();
             jsonStr = jsonStr.replace(/\"/g,"");// Added by Pravin k on 04-OCT-18 [To remove quotes from json-string].
             console.log('feed data jsonStr : ',jsonStr);

             var linkArgArray = link.LinkArg.split(',');
             console.log('LinkArgArray',linkArgArray);
             if(linkArgArray){
                 linkArgArray.forEach(
                       (arg: any) => {
                         var colName = arg.substring(0, arg.indexOf('.'));
                         pkFieldValue = pkFieldValue + feedData[colName] + ':';
                         console.log('colName: ['+colName+'] pkFieldValue: ['+pkFieldValue+']');
                       }
                 );
         }           
        }

        
        var response = {
                "linkInfo" : link,
                "pkFieldValue" : pkFieldValue,
                "objName" : obj_name,
                "isAnyRowSelected": true,
                "feedData" : jsonStr
        }
    
        invokeDashboardLink(response);
    }
    
    getDefaultDate(value: string)
    {
        var defaultDate = new Date();
        console.log('value :::', value,'  default date :::::',defaultDate);
        try 
        {
            //if(value && ( value.startsWith('LAST') || value.startsWith('NEXT') ) )
            if(value && ( value.startsWith('LAST') || value.startsWith('NEXT') || value.startsWith('QUARTER') ) )
            {
                console.log('---Starts with LAST or NEXT ---');
                defaultDate = eval(value);
            }
            else if(value && value == 'CURRENT_DATE'){
                defaultDate = new Date();
            }
            else if(value)
            {
				if(value.includes('/'))
				{
					let splitDate = value.split('/');
					value = splitDate[1]+'/'+splitDate[0]+'/'+splitDate[2];
				}
				console.log('VALUE.... ',value);
                //defaultDate = new Date();
				console.log('Inside else part of date .. ',(this.datePipe.transform( value, 'dd/MM/yyyy' )));
				//defaultDate = new Date(this.datePipe.transform( value, 'dd/MM/yyyy' ));
				defaultDate = new Date(value);
                console.log('This case should never happened defaultDate',defaultDate);
            }
	    else
	    {
			defaultDate = new Date();
	    }
            
        } 
        catch (e)
        {
        	console.log('Exception in getDefaultDate',e);
        }
        
        console.log('In getDefaultDate',defaultDate);
        return defaultDate;
    }
    
    
    getDefaultSite(value: string)
    {
        var defaultSite;
        console.log('getDefaultSite value :::', value);
        try 
        {
            if(value  )
            {
                console.log('---Starts with LAST or NEXT ---');
                defaultSite = '1.'+value;
            }
        } 
        catch (e)
        {
            console.log('Exception in getDefaultSite',e);
        }
        
        console.log('In defaultSite',defaultSite);
        return defaultSite;
    }
    
    getDefaultFilterParam(dashboardName: any,datasourceId: any)
    {
        var dataSources = this.dashboardDataSource[dashboardName];
        console.log('In getDefaultFilterParam >>>',dashboardName,datasourceId,this.dashboardDataSource );
        var dataSource = dataSources[datasourceId];
        var defaultFilterString = dataSource.defaultFilterString;
        console.log('defaultFilterString',defaultFilterString);
        
        return defaultFilterString;
    }
    
    LAST(count: any, type: any)
    {
        console.log('In LAST',count,type);
        var defaultDate: Date = new Date();

        try 
        {            
            switch(type)
            {
                case "M" :
                    defaultDate.setMonth(defaultDate.getMonth() - parseInt(count));
                    defaultDate.setDate(1);
                    break;            
            }
        }
        catch(e) 
        {
            console.log('Exception in LAST',e);
        }
        console.log('Default date::',defaultDate);
        
        return defaultDate;
    }
    
    NEXT(count: any, type: any)
    {
        console.log('In NEXT',count,type);
        var defaultDate: Date = new Date();
        
        try 
        {            
            switch(type)
            {
                case "M" :
                    defaultDate.setMonth(defaultDate.getMonth() + parseInt(count));
                    var lastDayOfMonth = new Date(defaultDate.getFullYear(), defaultDate.getMonth() + 1, 0).getDate();
                    defaultDate.setDate(lastDayOfMonth);
                    break;
            }
        }
        catch(e) 
        {
            console.log('Exception in NEXT',e);
        }
        console.log('Default date::',defaultDate);
        
        return defaultDate;
    }
    
    //Get Start and End date of current quarter [ Calender Quarters ]
	//TODO : Financial Calender Quarter
	QUARTER(type: any)
    {
		var quarters = [[0,1,2],[3,4,5],[6,7,8],[9,10,11]];
        var defaultDate: Date = new Date();
        //quarter_of_the_year
        var month = defaultDate.getMonth() + 1;
        var qurtOfYear = (Math.ceil(month / 3));//Get Current Quarter of Current Year
        console.log('In QUARTER',type, month,qurtOfYear);
               
        try 
        {            
            switch(type)
            {
                case "START" :
                    defaultDate.setMonth( quarters[qurtOfYear-1][0] );
                    var dayOfQuart = new Date(defaultDate.getFullYear(), defaultDate.getMonth() + 1, 1).getDate();
                    defaultDate.setDate(dayOfQuart);
                    break;
                case "END" :
                    defaultDate.setMonth( quarters[qurtOfYear-1][2] );
                    var dayOfQuart = new Date(defaultDate.getFullYear(), defaultDate.getMonth() + 1, 0).getDate();
                    defaultDate.setDate(dayOfQuart);
                    break;
                case "MTD" :
                    defaultDate = new Date();
                    break;
            }
        }
        catch(e) 
        {
            console.log('Exception in QUARTER',e);
        }
        console.log('Default date::',defaultDate);
        
        return defaultDate;
    }
    
    getDefaultYear(value:string){
        
        var defaultYear;
        
        switch(value)
        {
            case "CURRENT_YEAR" :
                var currDate = new Date();
                defaultYear = currDate.getFullYear();
                break;
            default :
                if(value){
                    defaultYear = value;
                }else {
                    var currDate = new Date();
                    defaultYear = currDate.getFullYear();
                }
        }
        
        console.log('defaultYear ::',defaultYear);
        return defaultYear;
    }
    
    
    getDefaultMonth(value:string){
        console.log('dafault month ',value);
        var defaultMonth;
        var currDate: any;
        
        switch(value)
        {
            case "CURRENT_MONTH" :
                currDate = new Date();
                defaultMonth = currDate.getMonth() +1;
                if (defaultMonth < 10) defaultMonth = '0' + defaultMonth;
                break;
            default :
                if(value){
                    defaultMonth = value;
                }else {
                    currDate = new Date();
                    defaultMonth = currDate.getMonth() +1;
                    if (defaultMonth < 10) defaultMonth ='0' + defaultMonth;
                }
        }
        
        console.log('defaultMonth >>>>',defaultMonth);
        defaultMonth = defaultMonth + '/' + currDate.getFullYear();
        console.log('defaultMonth ::',defaultMonth);
        return defaultMonth;
    }
    
    invokeLinkInfo: any;
    invokeAngCompLink(link: any, feedData: any, obj_name: any, templatePortal: any, compData: any){
        
        console.log('In invoke invokeAngCompLink',link,templatePortal);
        this.invokeLinkInfo = link;
        var targetId = link.TargetObject+'_popup';
        this.createOverlay(targetId, templatePortal);
        var configData: any = {};
        configData["componentName"] = link.TargetObject;
        configData["targetId"] = targetId;
        configData["cacheComp"] = false;
        configData["data"] = compData;
        configData["feedData"] = feedData;//Added by Pravin K on 4-FEB-20
        
        
        if( link.LinkForm == "LINK" )
        {
            loadComponent(link.TargetObject, JSON.stringify(configData), link.callBack);
        }
        else if( link.LinkForm == "DASHBOARD" )
        {
            loadAngularDashboard(link.TargetObject, JSON.stringify(configData));
        }
    }
    
    createOverlay(targetId: any, templatePortal: any){
        var config = new OverlayConfig();
        config.hasBackdrop = true;
        config.positionStrategy = this.overlay.position()
            .global()
            .width('100%')
            .height('100%');

        this.overlayRef = this.overlay.create(config);

        var el = document.createElement("div");
        el.setAttribute("id", targetId);
        el.setAttribute("class", 'popup-overlay-containt');

        var closeBtnEl = document.createElement("div");
        closeBtnEl.innerText = 'x';
        closeBtnEl.setAttribute("class", 'popup-overlay-close');
        closeBtnEl.addEventListener("click", this.onClose.bind(this));

        this.overlayRef.overlayElement.appendChild(el);
        this.overlayRef.overlayElement.appendChild(closeBtnEl);
        console.log('overlayRef',this.overlayRef);

        this.overlayRef.attach(templatePortal);
    }

    onClose(){
        if(this.overlayRef != null)
        {
            this.overlayRef.dispose();
		// To destroy component created dynamically - Starts 
        console.log('invokeLinkInfo in onClose function',this.invokeLinkInfo);
        if( this.invokeLinkInfo && this.invokeLinkInfo.LinkForm == "LINK" )
        {
            destroyComponent(this.invokeLinkInfo.TargetObject);
        }
        else if( this.invokeLinkInfo && this.invokeLinkInfo.LinkForm == "DASHBOARD" )
        {
            detroyDashboard(this.invokeLinkInfo.TargetObject);
        }

        }
        this.overlayRef = null;
        console.log('this.overlayRef '+this.overlayRef)
        
		// To destroy component created dynamically - Ends
    }
/*    
    saveExploreReport(reportName, reportConfig)
    {
        var serverUrl = this.getHostURL() + "/ibase/rest/exploreReport/saveExploreReport/"+reportName;
        var reportConfigStr = JSON.stringify( reportConfig );
        
        localStorage.setItem(reportName, reportConfigStr);
        
 var headers = new Headers({ 'Content-Type': 'application/json' });
        var options = new RequestOptions({ headers: headers });
        this.http.post( serverUrl, reportConfigStr, options)
                 .map( (res) => this.extractData(res) ).subscribe(
                       response => { 
                          console.log('Response In saveExploreReport'+response);
                       }
                  );
    }
    
    getExploreReport(reportName)
    {
        var reportConfig = localStorage.getItem( reportName );
        var reportJson;
        if(reportConfig && reportConfig != null && reportConfig.trim())
        {
           reportJson = JSON.parse(reportConfig);
           this.exploreReportSubj = new BehaviorSubject<any>(reportJson);
        }
        else
        {
            var serverUrl = this.getHostURL() + "/ibase/rest/exploreReport/getExploreReport/"+reportName;
                        var headers = new Headers({ 'Content-Type': 'application/json' });
            var options = new RequestOptions({ headers: headers });
            this.http.get( serverUrl , options) 
                     .map( (res) => this.extractData(res) )
                     .subscribe(
                                 response => {
                                   if(response.result == 'success')
                                   {
                                       var report = response.report;
                                       localStorage.setItem(reportName, JSON.stringify( report ));
                                       console.log('----report',report);
                                       this.exploreReportSubj.next(report);
                                   }
                                   else 
                                   {
                                       this.exploreReportSubj.next('');
                                   }
                                 }
                                );
        }
                        
        return this.exploreReportSubj;              
    }
*/
	preloadDashboardMetadata (metadataName:string)
    {
        if(this.isNetwork)
        {
            var metadataUrl = this.getHostURL() + this.SERVICE_URL + metadataName;  
            var headers = new HttpHeaders({ 'Content-Type': 'application/json' });
            var options = { headers: headers };
            console.log( "getDashboardMetadata>>>>>" + metadataUrl); 
           
            var userName = localStorage.getItem('userName') || '';
            var dashboardMetadata = localStorage.getItem(metadataName+userName);
            if(!dashboardMetadata)
            {
                console.log("preloadDashboardMetadata dashboard metadata not found in local storage");
                this.http.get<any>( metadataUrl, options).pipe( map( (res) => this.extractDashboardData(res, metadataName) ) ).subscribe(
                    response => {
                    }
                );
            }
        }

    }
    preloadDashboardData (dataSource:any)
    {
        //var dataSource = {'url' : servletUrl / NA, 'value' : servletUrl / datamodelname, 'type' : servlet/datamodel}
        if(this.isNetwork)
        {
            if(dataSource.type.toLowerCase() == "servlet")
            {
                var userName = localStorage.getItem('userName') || '';
                var _dashboardDataStr: any = localStorage.getItem(dataSource.value+'_'+userName);
                var _dashboardData = JSON.parse(_dashboardDataStr);
                
                //Changed by Sonam K on 27-AUG-20 [To update My Places dashboard card count on save]
                var dataSrcURL = this.buildDatasourceURL(dataSource, '');
                //Added by sunny soni for native related change for handling server call [Start]                
                var httpHeaders = { 'Content-Type': 'application/json' };
                this.httpRequetService.sendHttpRequest('GET', httpHeaders, dataSrcURL, '', (response: any) => {
                    var isJsonParsable = (string: any) => {
                        try {
                            JSON.parse(string);
                        } 
                        catch (e) {
                            return false;
                        }
                        return true;
                    }
                    if (isJsonParsable(response)) {
                        response = JSON.parse(response);
                    }                    
                    console.log("[preloadDashboardData] Setting data in local storage for "+ dataSource.value+ " datasource ");
                    localStorage.setItem(dataSource.value+'_'+userName, JSON.stringify(response));
                    this.preloadCallback();
                    this.evaluateCallbackFunctionIfExist(dataSource);                    
                });
                //Added by sunny soni for native related change for handling server call [End]
                //var headers = new Headers({ 'Content-Type': 'application/json' });
                //var options = new RequestOptions({ headers: headers });
                /* commented by sunny soni for native related change for handling server call START 
                var headers = new HttpHeaders({ 'Content-Type': 'application/json' });
                var options = { headers: headers };
                
                this.http.get<any>( dataSrcURL, options).pipe( map( (res) => this.extractData(res) ) ).subscribe(
                    response => { 
                        console.log("Setting data in local storage for "+ dataSource.value+ " datasource ");
                        localStorage.setItem(dataSource.value+'_'+userName, JSON.stringify(response));
                        this.preloadCallback();
                        this.evaluateCallbackFunctionIfExist(dataSource);
                    }
                );
                commented by sunny soni for native related change for handling server call END 
                    */
                //Changed by Sonam K on 27-AUG-20 [To update My Places dashboard card count on save]
                
                /*
                if( _dashboardData ) //First Preference to Cache Data
                {
                    console.log("Inside preloadDashboardData For "+ dataSource.value+ " found dashboard data in local storage");
                    this.preloadCallback();
                }
                else
                {
                    var dataSrcURL = this.buildDatasourceURL(dataSource, '');
                    var headers = new HttpHeaders({ 'Content-Type': 'application/json' });
                    var options = { headers: headers };
                    this.http.get<any>( dataSrcURL, options).pipe( map( (res) => this.extractData(res) ) ).subscribe(
                        response => { 
                            console.log("Setting data in local storage for "+ dataSource.value+ " datasource ");
                            localStorage.setItem(dataSource.value+'_'+userName, JSON.stringify(response));
                            this.preloadCallback();
                            this.evaluateCallbackFunctionIfExist(dataSource);
                        }
                    );
                }
                */
            }
            else if(dataSource.type.toLowerCase() == "datamodel")
            {
                //this.dashboardDatamodelService.preloadDataModel(dataSource.value, false);
                this.dashboardDatamodelService.preloadDataModel(dataSource.value, false).subscribe(preloadData =>{
                    console.log('preloadData', preloadData);
                    this.evaluateCallbackFunctionIfExistDM(dataSource, preloadData);
                });
            }
        }
        else
        {
            this.preloadCallback();
        }
    }
    
    preloadCallback : any;
    
    getFilteredDashboardData(dashboardName: any, datasourceId: any, filterParameter: any, dashboardData: any) : any
    {
        var retData = dashboardData;
        var dataSources = this.dashboardDataSource[dashboardName];
        //console.log('In getDashboardDatasource >>>',dashboardName,datasourceId,this.dashboardDataSource );
        var dataSource = dataSources[datasourceId];
        console.log('getDashboardDatasource datasource::',dataSource);
        // Added by Pankaj R on 31-OCT-20 to filter data on multiple filter keys on drildown [START]
        //if( dataSource && dataSource.filterKey && filterParameter && filterParameter.indexOf(dataSource.filterKey) >= 0 )
        if( dataSource && dataSource.filterKey && filterParameter)
        {
            var _filterKey = dataSource.filterKey;
            var filterKeys = _filterKey.split(',');

            var filterExpr = dataSource.filterExpr;
            if( filterExpr )
            {
                filterExpr = this.replaceAll( filterExpr, " and ", " && " );
                filterExpr = this.replaceAll( filterExpr, " or ", " || " );
            }

            for(var filterKey of filterKeys)
            {
                if( filterParameter.indexOf(filterKey) >= 0 )
        		{
                    //var filterKey = dataSource.filterKey;
                    console.log('filterParameter :: ',filterParameter);
            		var filterParmsArray = filterParameter.split('&').filter( (x: any) => { return x.startsWith(filterKey+'=') } );
                    console.log('filterParmsArray :: ',filterParmsArray);
            		var filterVal = filterParmsArray[0];
                    
		    		console.log('getFilteredDashboardData dashboardData + filterVal', filterKey, filterExpr, filterVal, dashboardData);
            		if( filterVal )
            		{
                		filterVal = filterVal.replace(filterKey+'=', '');
                		//retData = dashboardData[filterVal];
                		console.log('getFilteredDashboardData filterVal [', filterVal, ']');
                        if( filterExpr )
                		{
                    		filterExpr = filterExpr.replace( '$' + filterKey, filterVal);
                    		console.log('getFilteredDashboardData filterExpr [', filterExpr, ']');
                            // retData = dashboardData.filter((context) => {
                            //     return eval(filterExpr);
                            // });
                		}
                		else
                		{
                    		retData = dashboardData[filterVal];
                		}
            		} 
                    console.log('filterExpr Inside for loop..',filterExpr)
                }
            }
            console.log('filterExpr outiside for loop..',filterExpr)
            if( filterExpr && filterExpr.indexOf("$") == -1 && dashboardData.filter)
            {
                retData = dashboardData.filter((context: any) => {
                    return eval(filterExpr);
                });
            }
            // Added by Pankaj R on 31-OCT-20 to filter data on multiple filter keys on drildown [END]
        }
        console.log('getFilteredDashboardData retData', retData);
        return retData ? retData : dashboardData;
    } 
    
	//Added By Prajyot on 23/02/19 to Update Cache DCR Data by referring Todays Dashboard Data - Starts 
    evaluateCallbackFunctionIfExist(dataSource: any)
    {
        if(dataSource && dataSource.callbackJSFunction)
        {
            console.log("Evaluating callbackJSFunction for "+ dataSource.value+ " datasource ");
            try 
            {
                eval(dataSource.callbackJSFunction +'()');
            }
            catch(e)
            {
                console.log("Exception while Evaluating callbackJSFunction for "+ dataSource.value+ " datasource ");
            }
        }
    }
    evaluateCallbackFunctionIfExistDM(dataSource: any, data: any)
    {
        console.log('inside evaluateCallbackFunctionIfExistDM ', dataSource);
        if(dataSource && dataSource.callbackJSFunction)
        {
            console.log("Evaluating callbackJSFunction DM for "+ dataSource.value+ " datasource ");
            try 
            {
                //updateCacheDatamodel(dataSource.value, data, this.zone );
                eval(dataSource.callbackJSFunction +'(dataSource.value, data, this.zone)');
            }
            catch(e)
            {
                console.log("Exception while Evaluating callbackJSFunction for "+ dataSource.value+ " datasource ", e);
            }           
        }
    }
	//Added By Prajyot on 23/02/19 to Update Cache DCR Data by referring Todays Dashboard Data - Ends 

    getUserInfo(){
        return this.userInfo;
    }

    saveExploreReport(objName: any, reportName: any, reportConfig: any) {
        var serverUrl = this.getHostURL() + "/ibase/rest/exploreReport/" + objName + "/" + reportName;
        var reportConfigStr = JSON.stringify(reportConfig);

        var reportKey = objName + '_' + reportName;
        localStorage.setItem(reportKey, reportConfigStr);

        var headers = new HttpHeaders({ 'Content-Type': 'application/json' });
        var options = { headers: headers };
        this.http.post<any>(serverUrl, reportConfigStr, options)
            .pipe( map((res: any) => this.extractData(res)) ).subscribe(
                response => {
                    console.log('Response In saveExploreReport' + response);
                    this.getAllLayoutByObject(objName, true);
                }
            );
    }
    
    deleteExploreReport(objName: any, prefName: any)  
    {
            var serverUrl = this.getHostURL() + "/ibase/rest/deleteExploreReport/" + objName + "/" + prefName;
            var reportKey = objName + '_' + prefName;
            var headers = new HttpHeaders({'Access-Control-Allow-Methods': 'DELETE'});
            var options = { headers: headers };
            
            
            return this.http.delete<any>( serverUrl, options)
            .pipe( map((res: any) =>this.extractData(res)) ).subscribe(
                    response => {
                        console.log('Response In saveExploreReport' + response);
                        this.getAllLayoutByObject(objName, true);
                    }
           );
    }

    getExploreReport(userId: any, objName: any, reportName: any) {
        var reportKey = objName + '_' + reportName;
        var reportConfig = localStorage.getItem(reportKey);
        var reportJson;
        if (reportConfig && reportConfig != null && reportConfig.trim()) {
            reportJson = JSON.parse(reportConfig);
            this.exploreReportSubj = new BehaviorSubject<any>(reportJson);
        }
        else {
            var serverUrl = this.getHostURL() + "/ibase/rest/exploreReport/"+userId+ "/" + objName + "/" + reportName;
            var headers = new HttpHeaders({ 'Content-Type': 'application/json' });
            var options = { headers: headers };
            this.http.get<any>(serverUrl, options)
                .pipe( map((res: any) => this.extractData(res)) )
                .subscribe(
                    (response: any) => {
                        //Channge by shrutika on 26-02-2021 for bydefault layout not open in flex monaster, Issue occur beacuse of body not present in V9.
                         var strData = JSON.stringify(response);
                        var newData = JSON.parse(strData);
                        //if (((<any>response)._body)['result'] == 'success') {
                        if (newData['result'] == 'success') {
                            var report = response['report'];
                            localStorage.setItem(reportKey, JSON.stringify(report));
                            console.log('----report', report);
                            this.exploreReportSubj.next(report);
                        }
                        else {
                            this.exploreReportSubj.next('');
                        }
                    }
                );
        }

        return this.exploreReportSubj;
    }

    getAllLayoutByObject(objName: any, isRefresh: any) {

        var userName = localStorage.getItem('userName') || '';
        var reportKey = 'RPTLAYOUT_' + objName+userName;
        var reportConfig = localStorage.getItem(reportKey);
        var reportJson;
        if (reportConfig && reportConfig != null && reportConfig.trim() && !isRefresh) {
            reportJson = JSON.parse(reportConfig);
            this.exploreReportLayout = new BehaviorSubject<any>(reportJson);
        }
        else {
            var serverUrl = this.getHostURL() + "/ibase/rest/exploreReport/"+objName+"/layouts";
            var headers = new HttpHeaders({ 'Content-Type': 'application/json' });
            var options = { headers: headers };
            this.http.get<any>(serverUrl, options)
                .pipe( map((res: any) => this.extractData(res)) )
                .subscribe(
                    response => {
                        console.log(' ',response);
                        //Channge by shrutika on 26-02-2021 for bydefault layout not open in flex monaster, Issue occur beacuse of body not present in V9.
                        var strData = JSON.stringify(response);
                        var newData = JSON.parse(strData);
                        //if (((<any>response)._body)['result'] == 'success') {
                        if (newData['result'] == 'success') {
                            var report = response;
                            localStorage.setItem(reportKey, JSON.stringify( report ));
                            console.log('----report', report);
                            this.exploreReportLayout.next(report);
                        }
                        else {
                             //Channge by shrutika on 26-02-2021 for bydefault layout not open in flex monaster, Issue occur beacuse of body not present in V9.
                            //console.log('----Failure', ((<any>response)._body)['result']);
                            console.log('----Failure', newData['result'] );
                            this.exploreReportLayout.next('');
                        }
                    }
                );
        }
        return this.exploreReportLayout;
    }

    //Added by Prasad on 01/06/2020 [added multiple condition to filter from json] START
    /* Define function for escaping user input to be treated as a literal string within a regular expression */
    escapeRegExp(string: any){
        return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    }
            
    /* Define functin to find and replace specified term with replacement string */
    replaceAll(str: any, term: any, replacement: any) {
        return str.replace(new RegExp(this.escapeRegExp(term), 'g'), replacement);
    }
    //Added by Prasad on 01/06/2020 [added multiple condition to filter from json] END

}
