import { Component, OnInit, Input, Output, EventEmitter} from '@angular/core';
import { BISIntentService } from '../../bis-services';
import { Subscription } from 'rxjs';

//For Speech Listener
declare let plugins: any;
var speechListenClock: any;
var iOSSpeechListenClock: any;
@Component({
  selector: 'bis-speech-recognition',
  template: `
  <span class="invoke-input-list" touch-click (onTouchClick)="startListeningVoice();">
  <i *ngIf = "iOSBusyError && !listenAnimationFlag && !stopAnimationFlag" id ="SpecchRecMic_" class="material-icons iOSBusyError" >mic</i>
  <i *ngIf = "!iOSBusyError && !listenAnimationFlag && !stopAnimationFlag" id ="SpecchRecMic" class="material-icons" >mic</i>
  <div *ngIf = "!iOSBusyError && listenAnimationFlag" class="bis-ripple bis-Listen-Animation"><div></div><div></div></div>
  <div *ngIf = "!iOSBusyError && stopAnimationFlag" class="bis-ellipsis bis-Stop-Animation"><div></div><div></div><div></div><div></div></div>
  </span>
  `,
  styleUrls: ['./bis-speech-recognition.css']
})
export class BISSpeechRecognition implements OnInit {

  @Output() listenAnimation: EventEmitter<any> = new EventEmitter(false);
  @Input() listenAnimationFlag : boolean = false;
  @Output() stopAnimation: EventEmitter<any> = new EventEmitter(false);
  @Input() stopAnimationFlag : boolean = false;
  @Output() placeholder: EventEmitter<any> = new EventEmitter();
  @Output() isIntentInputProtected: EventEmitter<any> = new EventEmitter();
  @Output() intentInput: EventEmitter<any> = new EventEmitter();
  stopListnFlag: boolean = true;
  @Output() onInvokeEnter: EventEmitter<any> = new EventEmitter();
  isBrowser: any;
  listeningFlag: Subscription | any;
  intentSelectedSubscr :Subscription | any;
  @Input('targetId') targetId: any;
  isRecording : boolean = true;
  stopCallForiOS : boolean = false;
  iOSBusyError: boolean = false; // to hadle iOS busy error
  constructor(private intentService:BISIntentService){}

  ngOnInit() {
    console.log('listenAnimation',this.listenAnimationFlag);
    console.log('stopAnimation',this.stopAnimationFlag);
    this.isBrowser = this.intentService.isBrowser;
    this.intentService.getIntentSelection(this.targetId).subscribe(
     resp => {
       console.log('In getIntentSelection',resp);
       if(resp)
       {
         this.isRecording = false;
         clearInterval(speechListenClock);
         this.resetNEmitFlags();
         this.stopListening();
       }
     });
  }

 //By Sainath T on 30-05-19 [For first call to listener after login] -START
 ngAfterViewInit() {
  console.log('ngAfterViewInit83',this.isBrowser);
  if (!this.isBrowser) {
    this.listeningFlag = this.intentService.startListener.subscribe(flag => {
      if (flag) {
        console.log('In view init Calling Start Listening');
        this.startListeningVoice(true);
      }
    }
    );
	//Sainath T. on 23-SEP-2019 [To enable and disable listening mic] - Start
    this.intentService.getIOSbusyError(this.targetId).subscribe(
    isError => 
    {
      console.log('ngAfterViewInit!! getIOSbusyError[', isError, ']');
      this.iOSBusyError = isError;
      this.intentService.ngRefresh();
    });
    //Sainath T. on 23-SEP-2019 [To enable and disable listening mic] - End
  }
}
//By Sainath T on 30-05-19 [For first call to listener after login] -END

