import { Inject, Injectable, InjectionToken } from '@angular/core';
import { SignalrHub, SignalRHubOptions } from '@core/signalr';
import { BehaviorSubject, merge, of } from 'rxjs';
import { filter, map, shareReplay, tap, withLatestFrom } from 'rxjs/operators';
import { EnvelopeDTO, MessageBoardItemDTO } from './defs';

export const NOTIFICATIONS_HUB_OPTIONS = new InjectionToken<SignalRHubOptions>('hub.notifications.options');

@Injectable()
export class NotificationsHub extends SignalrHub {
  updateNotification$ = new BehaviorSubject<MessageBoardItemDTO>(undefined);
  constructor(@Inject(NOTIFICATIONS_HUB_OPTIONS) options: SignalRHubOptions) {
    super(options);
  }

  notifications$ = merge(
    of(this._getNotifications()).pipe(filter((f) => !!f)),
    this.listen<EnvelopeDTO<MessageBoardItemDTO[]>>('messageBoard')
  ).pipe(
    withLatestFrom(this.updateNotification$),
    map(([d, update]) => {
      const data = d;
      if (update && !!data && !data?.data?.find((message) => message?.category === 'ISA-Update')) {
        data.data.push(update);
      }
      return data;
    }),
    tap((data) => this._storeNotifactions(data)),
    shareReplay(1)
  );

  private _storeNotifactions(data: EnvelopeDTO<MessageBoardItemDTO[]>) {
    if (data) {
      localStorage.setItem('NOTIFICATIONS_BOARD', JSON.stringify(data));
    }
  }

  private _getNotifications(): EnvelopeDTO<MessageBoardItemDTO[]> {
    const stringData = localStorage.getItem('NOTIFICATIONS_BOARD');
    if (stringData) {
      return JSON.parse(stringData);
    }
    return undefined;
  }

  updateNotification() {
    this.updateNotification$.next({
      category: 'ISA-Update',
      type: 'update',
      headline: 'Update Benachrichtigung',
      text: 'Es steht eine aktuellere Version der ISA bereit. Bitte aktualisieren Sie die Anwendung.',
    });
  }
}
