import { Injectable, ElementRef, ChangeDetectorRef, EventEmitter, Output, NgZone } from '@angular/core';
import { HttpHeaders, HttpClient, HttpParams } from '@angular/common/http';
import { FormGroup, FormControl } from '@angular/forms';
import { BehaviorSubject, Observable } from 'rxjs';
import { BISResponse } from './bis-response';
import { BISDatamodelService } from './bis-datamodel.service';
import { DatePipe } from '@angular/common';
declare let plugins: any;
declare let callOpenTransaction: any;

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

  private conversation = new BehaviorSubject<BISResponse[]>([
    //new BISResponse( "vision", "Hi User! I'm your Vision Assistant. <br/> How can I help you ?" ),
  ]);

  private intentsDM = new BehaviorSubject<any>({});
  private userIntents: any = [];
  private formGroup: FormGroup | any;
  private formElement: ElementRef | any;

  private inputSuggestion = new BehaviorSubject<any>({});
  private inputSuggestionDM: any = {};
  private inputDMRequest: any = {};

  private requestMap = new Map<string, BISResponse>();
  private identity: string = "";

  private invokeIntentSubmit = new BehaviorSubject<any>(false);
  //Added by sadique shaikh 10-07-2019[To get and set pref value]
  public userPref:any

  //Added by Prasad on 27/08/18 [updating data after datamodel reponse]
  public chgDetectorRef: ChangeDetectorRef | any;

  //Added by Prasad on 19/10/18  [to handle fallback response]
  private fallbackIntentId = new BehaviorSubject<any>("");
  //Added by Sianath T. on 02/01/2018 [For date picker implementation]
  dateFormat = "dd/MM/yy";
  //Added by Pratheek on 18-06-19[using the new variable so to differentiate the Welcome screen and Quick Action Pamel]-START
  objNameDummy:string = "";
  objNameDataValue:string | any;
  multipleSubstrictions:any = {};
  invokeIntentOnSubmit:any = {};
  inputFieldSuggestions: any= {};
  converstations:any={};
  intentDM:any ={};
  intentSelectionSubscr:any = {};
  //Added by Pratheek on 18-06-19[using the new variable so to differentiate the Welcome screen and Quick Action Pamel]-End
  //For Speech listener start after login -Start
  @Output() startListener: EventEmitter<any> = new EventEmitter();
  public osType: string | any;
  public isBrowser: boolean = false;
  //Added by Sainath T. on 07-08-19 [To implement push notification]
  notificationRequest: string = "";
  notificationResponse: any = {};
  formValueEntities: any = {};//will be received When AI entity detection fails
  callFromProteusVision: boolean = false; // To set the Css ass per the application
  fallbackIntent_: boolean = false; // to filter intents on intent id if its a fallback intent
  iOSBusyError: any = {};//Used in Speech recognition component
  //For Speech listener start after login -End
  constructor(public http: HttpClient, public datamodelService: BISDatamodelService, public datePipe: DatePipe, public zone: NgZone,) { }
  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
  getMessages(id: any): Observable<BISResponse[]> {
    // return this.conversation['bi_assistant_'+id].asObservable();
    return this.converstations['bi_assistant_'+id].asObservable();
  }
  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
  //Added by Pratheek on 18-06-19[created a new BehaviourObject so to differentiate the Welcome screen and Quick Action Pamel]-Start
  loadComponentData( id: any )
  {
    this.multipleSubstrictions['bi_assistant_'+id] = new BehaviorSubject<any>(""); 
    this.invokeIntentOnSubmit['bi_assistant_'+id] = new BehaviorSubject<any>(false); 
    this.inputFieldSuggestions['bi_assistant_'+id] = new BehaviorSubject<any>({}); 
    this.converstations['bi_assistant_'+id] = new BehaviorSubject<BISResponse[]>([]); 
    this.intentDM['bi_assistant_'+id] = new BehaviorSubject<any>({}); 
    this.intentSelectionSubscr['bi_assistant_'+id] = new BehaviorSubject<any>(false);
    this.formValueEntities['bi_assistant_'+id] = new  BehaviorSubject<any>({});
    this.iOSBusyError['bi_assistant_'+id] = new BehaviorSubject<any>(false);
  }
  //Added by Pratheek on 18-06-19[created a new BehaviourObject so to differentiate the Welcome screen and Quick Action Pamel]-End
  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START

  //Chnaged by Sainath T. on 6-Anu-2019 [added optional parameter to set notification identity]- Start
  addUserMsg( id: any, msg: string, identity?: string ) {
    var bisMsg = new BISResponse("user", msg, false, "", "");
    this.updateMessage(id,bisMsg);
    if( identity && identity != undefined && identity.trim().length != 0 )
    {
      this.addWaitingMsg( id, identity );
    }
    else
    {
      this.addWaitingMsg( id,(""+ new Date().getTime()) );
    }
  }

  addWaitingMsg( id: any, identity : string ) {
    this.identity = identity;
    console.log("identity in Waiting : ", identity);
    var waitMsg = new BISResponse("vision", "Please wait...", true, "", "");
    this.requestMap.set(identity, waitMsg);
    // var arr = this.conversation.getValue();
    var arr = this.converstations['bi_assistant_'+id].getValue();
    //Chnaged by Sainath T. on 25-04-19 [To empty array on relogin for e12mobile ] - START
    if (this.identity == "00") 
    {
      console.log("Conersation arr befor delet"+this.converstations['bi_assistant_'+id].getValue());
      arr = []; 
      // this.conversation.next(arr);
      this.converstations['bi_assistant_'+id].next(arr);
      console.log("Conersation arr After delet" + this.conversation.getValue());
    }

    //Chnaged by Sainath T. on 25-04-19 [To empty array on relogin for e12mobile ] - END
    this.updateMessage(id,waitMsg);
    //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
  }

    //Changed by Pooja S on [Changes vision response in case of multiValue found]
  addVisionMessage(
    identity: string, msg: any, template: string,
    format: string, inferred?: boolean, modelName?: string, addlInfo ?: string
  ) {
    //var bisMsg = new BISResponse( "vision", msg, false );
    //this.updateMessage(bisMsg);
    //var arr = this.conversation.getValue();
    console.log("identity in Vision : ", identity);

    console.log("identity in Vision this.requestMap: ", this.requestMap);
    let responseObj: BISResponse | any = this.requestMap.get(identity);
    console.log("responseObj : ", responseObj);
    if (responseObj != null) 
    {
      responseObj.setWaiting(false);
      //Added by Sainath T on 19/09/18.[handle intent reponse for different format]
      //Changed by Pooja S on [Changes vision response in case of multiValue found]
      responseObj.setTemplateResponse(format, msg, template, inferred, modelName, addlInfo);
    }
	//Added by Pratheek on 18-06-19[call the refresh methhod to update the data]-Start
    this.ngRefresh();
    //Added by Pratheek on 18-06-19[call the refresh methhod to update the data]-End
	//Changed by Sainath Thakare on 20-SEP-2019 [To set focus only in browser]-Start   
    if(this.isBrowser)
    {
      this.scrollToBottomNFocus();
    }
    else
    {
      this.scrollToBottom();
    }
    //Changed by Sainath Thakare on 20-SEP-2019 [To set focus only in browser]-End
    //this.conversation.next(arr);
  }

  private updateMessage(id: any,bisMsg: BISResponse) {
	//Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-Start
    // var arr = this.conversation.getValue();
    var arr = this.converstations['bi_assistant_'+id].getValue();
	//Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
    if (bisMsg != null)
    {
      arr.push(bisMsg);
    }
	//Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-Start
    // this.conversation.next(arr);
    this.converstations['bi_assistant_'+id].next(arr);
	//Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
    //Changed by Sainath Thakare on 20-SEP-2019 [To set focus only in browser]-Start
    if(this.isBrowser)
    {
      this.scrollToBottomNFocus();
    }
    else
    {
      this.scrollToBottom();
    }
    //Changed by Sainath Thakare on 20-SEP-2019 [To set focus only in browser]-End
  }
  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-Start
  getIntents(id: any) : Observable<any>{
    // return this.intentsDM.asObservable();
    return this.intentDM['bi_assistant_'+id].asObservable();
}
  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
   //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-Start
  fetchIntentsDM(targetID: any) : void {
    /*var headers = new HttpHeaders().set('Content-Type','application/json');
    var options = {headers : headers};
    var userCode = this.getStorageItem( "userName" );
    console.log( 'userCode : ', userCode );
    
    this.http.get<any>('/ibase/resource/HeaderDataFiles/SCOPE_DATA/'+ userCode +'/intent_metadata.json', options).subscribe(intentsDM => {
    //this.http.get<any>('./assets/intent_metadata.json', options).subscribe(intentsDM => {
      this.intentsDM.next( intentsDM );
    });*/
    this.datamodelService.getDataModelData('intent_metadata', '', '', true).subscribe(
      intentsDM => {
        console.log('Intents data:', intentsDM);

        if (intentsDM!.reponse != "loading") 
        {
		  //Added by Pratheek on 18-06-19[created condition to differentiate the welcome screen and quick action Panel]-START
          //this.intentsDM.next(intentsDM);
          this.intentDM['bi_assistant_'+targetID].next(intentsDM);
           if( this.objNameDummy == "WELCOME")
           {
                this.getIntentResult('WELCOME').subscribe( response => {
                this.processIntentResponse( response,targetID );
                // Added by Prasad on 27/08/18 [updating data after datamodel reponse]
                this.chgDetectorRef.detectChanges();
                
                //Added by Sainath T. on 6-Ang-2019 [To process notififcation data]- Start
                if( this.notificationRequest && this.notificationRequest.trim().length != 0 )
                {
                  var identity = "";
                  if (this.notificationResponse!.Response!.identity != null) 
                  {
                    identity = this.notificationResponse!.Response!.identity;
                  }
                  console.log("identity : ", identity);
                  this.addUserMsg( targetID, this.notificationRequest, identity );
                  this.processIntentResponse( this.notificationResponse, targetID );
                }
                //Added by Sainath T. on 6-Ang-2019 [To process notififcation data]- End
                
                //Added by Sainath T.[To Call Speech Recognition After Login]
            	this.startSpeechListener(); 
                });
           }
           else
           {
                // this.fallbackIntentId.next(  this.objnamedummy );
                this.multipleSubstrictions['bi_assistant_'+targetID].next(this.objNameDummy);
                // Added by Prasad on 27/08/18 [updating data after datamodel reponse]
                this.chgDetectorRef.detectChanges();
           }
		   //Added by Pratheek on 18-06-19[created condition to differentiate the welcome screen and quick action Panel]-ENd
        }
      }
    );
  }

  filterUserIntents(intents: any[]): any[] {
    this.userIntents=[];
    intents.filter(intent => {
      if (intent.INTENT_TYPE == 'U') {
        for (var intentInvoc of intent.INTENT_INVOCS ) 
        {
          //console.log('intentInvoc', intentInvoc);
          intentInvoc['BIS_INTENT_ID'] = intent.BIS_INTENT_ID;
          intentInvoc['INTENT_ARGS'] = intent.INTENT_ARGS;
          //By Sainath T. on 03/012/2018 [for display intents groupwise on sort APPL_DESCR)
          intentInvoc['APPL_DESCR'] = intent.APPL_DESCR;
          this.userIntents.push(intentInvoc);
        }
      }
    });
    return this.userIntents;
  }
  //By sainath T. on 17-SEp-2019 [Added optional parameter true to filter fallback intent with diff. condition]
  filterIntents(value: any, intents: any[], fallbackIntent?: any): any[] {
    this.fallbackIntent_ = fallbackIntent;
    var intentIdArr: any[] = [];
    //Changed by Pooja S on 31-July-2019 [on the did you mean suggestion] Start
    var filteredIntents:any[] = [];
    
    if ( value instanceof Array )
    {
      for( let suggestionIntentId of value )
      {
        if(suggestionIntentId != 'ull')
        {
       	  for(let intent of intents)
          {
            var intentDescr = intent.INVOC_DESCR;
            var intentId = intent.BIS_INTENT_ID;
            //console.log( 'intentId : [', intentId, '] value:[',suggestionIntentId, '] intentDescr:[',intentDescr,']'  );
            if ((intentId.toLowerCase() == suggestionIntentId.toLowerCase()) && intentIdArr.indexOf(intentId) == -1) 
            {
              intentIdArr.push( intentId );
              filteredIntents.push( intent );
            }
          }
        }
      }
    }
    else
    {
      //Changed by Amey W. [To resolve the issue of searching the Intent] on 27-08-2019
      value = value.concat(" ");
      var spaceCount = (value.split(" ").length - 1);
      filteredIntents = intents.filter(intent => {
        var intentDescr = intent.INVOC_DESCR.toLowerCase();
        var intentId = intent.BIS_INTENT_ID;
        //console.log( 'intentId : [', intentId, '] value:[',value,']' );
        //if (intentDescr && (intentDescr.toLowerCase().includes(value) || intentId.toLowerCase() == value) && intentIdArr.indexOf(intentId) == -1) 
        //Changed by Pooja S on 31-July-2019 [on the did you mean suggestion] 
        
        //By sainath T. on 17-SEp-2019 [To filter fallback intent with Intent id]
        if (this.fallbackIntent_ && intentDescr && (intentDescr.toLowerCase().includes(value) || (intentId.toLowerCase()) == value.trim()) && intentIdArr.indexOf(intentId) == -1) 
        {
          intentIdArr.push(intentId);
          return intent;
        }
        else if (intentDescr && intentDescr.startsWith(value) && intentIdArr.indexOf(intentId) == -1 && spaceCount == 1 )
        {
          intentIdArr.push(intentId);
          return intent;
        }
      });

      if( intentIdArr.length == 0  &&  ( value.charAt(0)=='%' || spaceCount > 1 )  )
      {    
        if( value.charAt(0)=='%' )
        {
          value = value.substring(1);
        }
        for( let intent of intents )
        {
          var intentDescr = intent.INVOC_DESCR;
          var intentId = intent.BIS_INTENT_ID;
          if (intentDescr && intentDescr.toLowerCase().includes(value.trim()) && intentIdArr.indexOf(intentId) == -1 ) 
          {
            intentIdArr.push( intentId );
            filteredIntents.push( intent );
          } 
        }
      }
    }
    //console.log('filteredIntents', filteredIntents );
    //Changed by Pooja S on 31-July-2019 [on the did you mean suggestion] End
    //Added by Sadique on 24-08-2019 [To sort the Intents while searching]
    filteredIntents = filteredIntents.sort((a, b) => { return (a.INVOC_DESCR.length - b.INVOC_DESCR.length) } );
    return filteredIntents;
  }

  getInvokeArg(userIntentArgKey: string): any {
    console.log('getInvokeArg userIntentArgKey', userIntentArgKey);
    if (userIntentArgKey) {
      let [intentId, argName] = userIntentArgKey.split(":");
      console.log('intentId', intentId, 'argName', argName);
      var invokeArg: any = {};
      this.userIntents.filter((intent: any) => {
        if (intentId == intent.BIS_INTENT_ID) 
        {
          intent.INTENT_ARGS.filter((intentArg: any) => {
            if (argName == intentArg.ARG_NAME) {
              console.log(' argName == intentArg.ARG_NAME ', intentArg);
              invokeArg = intentArg;
              return;
            }
          });
        }
      });
    }
    return invokeArg;
  }
  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
  getInvocationTemplate(assistantId: any,id: any,intent: any){
    var intentInvocString = intent.INVOC_STRING;
    var intentInvocArgs = intent.INTENT_ARGS;
    for (var intentInvocArg of intentInvocArgs) 
    {
      var userIntentArgKey = intent.BIS_INTENT_ID + ':' + intentInvocArg.ARG_NAME;
	  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
      var inputTempl = `<bis-invoke-input targetid = '${id}' assistantid='${assistantId}' userIntentArgKey = '${userIntentArgKey}' ></bis-invoke-input>`;
 	  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
      var searchTempl = ':' + intentInvocArg.ARG_NAME;
      intentInvocString = intentInvocString.replace(new RegExp(searchTempl, 'g'), inputTempl);
      //intentInvocString = intentInvocString.replace(new RegExp('\\{{.+?\\}}', 'g'), inputTempl);
    }
    console.log('intentInvocString', intentInvocString);
    return intentInvocString;
  }

  setFormGroup(form: FormGroup) {
    this.formGroup = form;
  }

  setFormElement(formElement: ElementRef) {
    this.formElement = formElement;
  }

  addToForm(formControlName: string, formControl: FormControl) {
    this.formGroup.addControl(formControlName, formControl);
  }

  focusInvalidInput() {
    var formControls = this.formGroup.controls;
    if (formControls) {
      for (let controlName of Object.keys(formControls)) {
        var formControl = formControls[controlName];
        //Changed by Pooja S on 31-July-2019 [on the did you mean suggestion]
        if (formControl.invalid && this.formElement ) {
          var invalidControl = this.formElement.nativeElement.querySelector('input[name="' + controlName + '"]');
          //console.log('formControl invalid >', invalidControl );
          alert(invalidControl.getAttribute("placeholder") + " should not be blank.");
          invalidControl.focus();
          return;
        }
      }
    }
  }

  focusInput(inputName: string) {
    if( this.formElement )
    {
      this.formElement.nativeElement!.querySelector('input[name="' + inputName + '"]')!.focus();
    }
  }

  setInputValue(fieldName: string, fieldValue: string, displayValue: string) {
    console.log('formElement >> ', this.formElement);
    if (this.formElement && this.formGroup) {
      this.formGroup.controls[fieldName]!.setValue(fieldValue);
      this.formGroup.controls['INVOKE_' + fieldName]!.setValue(displayValue);
      this.focusInput('INVOKE_' + fieldName);
    }
  }

  intentResultUrl = '/ibase/rest/BISService/invokeIntent';
  
  //Added by Sainath T. on 07-08-19 [Added optional param to send user massage and isBrowser flag to server]
  getIntentResult(intentId: any, inputValue?: string, userMsg?: string): Observable<any> {
    //console.log('intentId[',intentId,'] inputValue[',inputValue,'] userMsg',userMsg,']');
    var httpHeaders = new HttpHeaders().set('Content-Type', 'application/json');
    var formValues: any = {};
    if (this.formGroup != null) 
    {
      formValues = this.formGroup.value;
    }

    formValues["BIS_INTENT_ID"] = intentId;
    formValues["identity"] = this.identity;
    formValues["USER_MSG"] = userMsg != null ? userMsg : "";
    formValues["IS_BROWSER"] = this.isBrowser;
    // Changed by Abhishek T on 29-OCT-18 [Send user entered text in request parameters] START
    inputValue && (formValues['INPUT_TEXT'] = inputValue)

    console.log('formValues > ', JSON.stringify(formValues));
    var options = {
      headers: httpHeaders,
      observe: 'response',
      responseType: 'json',
      //params : intentParams
    };
    //Added by Sainath T on 16/10/18[To open transaction from Vision Asssistant]-START
    if (intentId == "OPEN_HOME_SCREEN") 
    {
      //Changed by Sainath T. on 25-SEP-2019 [To open transaction in mobile too]- Start
      var objName = formValues["OBJ_NAME"];
      //(<any>window).openTransactionsGWT(objName);
      callOpenTransaction(objName,this.isBrowser);
      //Changed by Sainath T. on 25-SEP-2019 [To open transaction in mobile too]- End
      var response: any = {};
      response["Response"] = this.createOpenHomeScreenResponse(this.identity);
      var respSubject = new BehaviorSubject<any>({});
      respSubject.next(response);
      return respSubject;
    }
    else 
    {
      //Added by Sainath T on 16/10/18[To open transaction from Vision Asssistant]-END
      //Added by Sainath T on 15/02/19[To pass formValues by httpParam to solve bad request problem]-END
      let formParam = new HttpParams().set('INTENT_PARAM', JSON.stringify(formValues))
      return this.http.post<any>(`${this.getHostURL()}${this.intentResultUrl}?${formParam}`, options);
      // return this.http.post<any>(`${this.getHostURL()}${this.intentResultUrl}?INTENT_PARAM=${JSON.stringify( formValues )}`, options);
    }
  }
  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
  processIntentResponse( intentResponse: any,targetId: any ) {
    console.log("intentResponse : ", intentResponse);
    var response = "", status = "", identity = "", intentId = "";
    var template = "", format = "";
    //Added by Pooja S on [Changes vision response in case of multiValue found]
    var addlInfo="";

    const inferred: boolean = intentResponse.Response!.inferred;
    const modelName: string = intentResponse.Response!.modelName;

    console.log("Inferred", inferred);
    console.log("Model Name", modelName);

    if (intentResponse!.Response!.status != null) 
    {
      status = intentResponse!.Response!.status;
    }
    console.log("status : ", status);
    if (intentResponse!.Response!.identity != null) 
    {
      identity = intentResponse!.Response!.identity;
    }
    console.log("identity : ", identity);
    //Added by Prasad on 19/10/18  [to handle fallback response] START
    if (intentResponse!.Response!.intent_id != null) 
    {
      intentId = intentResponse!.Response!.intent_id;
    }
    console.log("intentId : ", intentId);
    //Added by Prasad on 19/10/18  [to handle fallback response] END
    if ("success" == status) 
    {
      if (intentResponse!.Response!.results!.Root!.Detail != null) 
      {
        //Added by Sainath T on 19/09/18.[handle intent reponse for different format]-start
        format = intentResponse!.Response!.results!.Root!.Detail!.result!.format;
        //By Sainath T.on 16/11/18 [To handle response of call add transaction]
        if ("4" == format) 
        {
          if (intentResponse!.Response!.results!.Root!.Detail!.result!.data != null) 
          {
            var data = intentResponse!.Response!.results!.Root!.Detail!.result!.data;
            var dataJson = JSON.parse(data);
            console.log('data parse Root3==>', dataJson);

            if (dataJson!.Root!.Errors != null) 
            {
              var Errors = dataJson!.Root!.Errors;

              if (Errors!.error != null) 
              {
                var msg = "Oops! I came across an error in doing that.";
                var msgDescr = Errors.error.description;
                var msgTrace = Errors.error.trace;
                response = this.getErrorMsg(msg, msgDescr, msgTrace);
              }
            }
            else 
            {
              response = dataJson.Root.MsgOnSave;
              //Added by Sainath T on 31-08-2020 [Changes vision response in case of multiValue found] Start
              if( intentResponse!.Response!.results!.Root!.Detail!.result!.addl_info )
              {
                addlInfo = intentResponse!.Response!.results!.Root!.Detail!.result!.addl_info;
                response = addlInfo+'<br><br>'+response;
              }
              //Added by Sainath T on 31-08-2020 [Changes vision response in case of multiValue found] End
              console.log('In success response 4 : [' + response + ']');
              var objName = "";
              var tranID = "";
              if (intentResponse!.Response!.results!.Root!.Detail!.result!.objName) 
              {
                objName = intentResponse!.Response!.results!.Root!.Detail!.result!.objName;
              }
              if (dataJson.Root.TranID) 
              {
                tranID = dataJson.Root.TranID;
              }
              var callLink = this.getCallLinkString(objName, tranID);
              //var functions  = "performLinkAction( 'TEST29','bis_intent','bis_intent','1','','','LINK','bis_intent21','','','')";
              //to see new added transaction on click of tranID
              response = "<span>" + response + "<a onclick=\"" + callLink + "\" href='#' class = 'bis-linkAction'>" + tranID + "</a></span>";
              format = '1';
              console.log('In success response 4 : [' + response + '], TranID : [' + tranID + ']');
            }
          }
        }
        else 
        {
          response = intentResponse!.Response!.results!.Root!.Detail!.result!.data;
          //Added by Pooja S on [Changes vision response in case of multiValue found] Start
          if( intentResponse!.Response!.results!.Root!.Detail!.result!.addl_info )
          {
            addlInfo = intentResponse!.Response!.results!.Root!.Detail!.result!.addl_info;
          }
          //Added by Pooja S on [Changes vision response in case of multiValue found] End
          template = intentResponse!.Response!.results!.Root!.Detail!.result!.template;
        }
        //By Sainath T.on 16/11/18 [To handle response of call add transaction]-END
        console.log('In success response : [' + response + '], template : [' + template + '], format : [' + format + ']');
        //Added by Sainath T on 19/09/18.[handle intent reponse for different format]-end
      }
      else if (intentResponse!.Response!.results!.Root!.Errors != null) 
      {
        var msgDescr = intentResponse!.Response!.results!.Root!.Errors!.error!.description;
        var msgTrace = intentResponse!.Response!.results!.Root!.Errors!.error!.trace;
        response = msgDescr + " " + msgTrace;
        //Added by Prasad on 19/10/18  [to handle fallback response] START
        var errorMsg = intentResponse!.Response!.results!.Root!.Errors!.error!;
        console.log('intentResponse!.Response!.results!.Root!.addl_info:', intentResponse!.Response!.results!.Root!.addl_info);
        if( intentResponse!.Response!.results!.Root!.addl_info )
        {
          addlInfo = intentResponse!.Response!.results!.Root!.addl_info;
          response = addlInfo + '<br><br>' + response;
        }
        
        var msgId = errorMsg['@id'];
        console.log('msgId:', msgId);
        if (msgId == 'INVINTARG' || msgId == 'INVINTVAL') 
        {
		      //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
          // this.fallbackIntentId.next( intentId );
          this.multipleSubstrictions['bi_assistant_'+targetId].next( intentId );
		      //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
        }
        //Added by Sainath T. on 16-Aug-2019 [implement entity value detection if AI fails]
        else if ( msgId == 'MULTVALFND')
        {
          this.multipleSubstrictions['bi_assistant_'+targetId].next( intentId );
          if(intentResponse!.Response!.results!.MultiValueEntities != null)
          {
            console.log('in fromgroup entity detection!!!');
            var formValueEntities : any  = intentResponse!.Response!.results!.MultiValueEntities;
            this.formValueEntities['bi_assistant_'+targetId].next( formValueEntities );
          }
        }
        //Added by Sainath T. on 16-Aug-2019 [implement entity value detection if AI fails]-end
        //Added by Prasad on 19/10/18  [to handle fallback response] END
      }
    }
    else 
    {
      //response = intentResponse!.Response!.results;
      var jsonRes = intentResponse!.Response!.results;
      console.log("Error response : ", jsonRes);
      if (jsonRes != null) 
      {
        //console.log( "jsonRes : ", jsonRes );
        if (jsonRes!.Root!.Errors != null) 
        {
          var msg = "Oops! I came across an error in doing that.";
          var msgDescr = jsonRes!.Root!.Errors!.error!.description;
          var msgTrace = jsonRes!.Root!.Errors!.error!.trace;

          response = "<details class = 'bis-details'>";
          response += "<summary>" + msg + "</summary>";
          response += "<p class='errorTrace'>" + msgDescr + "</p>";
          if ( msgTrace != null && msgTrace != undefined ) 
    	    {
            if ( msgTrace.length > 1000) 
            {
              msgTrace = msgTrace.substring(0, 999);
            }
            response += "<p class='errorTrace'>" + msgTrace + "</p>";
          }
          response += "</details>";
        }
      }
    }
    //Added by Pooja S on 31-July-2019 [on the did you mean suggestion] Start
    if (intentResponse!.Response!.intents != null) 
    {
      var intents = intentResponse!.Response!.intents;
      var didYouMeanIntents = intents.split(",");
      this.multipleSubstrictions['bi_assistant_'+targetId].next( didYouMeanIntents );
    }
    //Added by Pooja S on 31-July-2019 [on the did you mean suggestion] End
    //Added by Pooja S on [Changes vision response in case of multiValue found] 
    this.addVisionMessage(identity, response, template, format, inferred, modelName, addlInfo);
  }

  getStorageItem(key: any): string {
    return localStorage.getItem(key) as any;
  }

  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
  getInvokeArgSuggestion(id: any) : Observable<any>{
      // return this.inputSuggestion.asObservable();
      return this.inputFieldSuggestions['bi_assistant_'+id].asObservable();
  }
  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
  filterInputSuggestion(id: any,pophelpConfig: any, filterValue: any) {

    var fieldName = pophelpConfig.fieldName;
    var datamodelName = pophelpConfig.data_model_name;
    var inputDMData = this.inputSuggestionDM[datamodelName];
    //console.log( 'filterInputSuggestion inputDMData>>>>>', inputDMData );
    //Sainath T. on 23/11/2018 [ For filter dependent pophelp data ]-Starts

    var otherFormValues = {};
    if (this.formGroup) 
    {
      console.log('formGroup in intent service', this.formGroup);
      if (this.formGroup.value) 
      {
        otherFormValues = this.formGroup.value;
        console.log('OtherFormatValues in intent s', otherFormValues);
      }
    }

    if (inputDMData) 
    {
      var filter_expr = this.inputSuggestionDM[datamodelName + '_FLTR_EXPR'];
      console.log('filter_expr>>111 ', filter_expr);

      if (filter_expr != null && filter_expr != "" && filter_expr != undefined && filter_expr.length > 0) 
      {
        filter_expr = this.getFilterdExpr(otherFormValues, filter_expr);
        //Sainath T. on 11/12/18[To check filter_expr is not null]
        if (filter_expr != null && filter_expr != "") 
        {
          var dataToFilter: any = {};
          dataToFilter["DETAILS"] = inputDMData;
          dataToFilter = this.filterPophelpJSON(dataToFilter, filter_expr);
          inputDMData = dataToFilter;
        }
      }
    }
    //Sainath T. on 23/11/2018 [ For filter dependent pophelp data ]-End

    if (inputDMData) 
    {
	    //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
      this.filterValues(id,inputDMData, filterValue, fieldName);
      //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
    }
    else if (this.inputDMRequest[datamodelName] != true) 
    {
      this.inputDMRequest[datamodelName] = true;
      this.datamodelService.getDataModelData(datamodelName, '', '', true).subscribe(
        dataModelResult => {
          if (dataModelResult && dataModelResult.DETAILS) 
          {
            //Added by Sainath on 26/11/2018 [ to get filter_expr] - START
            var dataModelResults = dataModelResult.DETAILS;
            var dataMdlName = datamodelName;
            //var filterexpr = this.getFilterExpr(dataModelResults);
            var detailJson: any = this.getFilterExpr(dataModelResults);
            if(detailJson['DATAMODEL_NAME'].length != 0)
            {
              dataMdlName = detailJson['DATAMODEL_NAME'];
            }
            //Added by Sainath on 26/11/2018 [ to get filter_expr] -END
            dataModelResult = dataModelResult.DETAILS.slice(2, dataModelResult.length);
            //this.inputSuggestionDM[datamodelName] = dataModelResult;
            this.inputSuggestionDM[dataMdlName] = dataModelResult;
            //To Add filter Expression
            this.inputSuggestionDM[dataMdlName + '_FLTR_EXPR'] = detailJson['FILTER_EXPR'];
			      //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
            this.filterValues(id,dataModelResult, filterValue, fieldName);
            //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
          }
        });
    }
  }
  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
  resetInputSuggestion(id: any) {
    // this.inputSuggestion.next({});
    this.inputFieldSuggestions['bi_assistant_'+id].next({});
  }
  //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
  private filterValues(id: any,inputDMData: any, filterValue: any, fieldName: any) {

    //console.log('filterValues dataModelResult[',inputDMData,'] filterValue>>[', filterValue, '] fieldName >> [', fieldName,']');
    var filterValues = inputDMData.filter(
      (field: any) => {
        //By Sainath T. on 23-04-19 [Filter the suggestion on label]
        return ((field.label.toLowerCase().indexOf(filterValue.toLowerCase()) > -1));
        //field.value.toLowerCase().indexOf(filterValue.toLowerCase()) > -1 )
      }
    );
    var filterData: any = {
      fieldName: fieldName,
      values: []
    };
	//Added by Sainath T. on 23-SEP-2019 [To filter intents on length]
    filterValues = filterValues.sort((a: any, b: any) => { return (a.value.length - b.value.length) } );
    console.log( 'filterValues [', filterValues, ']' );

    filterData.values = filterValues;
    //console.log('filterValues', filterValue, ' >> ', filterData);
    //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
    //this.inputSuggestion.next(filterData);
    this.inputFieldSuggestions['bi_assistant_'+id].next(filterData);
    //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
  }

  onInvokeIntentSubmit(id: any): Observable<any> {
    //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-Start
    // return this.invokeIntentSubmit.asObservable();
    return this.invokeIntentOnSubmit['bi_assistant_'+id].asObservable();
    //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
  }

  setInvokeIntentSubmit(id : String,toSubmit : boolean) {
    //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-Start
    // this.invokeIntentSubmit.next(toSubmit);
    return this.invokeIntentOnSubmit['bi_assistant_'+id].next(toSubmit);
    //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
  }

  scrollToBottom() 
  {
    //By Sainath T. on 31-01-19 [ Added time out for Response Scroll to the bottom on sent"]
    setTimeout(function () 
    {
      var objDiv = document.getElementById("bis-message-list");
      if ( objDiv )
      {
        try
        {
          //console.log('scrollTop : ', objDiv.scrollTop, 'scrollHeight : ', objDiv.scrollHeight);
          objDiv!.scrollTop = objDiv.scrollHeight + objDiv.clientHeight;
          //console.log('objDiv!.scrollTop : ', objDiv!.scrollTop);
        }
        catch
        {
          console.log('Exception while getting objDiv in bis-intent.service.ts');
        }
      }
      //By Sainath T. on 28/08/2019
      window.document.body.scrollTop = 0;
    }, 0);
  }

  scrollToBottomNFocus(inputFocus?:boolean) {
    console.log('scrollToBottomNFocus',this.isBrowser, 'inputFocus ',inputFocus);
    this.scrollToBottom();
    //Added By Sainath T. on 10-06-19 [focus only for Browser]
    //Commented by Sainath Thakare on 20-SEP-2019
    /* if(this.isBrowser || inputFocus || this.osType == 'iOS')
    { */
      console.log('setting input focuss');
      if (document.getElementById("bis-intent-input")) 
      {
        // document.getElementById("bis-intent-input").focus();
        document.getElementById("bis-intent-input")?.focus();
      }
    /* } */
  }

  disableIntentInput() {
    if (document.getElementById("intent-input-container")) 
    {
      document.getElementById("intent-input-container")!.style.pointerEvents = "none";
    }
    if (document.getElementById("bis-intent-input")) 
    {
      document.getElementById("bis-intent-input")!.setAttribute("disabled", "true");
    }
  }

  enableIntentInput() {
    if (document.getElementById("intent-input-container")) 
    {
      document.getElementById("intent-input-container")!.style.pointerEvents = "auto";
    }
    if (document.getElementById("bis-intent-input")) 
    {
      document.getElementById("bis-intent-input")!.removeAttribute("disabled");
    }
  }

  //Added by Sainath T on 16/10/18[To Generate response when Open_Home_Screen is Called]-START
  createOpenHomeScreenResponse(identity: string) 
  {
    var responseData: any = {};
    var result: any = {};
    var detail: any = {};
    var root: any = {};
    result["data"] = "Ok";
    result["format"] = "1";
    result["template"] = "";
    var resultData: any = {};
    resultData["result"] = result;
    detail["Detail"] = resultData;
    root["Root"] = detail;
    responseData["identity"] = identity;
    responseData["status"] = "success";
    responseData["results"] = root;
    console.log('manualy generated responseData', responseData);

    return responseData;
  }
  //Added by Sainath T on 16/10/18[To Generate response when Open_Home_Screen is Called]-END

  //Added by Sainath T on 04/12/18[To get action link string for call add transaction]-START
  getCallLinkString(objName: any, tranID: any) 
  {
    var callLink = "";
    var targetObjName = objName;
    var linkType = "1";
    var linkUri = "";
    var linkArgmnt = "";
    var linkTitle = "LINK";
    var linkForm = objName + "21";
    var qryStr = "";
    var fieldName = null;
    var linkImage = null;
    callLink = "performLinkAction( '" + tranID + "','" + objName + "','" + targetObjName + "','" + linkType + "','" + linkUri + "','" + linkArgmnt + "','" + linkTitle + "','" + linkForm + "','" + qryStr + "','" + fieldName + "','" + linkImage + "')";
    return callLink;
  }
  //Added by Sainath T on 04/12/18[To get action link string for call add transaction]-END

  //Added by Sainath T on 04/12/18[To get error msg response]-START
  getErrorMsg(msg: any, msgDescr: any, msgTrace: any) 
  {
    var response = "";
    response = "<details class = 'bis-details'>";
    response += "<summary>" + msg + "</summary>";
    response += "<p class='errorTrace'>" + msgDescr + "</p>";
    console.log( 'msgTrace ', msgTrace );
    if ( msgTrace != null && msgTrace != undefined ) 
    {
      if ( msgTrace.length > 1000 ) 
      {
        msgTrace = msgTrace.substring(0, 999);
      }
      response += "<p class='errorTrace'>" + msgTrace + "</p>";
    }
    response += "</details>";
    return response;
  }
  //Added by Sainath T on 04/12/18[To get action link string for call add transaction]-END

  //Sainath T. 23/11/2018 [to get filtered expression] -Start 
  getFilterdExpr(jsonToFilter: any, exprToFilter: any) 
  {
    var filterExprsStrg: string;
    var tokens:any = [];
    filterExprsStrg = exprToFilter;
    //Sainath T. on 11/12/18 [To save not updated filtr_expr]
    var tempFilterExpr = exprToFilter;
    console.log('filterExprsStrg==', filterExprsStrg, 'jsonToFilter==', jsonToFilter);
    tokens = filterExprsStrg.split("&&");
    console.log('token', tokens);
    for (var i = 0; i < tokens.length; i++) 
    {
      if ("" != tokens[i]) 
      {
        console.log('in if::', tokens[i]);
        var objKey = "";
        var keyValue = "";
        var leftSide = "";
        var rightSide = "";
        var innerTokens = [];
        var colName = "";
        var splitExpr = tokens[i].trim();
        innerTokens = splitExpr.split("==");
        leftSide = innerTokens[0];
        rightSide = innerTokens[1];
        console.log("Left [" + leftSide + "] Right [" + rightSide + "]");
        colName = splitExpr.substring(splitExpr.indexOf(":") + 1, splitExpr.lastIndexOf(":"));
        var capitalColName = colName.toUpperCase();
        console.log("Final Expresion [" + splitExpr + "] colName  [" + capitalColName + "]");
        filterExprsStrg = filterExprsStrg.replace(leftSide, "value." + leftSide);
        if (jsonToFilter != null) 
        {
          var jsonFilterArray:any[] = [];
          jsonFilterArray.push(jsonToFilter);
          //To get keys and values -Start
          jsonFilterArray.forEach(function (elementObject) {
            var keys = Object.keys(elementObject);
            keys.forEach(function (key) {
              console.log("key::" + key + ":value::" + elementObject[key]);
              objKey = key;
              //to check if key starts with no. - START
              var patt = new RegExp(/^[0-9]/);
              if (patt.test(objKey)) 
              {
                console.log('key is::', objKey);
                objKey = objKey.substring(objKey.indexOf(".") + 1, objKey.length);
                console.log('key After substring::', objKey);
              }
              //to check if key starts with no. - END
              objKey = objKey.toUpperCase();
              console.log('key After UpperCase::' + objKey + 'capitalColName' + capitalColName);

              if (objKey == capitalColName) 
              {
                keyValue = elementObject[key];
                filterExprsStrg = filterExprsStrg.replace(rightSide, " '" + keyValue + "'");
                filterExprsStrg = filterExprsStrg.replace("value.value", "value");
              }
              else {
                console.log('No column maches!!');
              }
            })
          });
          //To get keys and values -END
        }
      }
    }
    console.log('filterExprsStrg final:::', filterExprsStrg);
    //Sainath T. on 11/12/18 [To check updated expression]-START
    if (filterExprsStrg.includes(tempFilterExpr)) 
    {
      return filterExprsStrg = "";
    }
    else 
    {
      return filterExprsStrg;
    }
    //Sainath T. on 11/12/18 [To check updated expression]-END
  }
  //Sainath T. 23/11/2018 [to get filtered expression] -End 

  //Sainath T. 23/11/2018 [to get filtere expression from json] -START 
  getFilterExpr(detailJSON: any) 
  {
    var filter_expr = "";
    var dataModelName = "";
    var detailJson: any = {};
    try 
    {
      var obj = detailJSON[1];
      console.log('obj==', obj);

      if (obj.FILTER_EXPR) 
      {
        filter_expr = obj.FILTER_EXPR;
        console.log('getFilterExpr>>  ', filter_expr);
      }
      if (obj.DATAMODEL_NAME) 
      {
        dataModelName = obj.DATAMODEL_NAME;
        console.log('getdataModelName>>  ', dataModelName);
      }
      detailJson['FILTER_EXPR'] = filter_expr;
      detailJson['DATAMODEL_NAME'] = dataModelName;
    }
    catch
    {
      console.log('Exception::getFilterExpr(detailJSON)==');
      detailJson['FILTER_EXPR'] = "";
      detailJson['DATAMODEL_NAME'] = "";
    }
    return detailJson;
  }

  getFormGroup() 
  {
    return this.formGroup;
  }
  //Sainath T. 23/11/2018 [to get filtere expression from json] -END
  //Sai 05/12/2018 [to get filtered Pophelp Json] -START
  filterPophelpJSON(jsonToFilter: any, expressionToFilter: any) 
  {
    var filterJson: any[] = [];
    //var jsonString = JSON.parse(jsonToFilter);
    jsonToFilter.DETAILS.filter(function (value: any) {
      if (eval(expressionToFilter)) {
        filterJson.push(value);
      }
    });
    console.log('input suggestion filteredJson Data ==> ' + JSON.stringify(filterJson));
    return filterJson;
  }
  //Sai 05/12/2018 [to get filtered Pophelp Json] -END

  //Added by Prasad on 19/10/18  [to handle fallback response] START
  handleFallbackIntents(id: any): Observable<any> {
    //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-START
	  //return this.fallbackIntentId.asObservable();
    return this.multipleSubstrictions['bi_assistant_'+id].asObservable();
    //Added by Pratheek on 18-06-19[passing the id so to differentiate the Welcome screen and Quick Action Pamel]-End
  }
  //Added by Prasad on 19/10/18  [to handle fallback response] END

  //By Sainath T. on 31/12/2018 [To change input date display format] -START
  formatDate(value: any): any 
  {
    var changedValue: any = '';
    var dateFormatFrmLocal = localStorage.getItem('APPL_DATE_FORMAT');
    console.log('dateFormatFrmLocal[', dateFormatFrmLocal, ']');
    if (dateFormatFrmLocal && dateFormatFrmLocal.length > 0) 
    {
      this.dateFormat = dateFormatFrmLocal;
      console.log('dateFormat[', this.dateFormat, ']');
    }
    if (this.dateFormat) 
    {
      try 
      {
        changedValue = this.datePipe.transform(value, this.dateFormat);
      }
      catch (e) 
      {
        changedValue = this.datePipe.transform(new Date(), this.dateFormat);
      }
    }
    else 
    {
      changedValue = this.datePipe.transform(value, this.dateFormat);
    }
    console.log('selected changedValue value--', changedValue);
    return changedValue;
  }
  //By Sainath T. on 31/12/2018 [To change input date display format] -END
  //By Sainath T. on 23-04-2019 [To get Date Format]-START
  getFormattedDate(date: any, format: any) 
  {
    console.log('getFormattedDate>>815', this.datePipe.transform(date, format));
    return this.datePipe.transform(date, format);
  }
  //By Sainath T. on 20-03-2019 [To get Date Format]-END
  //By Sainath T. on 22-03-2019 [To get Default As per Argument Value]-START
  getDefaultValue(ARG_VALUE: any) {
    var defaultVal: any = '';
    var DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
    var toDate = new Date();
    if (ARG_VALUE.toLowerCase() == 'cur_month' || ARG_VALUE.toLowerCase() == 'this month') {
      defaultVal = this.getFormattedDate(new Date(), 'yyyyMM');
    }
    else if (ARG_VALUE.toLowerCase() == 'day' || ARG_VALUE.toLowerCase() == 'today') {
      defaultVal = this.formatDate(toDate);
    }
    else if (ARG_VALUE.toLowerCase() == 'yesterday') {
      var prevDateInMs = toDate.getTime() - DAY_IN_MILLIS;
      var preDate = new Date(prevDateInMs);
      defaultVal = this.formatDate(preDate);
    }
    else if (ARG_VALUE.toLowerCase() == 'tomorrow') {
      var nxtDateInMs = toDate.getTime() + DAY_IN_MILLIS;
      var nxtDate = new Date(nxtDateInMs);
      defaultVal = this.formatDate(nxtDate);
    }
    else if (ARG_VALUE.toLowerCase() == 'next month') {
      var thisMonth = new Date(toDate.getFullYear(), toDate.getMonth() + 1, 0);
      var nxtMonth = (new Date(toDate.getFullYear(), toDate.getMonth() + 2, 0));
      defaultVal = this.getFormattedDate(nxtMonth, 'yyyyMM');
    }
    else if (ARG_VALUE.toLowerCase() == 'last month') {
      var curMonth = (toDate.getMonth() + 1).toString();//bcz in JS Month starts with 
      var lastYear = (toDate.getFullYear()).toString();
      var lastMonth = "";
      if (curMonth == '1' || curMonth == '01') {
        lastMonth = "12";
        lastYear = (toDate.getFullYear() - 1).toString();
      }
      else {
        lastMonth = (Number(curMonth) - 1).toString();
      }
      if (lastMonth.length < 2) 
      {
        lastMonth = "0" + lastMonth;
      }
      defaultVal = lastYear + lastMonth;
    }
    else if (ARG_VALUE.toLowerCase() == 'this year') {
      var defaultVal: any = new Date().getFullYear().toString();
    }
    else if (ARG_VALUE.toLowerCase() == 'last year') {
      var defaultVal: any = (new Date().getFullYear() - 1).toString();
    }
    else if (ARG_VALUE.toLowerCase() == 'next year') {
      var defaultVal: any = (new Date().getFullYear() + 1).toString();
    }
    else if (ARG_VALUE.toLowerCase() == 'two days ago') {
      var toDate = new Date();
      var prevDateInMs = toDate.getTime() - DAY_IN_MILLIS;
      var preDate = new Date(prevDateInMs);
      var SecndpreDate = preDate.getTime() - DAY_IN_MILLIS;
      defaultVal = this.formatDate(SecndpreDate);
    }
    else if (ARG_VALUE.toLowerCase() == 'this financial year' || ARG_VALUE.toLowerCase() == 'accounting year') {
      var accYr1 = new Date().getFullYear();
      var accYr2 = accYr1 - 1;
      defaultVal = accYr2 + '-' + accYr1;
    }
    else if (ARG_VALUE.toLowerCase() == 'days of month') 
    {
      defaultVal = (new Date(toDate.getFullYear(), toDate.getMonth() + 1, 0).getDate()).toString();
    }
    else if (ARG_VALUE.toLowerCase() == 'week') 
    {
      var d = new Date(Date.UTC(toDate.getFullYear(), toDate.getMonth(), toDate.getDate()));
      d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
      var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
      console.log('yearStart>>', yearStart);
      defaultVal = (Math.ceil((((Number(d) - Number(yearStart)) / 86400000) + 1) / 7)).toString();
    }
    else {
      defaultVal = ARG_VALUE; //"Default Value"
    }
    console.log('default value899>>', defaultVal);
    return defaultVal;
  }

  getDefaultDateObj(ARG_VALUE: any) 
  {
    var defaultVal: any;
    var DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
    var toDate = new Date();
    if (ARG_VALUE.toLowerCase() == 'day' || ARG_VALUE.toLowerCase() == 'today') {
      defaultVal = toDate;//this.formatDate(toDate);
    }
    else if (ARG_VALUE.toLowerCase() == 'yesterday') {
      var prevDateInMs = toDate.getTime() - DAY_IN_MILLIS;
      defaultVal = new Date(prevDateInMs);
    }
    else if (ARG_VALUE.toLowerCase() == 'tomorrow') {
      var nxtDateInMs = toDate.getTime() + DAY_IN_MILLIS;
      defaultVal = new Date(nxtDateInMs);
    }
    else if (ARG_VALUE.toLowerCase() == 'two days ago') {
      var toDate = new Date();
      var prevDateInMs = toDate.getTime() - DAY_IN_MILLIS;
      var preDate = new Date(prevDateInMs);
      defaultVal = preDate.getTime() - DAY_IN_MILLIS;
    }
    console.log('default value925>>', defaultVal);
    return defaultVal;
  }
  //By Sainath T. on 23-04-2019 [To get Default As per Argument Value]-END

  //By Sainath T. on 23-04-2019 [For Total Implementation In Table]-START
  /**
  * it takes the number and converts it to decimal
  * @param value value to convert
  * @param exp numbers will display after decimal points as like round(2.1035, 2) = 2.15
  */
  round(value: any, exp: any) {
    console.log('In round 937!! ');
    if (typeof exp === 'undefined' || +exp === 0)
      return Math.round(value);

    value = +value;
    exp = +exp;

    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
      return NaN;

    // Shift
    value = value.toString().split('e');
    value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));

    // Shift back
    value = value.toString().split('e');
    return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
  }
  //By Sainath T. on 23-04-2019 [For Total Implementation In Table]-END

  // By Sainath T. on 23/04/2019 [ for speech recognition ] - START
  startSpeechListener() 
  {
    try 
    {
      plugins.cordova.speechRecognition.hasPermission((isGranted: any) => {
        if (isGranted) 
        {
          console.log('Yes, you have Permission for speech!!');
          //this.intentService.setstartListeningFlag(true);
          if( this.userPref == 'speech' )
            this.startListener.emit(true);
        }
        else 
        {
          plugins.cordova.speechRecognition.requestPermission(() => {
            console.log('Requested Permission for speech!!');
            //this.intentService.setstartListeningFlag(true);
            if(this.userPref == 'speech')
              this.startListener.emit(true);
          }, (err: any) => {
            console.log('Requested Permission for speech!!', err);
          });
        }
      }, (errr: any) =>       {
        console.log('Error while Checking Permission', errr);
      });
    }
    catch
    {
      console.log('Error while Checking Permission1212');
    }
  }
  // By Sainath T. on 23/04/2019 [ for speech recognition ] - END
  // By Sainath T. [To refresh content after callback] - Start
  ngRefresh() 
  {
    this.zone.run(() => 
    {
      //console.log('view refreshed In bis-interaction22');
    });
  }
  // By Sainath T. [To refresh content after callback] - End
  //Added by sadique shaikh on 9-07-2019[method added to Set and get user pref Value]
  setUserPref(value:String):Observable<any>
  {
    console.log('setUserPref value ',value);
    let paramMap: any={};

    paramMap['ACTION']='SET_USER_PREF';
    paramMap['PREF_VAL']=value;
    paramMap['OBJ_NAME']='bis_intent';
    paramMap['PREF_NAME']='ASSISTANT_PREF_TYPE';
    paramMap['PREF_VAL_TYPE']='String';

    let paramString:String = this.getEncodedParamString(paramMap);
    let url: string = this.getHostURL() + "/ibase/WebITMRequestHandlerServlet";
    console.log('setUserPref url ',url);

    let headers = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' });

    return this.http.post(url, paramString, { headers: headers });
  }

  getUserPref():Observable<any>
  {
    console.log('getUserPref value ');
    let paramMap: any={};

    paramMap['ACTION']='GET_USER_PREF';
    paramMap['OBJ_NAME']='bis_intent';
    paramMap['PREF_NAME']='ASSISTANT_PREF_TYPE';
    let paramString:String=this.getEncodedParamString(paramMap);
    let url: string = this.getHostURL() + "/ibase/WebITMRequestHandlerServlet?"+paramString;
    console.log('setUserPref url ',url);
    return this.http.get(url,{ responseType: 'text' });
  }

  getEncodedParamString(paramMap: Object | any) 
  {
    let encodedString: String = "";
    try 
    {
        for (let key in paramMap) {
            let value = paramMap[key];
            encodedString = encodedString + encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
        }
        var len = encodedString.length;
        encodedString = encodedString.substring(0, len - 1);
    } catch( ex ) {
        console.log('Exception in ChangePasswordComponent :: getEncodedParamString()', ex);
    }
    return encodedString;
  }

  getHostURL(): string 
  {
    // var HOST_URL: string = '';
    var HOST_URL: any = '';
    HOST_URL = localStorage.getItem('HOST_URL');
    if (!HOST_URL) HOST_URL = '';
    console.log('getHostURL[', HOST_URL, ']');
    return HOST_URL;
  }
  //Added by sadique shaikh on 9-07-2019[setUserPref method added to get user pref Value] -End
  
  //Added by Sainath T on 25-07-19[To get onselection event in Speech Recg component]-Start
  getIntentSelection(id: any): Observable<any> 
  {
    return this.intentSelectionSubscr['bi_assistant_'+id].asObservable();
  }
  onIntentSelection(id : String,toSubmit : boolean)
  {
    this.intentSelectionSubscr['bi_assistant_'+id].next(toSubmit);
  }
  //Added by Sainath T on 25-07-19[To get onselection event in Speech Recg component]-End
  
  //Added by Prasad on 07/08/19 [to set dynamic height to bis-messages content] START
  changeInvokeInputContainerHeight(invokeInputContainerHeight: any)
  {
    console.log('changeInvokeInputContainerHeight :: invokeInputContainerHeight : ', invokeInputContainerHeight);
    var rootElem = <HTMLElement>document.querySelector(':root')

    //By Sainath T. on 14-SEP-2019 [To resolve scroll related issue] - Start
    var bisHeaderEle = document.getElementById("bis_showHeader");
    var loadDisplay = false;
    if ( bisHeaderEle )
    {
      loadDisplay = (window.getComputedStyle(bisHeaderEle, null).getPropertyValue("display") == 'none') ? false : true;
      console.log('bisHeader display style',loadDisplay);
    }
    var invokeInputContainerHeight_ =( this.callFromProteusVision && loadDisplay ) ? invokeInputContainerHeight + 30 : invokeInputContainerHeight;
    rootElem.style.setProperty('--invokeInputContainerHeight',  invokeInputContainerHeight_ +"px" );
    //By Sainath T. on 14-SEP-2019 [To resolve scroll related issue] - End
    this.scrollToBottom();
  }
  //Added by Prasad on 07/08/19 [to set dynamic height to bis-messages content] END
  //Added by Sainath T. on 16-Aug-2019 [implement entity value detection if AI fails] - Start
  getFormValueEntities(id: string):Observable<any>
  {
    return this.formValueEntities['bi_assistant_'+id].asObservable();
  }
  //Added by Sainath T. on 16-Aug-2019 [implement entity value detection if AI fails]-End
  
  //Added by Sainath T. [Assistant resixe related issue in proteus vision] -Start
  setMobileHeader()
  {
    if(this.callFromProteusVision)
    {
      console.log('set header menu absolute');
      try{
        var MobileHeader  = document.getElementById('MobileHeader');
        // document.getElementById('MobileHeader').style.position = "absolute"; //previous
        document.getElementById('MobileHeader')!.style.position = "absolute";

      }
      catch{
        console.log('Error -set header menu absolute');
      }
    }
  }

  unSetInputFocus() 
  {
      console.log('setting input focuss unSetInputFocus');
      if (document.getElementById("bis-intent-input")) 
      {
        // document.getElementById("bis-intent-input").blur();
        document.getElementById("bis-intent-input")?.blur();
      }
  }
  //Added by Sainath T. [Assistant resixe related issue in proteus vision] - End
  //Added by Sainath T. on 23-SEP-2019 [To get and set iOS busy error] - Start
  getIOSbusyError(id:any): Observable<any> 
  {
    return this.iOSBusyError['bi_assistant_'+id].asObservable();
  }
  onIOSbusyError(id : String,isError : boolean)
  {
    this.iOSBusyError['bi_assistant_'+id].next(isError);
  }
  //Added by Sainath T. on 23-SEP-2019 [To get and set iOS busy error] - End
}