const { Settler } = require('./specificClass.js');


class nodeClass {
  /**
  * Node-RED node class for settler.
  * @param {object} uiConfig - Node-RED node configuration
  * @param {object} RED - Node-RED runtime API
  * @param {object} nodeInstance - Node-RED node instance
  * @param {string} nameOfNode - Name of the node
  */
  constructor(uiConfig, RED, nodeInstance, nameOfNode) {
    // Preserve RED reference for HTTP endpoints if needed
    this.node = nodeInstance;
    this.RED = RED;
    this.name = nameOfNode;
    this.source = null;

    this._loadConfig(uiConfig)
    this._setupClass();

    this._attachInputHandler();
    this._registerChild();
    this._startTickLoop();
    this._attachCloseHandler();
  }

  /**
   * Handle node-red input messages
   */
  _attachInputHandler() {
    this.node.on('input', (msg, send, done) => {

      switch (msg.topic) {
        case 'registerChild':
          // Register this node as a parent of the child node
          const childId = msg.payload;
          const childObj = this.RED.nodes.getNode(childId); 
          this.source.childRegistrationUtils.registerChild(childObj.source, msg.positionVsParent);
          break;
        default:
          console.log("Unknown topic: " + msg.topic);
      }

      if (done) {
        done();
      }
    });
  }

  /**
   * Parse node configuration
   * @param {object} uiConfig Config set in UI in node-red
   */
  _loadConfig(uiConfig) {
    this.config = {
      general: {
        name: uiConfig.name || this.name,
        id: this.node.id,
        unit: null,
        logging: {
          enabled: uiConfig.enableLog,
          logLevel: uiConfig.logLevel
        }
      },
      functionality: {
        positionVsParent: uiConfig.positionVsParent || 'atEquipment', // Default to 'atEquipment' if not specified
        softwareType: "settler" // should be set in config manager
      }
    }
  }

  /**
   * Register this node as a child upstream and downstream.
   * Delayed to avoid Node-RED startup race conditions.
   */
  _registerChild() {
    setTimeout(() => {
      this.node.send([
        null,
        null,
        { topic: 'registerChild', payload: this.node.id, positionVsParent: this.config?.functionality?.positionVsParent || 'atEquipment' }
      ]);
    }, 100);
  }

  /**
   * Setup settler class
   */
  _setupClass() {

    this.source = new Settler(this.config); // protect from reassignment
    this.node.source = this.source;
  }

  _startTickLoop() {
    setTimeout(() => {
      this._tickInterval = setInterval(() => this._tick(), 1000);
    }, 1000);
  }

  _tick(){
    this.node.send([this.source.getEffluent, null, null]);
  }

  _attachCloseHandler() {
    this.node.on('close', (done) => {
      clearInterval(this._tickInterval);
      done();
    });
  }
}

module.exports = nodeClass;