import { GlobalPositionStrategy, Overlay } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { Injectable, Injector, TemplateRef, Type } from '@angular/core';
import { UiModalConfig } from './defs/modal-config';
import { UiModalRef } from './defs/modal-ref';
import { UiModalComponent } from './modal.component';

@Injectable()
export class UiModalService {
  constructor(private overlay: Overlay, private injector: Injector) {}

  open<R = any, T = any>({
    content,
    title,
    data,
    config,
  }: {
    content: TemplateRef<any> | Type<any>;
    title?: string;
    data?: T;
    config?: UiModalConfig;
  }): UiModalRef<R> {
    const configs = new UiModalConfig({
      positionStrategy: new GlobalPositionStrategy().centerHorizontally().centerVertically(),
      hasBackdrop: true,
      backdropClose: true,
      width: '917px',
      panelClass: ['modal-overflow'],
      showScrollbarX: false,
      showScrollbarY: true,
      canClose: true,
      ...config,
    });

    const overlay = this.overlay.create(configs);

    const modalRef = new UiModalRef<R, T>(overlay, content, title, configs, data);

    const injector = this.createInjector(modalRef);
    overlay.attach(new ComponentPortal(UiModalComponent, null, injector));

    if (configs.backdropClose) {
      overlay.backdropClick().subscribe(() => modalRef._close({ type: 'backdropClick', data: null }));
    }

    return modalRef;
  }

  createInjector(ref: UiModalRef): Injector {
    return Injector.create({
      providers: [{ provide: UiModalRef, useValue: ref }],
      parent: this.injector,
    });
  }
}
