import { Inject, Injectable } from "@angular/core";
import { HttpHeaders, HttpParams, HttpClient } from '@angular/common/http';
import * as signalR from "@aspnet/signalr";
import { Observable, BehaviorSubject } from "rxjs";
import { Store, select, UPDATE } from '@ngrx/store';
import { AuthService } from "../auth/auth.service";
import { UPDATEE } from "../baseclass/UnifiedNotificationReducer";
import { UnifiedNotificationObject } from "../interface/UnifiedNotificationObject";
import { RequireInteractiveControl } from "../interface/Interactive Component/RequireInteractiveControl";
import { ConnectionIndicationService } from "./ConnectionIndication.service";

// interface AppStateUnot {
//     unot: NotificationMod;
//   }

  export class NotificationMod
  {
      totalcount:number;
      statusName:string;
      instance: NotificationFigure[];
  }


  export class NotificationFigure
  {
      statusName:string;
      instanceCount:number;
  }

  
@Injectable({
    providedIn: 'root'
  })
export class UnifiedNotificationService
{
    connection:signalR.HubConnection;
    // unot$: Observable<NotificationMod>;
    public notificationModSub : BehaviorSubject<NotificationMod>;
    totalcount:number;
    totalcount$: Observable<number>;
    notificationMod:NotificationMod;
    statustypecount:number;
    currentstatustypecount:number;
    constructor( private authService: AuthService,
        public http: HttpClient,
        @Inject('syncserviceurl') public syncserviceUrl: string)
        {
                
                this.notificationModSub = new BehaviorSubject(<NotificationMod>{});

                
        }

        build()
        {
        // alert('sss');
          this.connection = new signalR.HubConnectionBuilder()
              .withUrl(this.syncserviceUrl+"NotificationHub",
            {  accessTokenFactory: () => 
            
             this.authService.getAccessToken()
          })
              .build();
              
                  ConnectionIndicationService.ConnectionStatusChanged.subscribe(online=>
                    {
              if(online)
              {
                this.start();
              }else
              {
              this.stop();
             
              }
             
                    });
              
           
              this.connection.serverTimeoutInMilliseconds=3600000;
           
      
              return this.connection;
        }
        on()
        {
         
            this.connection.on("IStatusNotification", data => {
                let status:string =data;
                   this.UpdateCount(status);
                    });
        
               
        }
        off()
        {
          this.connection.off("IStatusNotification");
        
        }

        start()
        {
          // alert('sss3');
            this.connection.start().then(() => {
              console.log('Status Notification connection started');
          }).catch(err=>{
                // alert('Error while establishing connection');
          });
        
        
        }

        stop()
          {
        
            this.connection.stop().then(()=>{
        
            
            }).catch(function (err) {
            //   alert('Error while establishing connection');
          });
           
          }
        public InitiateCount(statuslist:string[])
        {
            this.currentstatustypecount=0;
            this.statustypecount=statuslist.length;
            this.totalcount=0;
            // alert(statuslist.length);
            if (statuslist.length==0) {
                this.notificationMod=<NotificationMod>{};
                this.notificationMod.totalcount=0;
                this.notificationModSub.next( this.notificationMod);
            }
            else {               
                for(let x in statuslist)
                {   
                    this.UpdateCount(statuslist[x]);
                }
            }
        }