  // By Sainath T. on 09/04/2019 [ for speech recognition ] - START
  startListeningVoice(busyErr? : boolean) 
  {
    /* console.log('startListeningVoice this.iOSBusyError!!',this.iOSBusyError);
    console.log('startListeningVoice busyErr!!',busyErr);
    console.log('startListeningVoicestopAnimationFlag!!',this.stopAnimationFlag);
    console.log('startListeningVoice listenAnimationFlag!!',this.listenAnimationFlag); */
    
    //By Sainath T on 09-09-19 [To handle iOS busy error] -Start
      this.stopListnFlag = true;
      this.isRecording = true;
      clearInterval(speechListenClock);
      clearInterval(iOSSpeechListenClock);
      //By Sainath T on 09-09-19 [To handle iOS busy error] -Start
	//Sainath T. on 23-SEP-2019 [To enable and disable listening mic] - Start
    if( this.iOSBusyError )
    {
      //alert( 'Speech recognition is not currently available. Please check later on.' ); //it takes 30 seconds to restart
      this.listenAnimationFlag = false;
      this.stopAnimationFlag = false;
      return;
    }
    //Sainath T. on 23-SEP-2019 [To enable and disable listening mic] - End
    
    //In case busy return
    if( this.listenAnimationFlag && busyErr == undefined)
    {
      //return;
      this.isRecording = false;
      this.stopListening( "From 001"); //001 : Stop mannualy
      this.listenAnimationFlag = false;
      this.stopAnimationFlag = false;
      //this.intentService.ngRefresh();
      this.stopAnimation.emit(false);
      this.listenAnimation.emit(false);
      this.isIntentInputProtected.emit(false);
      this.placeholder.emit('Ask Something...');
      this.intentService.ngRefresh();
      return;
    }
    if ( this.stopAnimationFlag && !busyErr ) 
    {
      return;
    }
    console.log('in startListeningVoice>>');
    this.listenAnimationFlag = true;
    this.listenAnimation.emit(true)
    this.placeholder.emit("Listening...")
    this.isIntentInputProtected.emit(true);
    this.intentInput.emit("");
    this.intentService.ngRefresh();
    //en-US
    let options = {
      language: "en-IN",
      matches: 5,
      prompt: "",
      showPopup: false,
      showPartial: true
    };
    try 
    {
      plugins.cordova.speechRecognition.startListening(
        (result: Array<string>) => 
        { 
          this.stopListnFlag = false;
          //to stop taking input after stop listening manualy
          console.log('isRecording>>', this.isRecording);
          if(this.isRecording)
          {
            this.intentInput.emit(result[0]);
            this.isRecording = true;
            //To refresh once when set the call back result
            this.intentService.ngRefresh();
            console.log('Call to filter Intents from Voice Listener');
            //this.filterIntents(this.intentInput);
            this.stopListeningInterval(true);
          }
        },
        (result: Array<string>) => {
          //added by Sainath T.on 20-SEp-2019 [if condition to stop taking input after stop listening manualy]
          if(this.isRecording)
          {
            console.log('start listening error', result);
            this.stopListnFlag = false;
            //Missing permission
            if (result.toString().toLowerCase() == "RecognitionService busy".toLowerCase()) 
            {
              //To handle busy error
              this.speechErrorHandler("RecognitionService_Busy");
            }
            else if (result.toString().toLowerCase().includes( "Error Domain=kAFAssistantErrorDomain".toLowerCase() ) )
            {
              //To handle busy error
              this.speechErrorHandler( result.toString().toLowerCase() );
            }
            else 
            {
              this.stopListeningCall('From 002');
            }
          }
        },
        options);
    }
    catch
    {
      console.log('caught error in startslistening voice!!');
      this.stopListnFlag = false;
      this.stopListeningCall('From 003');
    }
    //To call stop listener in case iOS -Start
    console.log('Set time out is called!!isRecording>>', this.isRecording);
    if(this.isRecording != undefined && this.isRecording)
    {
      iOSSpeechListenClock = setInterval(() =>
      {
        clearInterval(iOSSpeechListenClock);
        if (this.stopListnFlag && this.intentService.osType == 'iOS') 
        {
          console.log('Call Stop Listening if flag true!!');
          this.stopListeningCall("From 004");
        }
        
      }, 5000);
    } 
    //To call stop listener in case iOS -End
  }
  
  stopListeningCall(from?: string) 
  {
    console.log('In stopListening !!', from);
    this.listenAnimationFlag = false;
    this.placeholder.emit("");
    this.stopAnimationFlag = true;
    
    this.listenAnimation.emit(false);
    //this.ngRefresh()
    this.stopAnimation.emit(true);
    this.intentService.ngRefresh(); //changes

    try 
    {
      if (this.intentService.osType == 'iOS') 
      {
        this.stopListening("From 005");
      }
    }
    catch
    {
      console.log('catch error in stopListeningCall!!');
    }
    console.log('In stopListening set retry after 3 sec!!', from);
    setTimeout(() => {
      console.log("In setTimeout 3sec");
      this.resetNEmitFlags();
    }, 3000);
  }

