import { PositionStrategy, OverlayRef } from '@angular/cdk/overlay';
import { fromEvent, Subscription, merge } from 'rxjs';
import { isNumber } from 'util';

export class ContainerPositionStrategy implements PositionStrategy {
  windowScroll$ = fromEvent(window, 'scroll');

  windowResize$ = fromEvent(window, 'resize');

  subscription: Subscription;

  overlayRef: OverlayRef;

  onApplyCb: Function;

  get overlayElement() {
    return this.overlayRef.overlayElement;
  }

  constructor(public containerElement: HTMLElement, private position?: { top?: number; bottom?: number; left?: number; right?: number }) {}

  attach(overlayRef: OverlayRef): void {
    this.overlayRef = overlayRef;
  }

  apply(): void {
    this.update();
    this.subscription = merge(this.windowResize$, this.windowScroll$).subscribe(() => this.update());
  }

  dispose(): void {
    if (this.subscription) {
      this.subscription.unsubscribe();
      delete this.subscription;
    }
  }

  update() {
    if (!this.overlayRef.hasAttached()) {
      return;
    }

    this.overlayElement.style.overflow = 'auto';

    const domRect = this.containerElement.getClientRects().item(0);

    const position = this.position || {};

    this.overlayElement.style.top = `${isNumber(position.top) ? position.top : domRect.top}px`;
    this.overlayElement.style.left = `${isNumber(position.left) ? position.left : domRect.left}px`;

    if (isNumber(position.right)) {
      this.overlayElement.style.right = `${position.right}px`;
    } else {
      this.overlayElement.style.width = `${domRect.width}px`;
    }
    if (isNumber(position.bottom)) {
      this.overlayElement.style.bottom = `${position.bottom}px`;
    } else {
      this.overlayElement.style.height = `${domRect.height}px`;
    }
  }
}
