// PumpingStation editor — oneditprepare entry. Wires up form-field
// initialization, control-mode toggle, safety toggles, and binds
// redraws for the basin diagram + level-based mode preview.

(function () {
  const ns = window.PSEditor = window.PSEditor || {};

  ns.oneditprepare = function () {
    const node = this;

    // Wait for menu data (asset/logger/position dropdowns) before init.
    const waitForMenuData = () => {
      if (window.EVOLV?.nodes?.pumpingStation?.initEditor) {
        window.EVOLV.nodes.pumpingStation.initEditor(node);
      } else {
        setTimeout(waitForMenuData, 50);
      }
    };
    waitForMenuData();

    const refHeightEl = document.getElementById('node-input-refHeight');
    if (refHeightEl) refHeightEl.value = node.refHeight || 'NAP';

    // Safety toggle pairs — each toggle enables/disables its threshold input.
    const dryRunToggle    = document.getElementById('node-input-enableDryRunProtection');
    const dryRunPercent   = document.getElementById('node-input-dryRunThresholdPercent');
    const highVolumeToggle  = document.getElementById('node-input-enableHighVolumeSafety');
    const highVolumePercent = document.getElementById('node-input-highVolumeSafetyThresholdPercent');

    const toggleInput = (toggleEl, inputEl) => {
      if (!toggleEl || !inputEl) return;
      inputEl.disabled = !toggleEl.checked;
      inputEl.parentElement.classList.toggle('disabled', inputEl.disabled);
    };

    if (dryRunToggle && dryRunPercent) {
      dryRunToggle.checked = !!node.enableDryRunProtection;
      dryRunPercent.value = Number.isFinite(node.dryRunThresholdPercent) ? node.dryRunThresholdPercent : 2;
      dryRunToggle.addEventListener('change', () => toggleInput(dryRunToggle, dryRunPercent));
      toggleInput(dryRunToggle, dryRunPercent);
    }

    if (highVolumeToggle && highVolumePercent) {
      highVolumeToggle.checked = node.enableHighVolumeSafety !== undefined
        ? !!node.enableHighVolumeSafety
        : !!node.enableOverfillProtection;
      const highVolumePct = node.highVolumeSafetyThresholdPercent ?? node.overfillThresholdPercent;
      highVolumePercent.value = Number.isFinite(highVolumePct) ? highVolumePct : 98;
      highVolumeToggle.addEventListener('change', () => toggleInput(highVolumeToggle, highVolumePercent));
      toggleInput(highVolumeToggle, highVolumePercent);
    }

    // Control-mode section toggle (levelbased / manual).
    const toggleModeSections = (val) => {
      document.querySelectorAll('.ps-mode-section').forEach((el) => el.style.display = 'none');
      const active = document.getElementById(`ps-mode-${val}`);
      if (active) active.style.display = '';
    };
    const modeSelect = document.getElementById('node-input-controlMode');
    if (modeSelect) {
      modeSelect.value = node.controlMode === 'manual' ? 'manual' : 'levelbased';
      toggleModeSections(modeSelect.value);
      modeSelect.addEventListener('change', (e) => toggleModeSections(e.target.value));
    }

    // Numeric field defaults.
    ns.setNumberField('node-input-startLevel',     node.startLevel);
    ns.setNumberField('node-input-stopLevel',      node.stopLevel);
    // holdLevel defaults to startLevel when omitted (no hold band). Show
    // the saved value if there is one; otherwise mirror startLevel so the
    // user immediately sees the "no hold band" baseline. Coerce to Number
    // because Node-RED form-bind stores numeric inputs as strings.
    const holdNum = parseFloat(node.holdLevel);
    ns.setNumberField('node-input-holdLevel',
      Number.isFinite(holdNum) ? holdNum : node.startLevel);
    const deadZoneNum = parseFloat(node.deadZoneKeepAlivePercent);
    ns.setNumberField('node-input-deadZoneKeepAlivePercent',
      Number.isFinite(deadZoneNum) ? deadZoneNum : 1);
    ns.setNumberField('node-input-maxLevel',       node.maxLevel);
    ns.setNumberField('node-input-logCurveFactor', node.logCurveFactor);
    ns.setNumberField('node-input-shiftLevel',     node.shiftLevel);
    ns.setNumberField('node-input-shiftArmPercent', Number.isFinite(node.shiftArmPercent) ? node.shiftArmPercent : 95);
    ns.setNumberField('node-input-flowSetpoint',   node.flowSetpoint);
    ns.setNumberField('node-input-flowDeadband',   node.flowDeadband);

    const curveSelect = document.getElementById('node-input-levelCurveType');
    if (curveSelect) curveSelect.value = node.levelCurveType || node.curveType || 'linear';
    const shiftCheckbox = document.getElementById('node-input-enableShiftedRamp');
    if (shiftCheckbox) shiftCheckbox.checked = !!node.enableShiftedRamp;

    // Bind redraws to the inputs each diagram cares about. The basin
    // diagram itself only paints inflow/outflow/overflow lines, but its
    // validation ribbon also enforces startLevel/holdLevel/maxLevel
    // ordering — so it has to refire when any of those change too, or
    // the "Fix before deploy" ribbon goes stale mid-edit.
    ns.bindRedraw(
      ['basinHeight', 'overflowLevel', 'inflowLevel', 'outflowLevel',
       'startLevel', 'stopLevel', 'holdLevel', 'maxLevel',
       'dryRunThresholdPercent', 'highVolumeSafetyThresholdPercent'],
      ns.basinDiagram.redraw
    );
    ns.bindRedraw(
      // dryRunLevel is derived (outflowLevel + dryRunThresholdPercent),
      // so the mode preview must redraw when either of those change.
      ['startLevel', 'stopLevel', 'holdLevel', 'maxLevel',
       'inflowLevel', 'outflowLevel', 'overflowLevel',
       'dryRunThresholdPercent',
       'levelCurveType', 'logCurveFactor', 'enableShiftedRamp', 'shiftLevel',
       'shiftArmPercent'],
      ns.modePreview.redraw
    );

    // Whenever any level/percent input changes, refresh the bounds first
    // so the next redraw + validation sees the correct min/max attrs.
    ns.bindRedraw(
      ['basinHeight', 'basinVolume', 'overflowLevel', 'maxLevel',
       'inflowLevel', 'startLevel', 'stopLevel', 'holdLevel', 'outflowLevel',
       'dryRunThresholdPercent', 'highVolumeSafetyThresholdPercent',
       'enableShiftedRamp', 'shiftLevel', 'shiftArmPercent'],
      () => ns.bounds?.apply()
    );

    // Initial render + hover-couple wiring once the DOM is settled.
    setTimeout(() => {
      ns.bounds?.apply();
      ns.basinDiagram.redraw();
      ns.modePreview.redraw();
      ns.hoverCouple?.init();
    }, 60);
  };
})();
