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

@Directive({
  selector: '[appHasRole]',
})
export class HasRoleDirective implements OnInit, OnDestroy {
  // the role the user must have
  @Input() appHasRole: 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?.roles) {
            this.isVisible = false;
            this.viewContainerRef.clear();
            return;
          }
          const userRoles = user.roles.map((role) => role.roleCode);
          if (!isEmpty(intersection(this.appHasRole, userRoles))) {
            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();
  }
}
