import { TemplateRef, Injectable } from '@angular/core';
import { ComponentType } from '@angular/cdk/portal';
import { MatDialog, MatDialogConfig } from '@angular/material';

import { of } from 'rxjs';
import { take, map, catchError } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class DialogService {
  constructor(private matDialog: MatDialog) {}

  public open<T, D = any, R = any>(
    componentOrTemplateRef: ComponentType<T> | TemplateRef<T>,
    config?: MatDialogConfig<D>
  ): Promise<R> {
    return new Promise<R>((resolve, reject) => {
      config = { ...config, autoFocus: false };

      const dialogRef = this.matDialog.open<T, D, R>(
        componentOrTemplateRef,
        config
      );

      dialogRef
        .afterClosed()
        .pipe(
          take(1),
          map(result => {
            return resolve(result);
          }),
          catchError(err => {
            return of(reject(err));
          })
        )
        .subscribe();
    });
  }
}
