import {
  Component,
  ElementRef,
  EventEmitter,
  Input,
  OnDestroy,
  OnInit,
  Output,
  ViewChild,
  ViewEncapsulation
} from "@angular/core";
import {Notification} from "../notifications";
import {NotificationService} from "../notification.service";
import {Subscription} from "rxjs";
import {User} from "../../login/utils/helper.class";
import {Dates} from "../../utils/string-utils.class";
import {Option} from "../../sharedComponents/input/input.component";

declare var UIkit;

export class NotificationConfiguration {
  availableGroups: Option[] = [];
  entities: string[] = [];
  service: string;
}

@Component({
  selector: 'notification-sidebar',
  template: `
    <a *ngIf="!mobile" id="notifications-switcher" uk-toggle href="#notifications" class="uk-link-reset uk-offcanvas-switcher uk-flex uk-flex-middle uk-flex-center">
      <icon name="mail" ratio="1.5" customClass="uk-text-background" flex="true" visuallyHidden="Notifications"></icon>
      <span [class.uk-hidden]="unreadCount === 0" class="uk-offcanvas-count uk-flex uk-flex-middle uk-flex-center">
        {{unreadCount}}
      </span>
    </a>
    <ng-template #main>
      <ng-container *ngIf="!notification">
        <div class="notification-list uk-position-relative">
          <h4 class="uk-flex uk-flex-middle clickable uk-margin-remove-top uk-margin-medium-bottom" (click)="showNotificationsEmitter.emit(false)">
            <span *ngIf="mobile" class="uk-margin-right">
              <icon ratio="1.5" name="west" visuallyHidden="back" [flex]="true"></icon>
            </span>
            <span class="uk-text-bold">Notifications</span>
          </h4>
          <div class="uk-flex uk-flex-right@m uk-flex-center uk-padding uk-padding-remove-vertical">
            <button [disabled]="unreadCount === 0" (click)="readAll()" class="uk-button uk-button-link">Mark As Read ({{unreadCount}})</button>
          </div>
          <h6 *ngIf="notifications.length == 0" class="uk-position-center uk-margin-remove">No notifications</h6>
          <ul *ngIf="notifications.length > 0" class="uk-list">
            <li *ngFor="let notification of notifications; let i=index" class="clickable" (click)="select(notification)">
              <div class="uk-grid uk-grid-small" uk-grid>
                <notification-user [name]="notification.name" [surname]="notification.surname" [outline]="true"
                                   colorClass="uk-text-secondary"></notification-user>
                <div class="uk-width-expand">
                  <div class="uk-width-1-1 uk-flex uk-flex-middle">
                    <div class="uk-width-expand multi-line-ellipsis lines-2">
                      <p class="uk-margin-remove" [class.uk-text-light-grey]="notification.read">
                        {{notification.preview}}
                      </p>
                    </div>
                    <div class="uk-margin-left uk-flex uk-flex-center uk-text-secondary">
                      <icon *ngIf="!notification.read" name="circle" ratio="0.6" visuallyHidden="unread"></icon>
                    </div>
                  </div>
                  <span class="uk-text-secondary uk-text-small">{{getDate(notification.date)}}</span>
                </div>
              </div>
            </li>
          </ul>
        </div>
        <div *ngIf="configuration.availableGroups.length > 0" [availableGroups]="configuration.availableGroups" [entities]="configuration.entities" [service]="configuration.service" notify-form class="notify"></div>
      </ng-container>
      <div *ngIf="notification" class="notification">
        <h4 class="uk-flex uk-flex-middle clickable uk-margin-remove-top uk-margin-medium-bottom" (click)="back($event)">
          <span class="uk-margin-right">
            <icon ratio="1.5" name="west" visuallyHidden="back" [flex]="true"></icon>
          </span>
          <span *ngIf="notification.title" class="uk-text-bold">{{notification.title}}</span>
        </h4>
        <div class="uk-flex uk-flex-middle uk-margin-medium-bottom">
          <notification-user [name]="notification.name" [surname]="notification.surname" colorClass="uk-text-secondary" [outline]="true"></notification-user>
          <div class="uk-margin-left">
            {{notification.name + ' ' + notification.surname}}<br>
            <span style="opacity: 0.8;" class="uk-text-small uk-margin-small-top">
                {{notification.date | date:'medium'}} ({{getDate(notification.date)}})
              </span>
          </div>
        </div>
        <div [innerHTML]="notification.message | safeHtml">
        </div>
      </div>
    </ng-template>
    <div *ngIf="!mobile" #canvas id="notifications" class="uk-offcanvas" uk-offcanvas="flip: true; overlay: true;">
      <div class="uk-offcanvas-bar uk-padding-remove">
        <nav class="uk-navbar uk-background-default" uk-sticky>
          <div class="uk-navbar-right">
            <button class="uk-navbar-toggle uk-icon uk-close" (click)="closeCanvas(canvas)">
              <icon name="close" ratio="1.5" visuallyHidden="close account"></icon>
            </button>
          </div>
        </nav>
        <ng-container *ngTemplateOutlet="main"></ng-container>
      </div>
    </div>
    <div *ngIf="mobile" id="notifications">
      <ng-container *ngTemplateOutlet="main"></ng-container>
    </div>
  `,
  styleUrls: ['notification-sidebar.component.less'],
  encapsulation: ViewEncapsulation.None
})
export class NotificationsSidebarComponent implements OnInit, OnDestroy {
  @Input()
  public user: User;
  @Input()
  public mobile: boolean = false;
  @Input()
  public configuration: NotificationConfiguration;
  @Output()
  public showNotificationsEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
  public notifications: Notification[] = [];
  public notification: Notification;
  private subscriptions: any[] = [];
  
  constructor(private notificationService: NotificationService) {
  }
  
  ngOnInit() {
    this.subscriptions.push(this.notificationService.getNotifications(this.configuration.service).subscribe(notifications => {
      this.notifications = notifications;
    }, error => {
      this.notifications = [];
      UIkit.notification('An error has occurred. Please try again later', {
        status: 'danger',
        timeout: 6000,
        pos: 'bottom-right'
      });
    }));
  }
  
  ngOnDestroy() {
    this.subscriptions.forEach(subscription => {
      if (subscription instanceof Subscription) {
        subscription.unsubscribe();
      }
    })
  }
  
  get unreadCount(): number {
    return this.notifications.filter(notification => !notification.read).length;
  }
  
  getDate(date: Date): string {
    return Dates.timeSince(date);
  }
  
  select(notification: Notification) {
    this.notificationService.readNotification(notification._id).subscribe(() => {
      notification.read = true;
      this.notification = notification;
    }, error => {
      UIkit.notification('An error has occurred. Please try again later', {
        status: 'danger',
        timeout: 6000,
        pos: 'bottom-right'
      });
    });
  }
  
  back(event) {
    event.stopPropagation();
    this.notification = null;
  }
  
  closeCanvas(canvas) {
    UIkit.offcanvas(canvas).hide();
  }
  
  readAll() {
    this.notificationService.markAllAsRead(this.configuration.service).subscribe(() => {
      this.notifications.forEach(notification => {
        notification.read = true;
      });
    }, error => {
      UIkit.notification('An error has occurred. Please try again later', {
        status: 'danger',
        timeout: 6000,
        pos: 'bottom-right'
      });
    });
  }
}
