import { keys } from "../core";
import { getObserver, getObservers } from "./utils";

export function injectReactiveSubscribe(object: Record<string, any>,) {
  object["subscribe"] = function (name: string, callback: (value: any) => void) {
    getObserver(this, name).subscribe(callback);
  };
  object["unsubscribe"] = function (name?: string, callback?: (value: any) => void) {
    if (!name) {
      keys(getObservers(this)).forEach((observerName) => {
        this.unsubscribe(observerName);
      });
      return;
    }
    if (!(name in this)) {
      return;
    }
    getObserver(this, name).unsubscribe(callback);
  };
}

export function ReactiveSubscribe(Constructor: any) {
  const prototype = Constructor.prototype;

  injectReactiveSubscribe(prototype);
}

export interface ReactiveSubscribe<State extends Record<string, any>> {
  subscribe<Name extends keyof State = keyof State>(
    name: Name, callback: (value: State[Name]) => void): void;
  unsubscribe<Name extends keyof State = keyof State>(
    name?: Name, callback?: (value: State[Name]) => void): void;
}