  stopListeningInterval(stopListeningFlag?: boolean) 
  {
    console.log('Call to speechListenClock');
    clearInterval(speechListenClock);
    speechListenClock = setInterval(() => {
      clearInterval(speechListenClock);
      try {
        if (this.intentService.osType == 'iOS' || stopListeningFlag) 
        {
          this.stopListening("From 006");
        }
        this.callToOnInvokeEnter();
      } catch 
      {
        console.log('Caught error in speechListenClock!!');
        this.callToOnInvokeEnter();
      }
    }
      , 3000); //5000
  }

  callToOnInvokeEnter() 
  {
    console.log('!!callToOnInvokeEnter!!!!');
    if(this.listenAnimationFlag && !this.stopAnimationFlag)
    {
      this.listenAnimationFlag = false;
      this.placeholder.emit("");
      this.stopAnimationFlag = true;
      
      this.listenAnimation.emit(false);
      this.stopAnimation.emit(true);
      this.intentService.ngRefresh(); //Chnages
      
      console.log('In stopListening set retry after 3 sec!!');
      setTimeout(() => {
        console.log("In setTimeout__3sec");
        this.resetNEmitFlags();
        this.onInvokeEnter.emit();
      }, 3000);
  }
  }
  // By Sainath T. on 09/04/2019 [ for speech recognition ] - END
  stopListening(from? :string) : any
  {
    console.log('stopListening is Called ',from);
    plugins.cordova.speechRecognition.stopListening(
      () => 
      {
        console.log('stopListening is Called ');
        return true;
      }, (err: any) => 
      {
        console.log('error in Stop listening>>', err);
        return false;
      });
  }

  resetNEmitFlags()
  {
    this.listenAnimationFlag = false;
    this.stopAnimationFlag = false;
    this.stopAnimation.emit(false);
    this.listenAnimation.emit(false);
    this.isIntentInputProtected.emit(false);
    this.placeholder.emit('Ask Something...');
    this.intentService.ngRefresh(); //Chnages
  }
  //By Sainth T. on 09-09-19 [To handle diff. errors]- Start
  speechErrorHandler(error: string) 
  {
    if(error == 'RecognitionService_Busy')
    {
      this.stopAnimation.emit(false);
      this.placeholder.emit("Please wait...");
      this.intentService.ngRefresh();
      this.stopListening("from RecognitionService_Busy");
      setTimeout(() => {
        if(this.isRecording)
        this.startListeningVoice(true);
      }, 4000);
    }
    else if(error.includes("kAFAssistantErrorDomain".toLowerCase()))
    {
      //Commented and added by Sainath T. on 23-SEP-2019 [To handle iOS error and enable and disable mic]-Start
     /*  this.placeholder.emit("Please wait...");
      if(this.stopListening("from kAFAssistantErrorDomain"))
      {
        console.log('In kAFAssistantErrorDomain iffff');
        this.startListeningVoice(true);
      }
      else
      {
        console.log('In kAFAssistantErrorDomain elsss');
        this.resetNEmitFlags();
      } */
      
      this.stopListening( "from kAFAssistantErrorDomain" );
      this.resetNEmitFlags();
      console.log('in error handler iOSBusyError!!',this.iOSBusyError);
      if( error.includes( "kAFAssistantErrorDomain Code=209".toLowerCase() ) )
      {
        console.log('IN set iOSbusy set true');
        this.intentService.onIOSbusyError(this.targetId, true);
      }
      else if(error.includes( "kAFAssistantErrorDomain Code=203".toLowerCase() ) && this.iOSBusyError)
      {
        console.log('IN set iOSbusy set false');
        this.intentService.onIOSbusyError(this.targetId, false);
      }
      //Commented and added by Sainath T. on 23-SEP-2019 [To handle iOS error and enable and disable mic]-End
    }
    else
    {
      this.stopListening( "from 007" );
      this.resetNEmitFlags();
    }
  }
  //By Sainth T. on 09-09-19 [To handle diff. errors]- End
  ngOnDestroy()
  {
    if(this.listeningFlag)
    {
      this.listeningFlag.unsubscribe();
    }
    if(this.intentSelectedSubscr)
    {
      this.intentService.onIntentSelection(this.targetId, false);
      this.intentSelectedSubscr.unsubscribe();
    }
  }
}