        public  UpdateCount(status:string)
        {
            
            this.StatusCount(status).subscribe(s=>
                {
                    // alert(s.text());
                var ss:number = s;
                
        if(this.notificationMod==null)
        {
            this.notificationMod=<NotificationMod>{};
        }
        if(this.notificationMod.instance!=null)
        {
        }
        else
        {
            this.notificationMod.instance =  [];
        }
                        var item = this.notificationMod.instance.find(x=>x.statusName==status);
                if(item == null)
                {
               
                    var newitem:NotificationFigure = {instanceCount:ss,statusName:status};
                    this.totalcount+=ss;
                    this.notificationMod.totalcount=this.totalcount;
                    this.notificationMod.instance.push(newitem);
                }
                else
                {
                    var newitem:NotificationFigure = {instanceCount:ss,statusName:status};
                    this.notificationMod.instance.splice(this.notificationMod.instance.findIndex(s=>s.statusName==status),1);
                    this.notificationMod.instance.push(newitem);
                    var countnew:number = 0;
                    for(let x in this.notificationMod.instance)
                    {
                        countnew+=  this.notificationMod.instance[x].instanceCount;
                    }
                    this.totalcount=countnew;
                    this.notificationMod.totalcount=this.totalcount;
                    // unotres.instance.push(newitem);
                }
                this.currentstatustypecount +=1;
                this.notificationMod.instance=  this.notificationMod.instance.sort(
                                (n1,n2)=>
                            {return  n2.instanceCount - n1.instanceCount ;
                            });
                         this.notificationMod.statusName=status;
                            this.notificationModSub.next( this.notificationMod);
                            // this.store.dispatch({ type: UPDATEE, value: unotres });
        
        
                   
             
                }
                );
        }

     public   StatusCount(status:string) : Observable<number>
        {
            var optionss = {
                headers: new HttpHeaders({ 'Content-Type':  'application/json','Authorization': this.authService.getAuthorizationHeaderValue() }),
                params:new HttpParams()
              };
            
              return  this.http.get<any>(this.syncserviceUrl+"api/Notification/GetUnifiedNotificationCount?status="+status,
                 optionss);
    }

    public   GetNotificationList(status:string) :Observable<UnifiedNotificationObjectClass[]>
        {
            var optionss = {
                headers: new HttpHeaders({ 'Content-Type':  'application/json','Authorization': this.authService.getAuthorizationHeaderValue() }),
                params:new HttpParams()
              };
            
              return  this.http.get<UnifiedNotificationObjectClass[]>(this.syncserviceUrl+"api/Notification/GetUnifiedNotificationObjects?status="+status,
                 optionss);
    }

    public   GetAllUnifiedNotificationList() :Observable<UnifiedNotificationObjectClass[]>
        {
            var optionss = {
                headers: new HttpHeaders({ 'Content-Type':  'application/json','Authorization': this.authService.getAuthorizationHeaderValue() }),
                params:new HttpParams()
              };
            
              return  this.http.get<UnifiedNotificationObjectClass[]>(this.syncserviceUrl+"api/Notification/GetAllUnifiedNotificationList",
                 optionss);
    }

    public GetStatusList()
    {
        var optionss = {
            headers: new HttpHeaders({ 'Content-Type':  'application/json','Authorization': this.authService.getAuthorizationHeaderValue() }),
            params:new HttpParams()
          };
        
          return  this.http.get<string[]>(this.syncserviceUrl+"api/Notification/GetUnifiedNotificationStatus",
             optionss);
    }
    
    public GetUnifiedNotificationCountByModule(modulename:string): Observable<number>
    {
        var optionss = {
            headers: new HttpHeaders({ 'Content-Type':  'application/json','Authorization': this.authService.getAuthorizationHeaderValue() }),
            params:new HttpParams()
          };
        
          return  this.http.get<any>(this.syncserviceUrl+"api/Notification/GetUnifiedNotificationCountByModule?modulename="+modulename,
             optionss);
    }
}

export class UnifiedNotificationObjectClass implements UnifiedNotificationObject,RequireInteractiveControl
{
    isSelected: boolean;
    
    id: string;
    isLocked: boolean;  
    applicationName: string;
    objectName: string;
    docName: string;
    objectType: string;
    objectId: string;
    description: string;
    requiredClaim: string;
    urlLink: string;
    status: string;



}

export class UnifiedOcNotificationObjectClass extends UnifiedNotificationObjectClass
{
    
   oclist : string[]



}