import { HttpClient } from 'aurelia-fetch-client';
import { EventAggregator } from 'aurelia-event-aggregator';
import { NavigationInstruction, PipelineResult, RouterEvent } from 'aurelia-router';
import { DialogService } from 'aurelia-dialog';
import { autoinject, BindingEngine, computedFrom, Disposable } from 'aurelia-framework';
import { bindable, customElement } from "aurelia-templating";
import { AuthService } from "../../security/auth-service";
import { UINotificationList } from './ui-notification-list';
import { CommunicationHubClient } from '../../services/signalr/communication-hub-client';
import { Config } from '../../config';
import { UIInternal } from '../../exports';
import { NOTIFICATION_PUSHED } from './ui-notification-alert';

@customElement('ui-notification')
@autoinject
export class UINotification {
  public disposables: Array<Disposable>;

  @bindable
  private nbElementPerPage: number = 10;
  private hasOpenNotList = false;
  private counter = 0;

  constructor(private authService: AuthService, private dialogService: DialogService, private bindingEngine: BindingEngine, private commHubClient: CommunicationHubClient, public httpClient: HttpClient, private eventAggregator: EventAggregator, private config: Config) {
    this.disposables = new Array<Disposable>();
  }

  @computedFrom('counter')
  public get counterDisplay() {
    return this.counter.toString();
  }

  public async bind() {
    await this.commHubClient.whenReady();
    this.initChat();
    this.loadCounter();
  }

  public attached() {
    this.disposables.push(
      this.bindingEngine.propertyObserver(this.authService, "currentUser").subscribe((newValue, oldValue) => {
        if (newValue != null) {
          this.loadCounter();
        }
      })
    )
  }

  public initChat() {
    this.eventAggregator.subscribe(RouterEvent.Complete, (event: { instruction: NavigationInstruction; result: PipelineResult }) => {
      if (!this.hasOpenNotList && event.instruction.config.name != 'callback') {
        this.hasOpenNotList = true;
        if (this.authService.currentUser.userData.nbNotificationUnread > 0) {
          this.dialogService.open({ viewModel: UINotificationList, model: { nbElementPerPage: 10 }, lock: true, rejectOnCancel: true });
        }
      }
    });

    this.commHubClient.onUpdateNotificationCounter(async (notificationId: number) => {
      this.loadCounter();
      if (notificationId != null) {
        let result = await this.httpClient.get(this.config.globalConfig.remoteServiceName + "/api/communication/notifications/" + notificationId.toString());
        if (result.ok) {
          let notification = await result.json();
          UIInternal.broadcast(NOTIFICATION_PUSHED, notification);
        }
      }
    });
  }

  private async loadCounter() {
    let result = await this.httpClient.get(this.config.globalConfig.remoteServiceName + `/api/communication/${this.authService.currentUser.id.toString()}/notifications/unread/count`);
    if (result.ok) {
      let response = await result.json();
      this.counter = response;
    }
  }

  public async openNotifications() {
    await this.dialogService.open({ viewModel: UINotificationList, model: { nbElementPerPage: this.nbElementPerPage }, lock: true, rejectOnCancel: true })
      .whenClosed(async (result) => {
        if (!result.wasCancelled) {
          await this.loadCounter();
        }
      });
  }
}