import {
  Directive,
  Input,
  OnDestroy,
  OnInit,
  TemplateRef,
  ViewContainerRef,
} from '@angular/core';
import { AuthService } from '@core/services/auth.service';
import { intersection, isEmpty } from 'lodash';
import { ReplaySubject } from 'rxjs';
import { takeUntil, tap } from 'rxjs/operators';
import { AccountResDto } from '@api/models';

@Directive({
  selector: '[appHasPrivilege]',
})
export class HasPrivilegeDirective implements OnInit, OnDestroy {
  // the privilege the user must have
  @Input() appHasPrivilege: string[] = [];

  private destroyed$: ReplaySubject<boolean> = new ReplaySubject(1);

  isVisible = false;

  constructor(
    private viewContainerRef: ViewContainerRef,
    private templateRef: TemplateRef<any>,
    private authService: AuthService,
  ) {}

  ngOnInit() {
    this.authService.currentUser
      .pipe(
        takeUntil(this.destroyed$),
        tap((user: AccountResDto | null) => {
          if (!user?.privileges) {
            this.isVisible = false;
            this.viewContainerRef.clear();
            return;
          }
          const userPrivileges = user.privileges.map(
            (privilege) => privilege.actionCode,
          );
          if (!isEmpty(intersection(this.appHasPrivilege, userPrivileges))) {
            if (!this.isVisible) {
              this.isVisible = true;
              this.viewContainerRef.createEmbeddedView(this.templateRef);
            }
          } else {
            this.isVisible = false;
            this.viewContainerRef.clear();
          }
        }),
      )
      .subscribe();
  }

  ngOnDestroy() {
    this.destroyed$.next(true);
    this.destroyed$.complete();
  }
}
