import { Inject, Injectable, InjectionToken } from '@angular/core';
import { AuthService } from '@core/auth';
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';
import { cloneDeep } from 'lodash';

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

@Injectable()
export class NotificationsHub extends SignalrHub {
  get branchNo() {
    return String(this._auth.getClaimByKey('branch_no') || this._auth.getClaimByKey('sub'));
  }

  // get sessionStoragesessionStorageKey() {
  //   return `NOTIFICATIONS_BOARD_${this.branchNo}`;
  // }

  get sessionStoragesessionStorageKey() {
    return `NOTIFICATIONS_BOARD_AREA_${this.branchNo}`;
  }

  messageBoardItems$ = new BehaviorSubject<Record<string, MessageBoardItemDTO[]>>({});

  constructor(
    @Inject(NOTIFICATIONS_HUB_OPTIONS) options: SignalRHubOptions,
    private _auth: AuthService,
  ) {
    super(options);

    this.messageBoardItems$.next(this._getNotifications());

    this.messageBoardItems$.subscribe((data) => {
      this._storeNotifactions(data);
    });

    this.listen<EnvelopeDTO<MessageBoardItemDTO[]>>('messageBoard').subscribe((envelope) => {
      if (envelope.action === 'refresh') {
        this.refreshMessageBoardItems(envelope.target.area, envelope.data);
      }
    });
  }

  refreshMessageBoardItems(targetArea: string, messages: MessageBoardItemDTO[]) {
    const current = cloneDeep(this.messageBoardItems$.value);

    current[targetArea] = messages ?? [];

    this.messageBoardItems$.next(current);
  }

  notifications$ = this.messageBoardItems$.asObservable().pipe(
    map((data) => {
      const messages = { ...data };
      const keys = Object.keys(data);
      for (let key of keys) {
        if (data[key].length === 0 || data[key] === undefined) {
          delete messages[key];
        }
      }

      return messages;
    }),
  );

  // notifications$ = merge(
  //   of(this._getNotifications()).pipe(filter((f) => !!f)),
  //   this.listen<EnvelopeDTO<MessageBoardItemDTO[]>>('messageBoard')
  // ).pipe(
  //   withLatestFrom(this.updateNotification$),
  //   map(([d, update]) => {
  //     console.log('notifications$', 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) {
  //     sessionStorage.setItem(this.sessionStoragesessionStorageKey, JSON.stringify(data));
  //   }
  // }

  // private _getNotifications(): EnvelopeDTO<MessageBoardItemDTO[]> {
  //   const stringData = sessionStorage.getItem(this.sessionStoragesessionStorageKey);
  //   if (stringData) {
  //     return JSON.parse(stringData);
  //   }
  //   return undefined;
  // }

  private _getNotifications(): Record<string, MessageBoardItemDTO[]> {
    const stringData = sessionStorage.getItem(this.sessionStoragesessionStorageKey);
    if (stringData) {
      return JSON.parse(stringData);
    }
    return {};
  }

  private _storeNotifactions(data: Record<string, MessageBoardItemDTO[]>) {
    if (data) {
      delete data['messageBoard/isa-update'];
      sessionStorage.setItem(this.sessionStoragesessionStorageKey, JSON.stringify(data));
    }
  }

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