'use strict';

const globalSlimmerRegistry = require('./global-slimmer-registry-b3bce7e0.js');
const dynamicSlimmer = require('./dynamic-slimmer-f31fdfd7.js');
const changeManager = require('./change-manager-a297e4d2.js');
const observer = require('./observer-f49483e8.js');
const vegaInternalEventId = require('./vega-internal-event-id-87014e4f.js');
const domNodeSubjectObserverFactory = require('./dom-node-subject-observer-factory-ba6a95f3.js');

/**
 * Sub state notify slimmer
 */
class SubStateNotifySlimmerBase extends globalSlimmerRegistry.VegaSlimmer {
  // eslint-disable-next-line jsdoc/require-jsdoc
  constructor({ propName }) {
    super();
    /**
     * Checks if the input `host` matches the current `host` and `stateName` matches the current `propName`.
     *
     * @param {unknown} input - The `input` parameter is of type `unknown`, which means it can be any type.
     * @returns {boolean} a boolean value indicating whether the input is an acceptable table observer.
     */
    this.isAcceptableObserverPayload = (input) => {
      return input.host === this.host && input.stateName === this.propName;
    };
    this.propName = propName;
  }
  /**
   * Register the observer in connectedCallback
   */
  connectedCallback() {
    this.subStateObserver = new observer.Observer(this.isAcceptableObserverPayload.bind(this), (payload) => {
      payload.callback(this.propValue);
    });
    changeManager.ChangeManager.register(domNodeSubjectObserverFactory.domNodeSubjectFactory.getSubject(this.host, vegaInternalEventId.VegaInternalSubStatePull), this.subStateObserver);
  }
  /**
   * unregister the observer in disconnectedCallback
   */
  disconnectedCallback() {
    changeManager.ChangeManager.unregister(domNodeSubjectObserverFactory.domNodeSubjectFactory.getSubject(this.host, vegaInternalEventId.VegaInternalSubStatePull), this.subStateObserver);
  }
  /**
   * Notify the children component which prop has been changed in the parent component
   */
  subStateNotify() {
    changeManager.ChangeManager.notify(domNodeSubjectObserverFactory.domNodeSubjectFactory.getSubject(this.host, vegaInternalEventId.VegaInternalSubStatePush), {
      host: this.host,
      stateName: this.propName,
      value: this.propValue,
    });
  }
}

/**
 * Create dynamic subState notify slimmer
 *
 * @param {ClassPrototype} mapFromClass - It represents the class that you want to map from.
 * @param {string} propName - The parent component prop name
 * @param {string} watchMethodName - The watch method name of prop change
 * @returns {SubStateNotifySlimmerBase} - SubState notify slimmer
 */
function createSubStateNotifySlimmer(mapFromClass, propName, watchMethodName) {
  const methodsMap = [
    { mapFrom: 'connectedCallback', mapTo: 'connectedCallback' },
    { mapFrom: 'disconnectedCallback', mapTo: 'disconnectedCallback' },
  ];
  if (watchMethodName) {
    methodsMap.push({ mapFrom: watchMethodName, mapTo: 'subStateNotify' });
  }
  return dynamicSlimmer.createDynamicSlimmer(mapFromClass, SubStateNotifySlimmerBase, [
    { mapFrom: 'host', mapTo: 'host' },
    { mapFrom: propName, mapTo: 'propValue' },
  ], methodsMap, [
    {
      propName: propName,
    },
  ]);
}

exports.createSubStateNotifySlimmer = createSubStateNotifySlimmer;
