import { noChange } from 'lit';
import { AsyncDirective, directive } from 'lit/async-directive.js';
import { rxjs } from '@push.rocks/smartrx';

/**
 * Subscribes to an observable
 */
class SubscribeDirective extends AsyncDirective {
  observable: rxjs.Observable<unknown> | undefined;
  sub: rxjs.Subscription | null = null;

  render(observable: rxjs.Observable<unknown>) {
    if (this.observable !== observable) {
      this.sub?.unsubscribe();
      this.observable = observable;

      if (this.isConnected) {
        this.subscribe(observable);
      }
    }

    return noChange;
  }

  subscribe(observable: rxjs.Observable<unknown>) {
    this.sub = observable.subscribe((v: unknown) => {
      this.setValue(v);
    });
  }

  disconnected() {
    this.sub?.unsubscribe();
  }

  reconnected() {
    this.subscribe(this.observable!);
  }
}

export const subscribe = directive(SubscribeDirective);