const { PIDController } = require('./index');

console.log('=== PID CONTROLLER EXAMPLES ===\n');
console.log('This guide shows how to instantiate, tune, and operate the PID helper.\n');

// ====================================
// EXAMPLE 1: FLOW CONTROL LOOP
// ====================================
console.log('--- Example 1: Pump speed control ---');

const pumpController = new PIDController({
  kp: 1.1,
  ki: 0.35,
  kd: 0.08,
  sampleTime: 250, // ms
  outputMin: 0,
  outputMax: 100,
  derivativeFilter: 0.2
});

const pumpSetpoint = 75; // desired flow percentage
let pumpFlow = 20;
const pumpStart = Date.now();

for (let i = 0; i < 10; i += 1) {
  const timestamp = pumpStart + (i + 1) * pumpController.sampleTime;
  const controlSignal = pumpController.update(pumpSetpoint, pumpFlow, timestamp);

  // Simple first-order plant approximation
  pumpFlow += (controlSignal - pumpFlow) * 0.12;
  pumpFlow -= (pumpFlow - pumpSetpoint) * 0.05; // disturbance rejection

  console.log(
    `Cycle ${i + 1}: output=${controlSignal.toFixed(2)}% | flow=${pumpFlow.toFixed(2)}%`
  );
}

console.log('Pump loop state:', pumpController.getState(), '\n');

// ====================================
// EXAMPLE 2: TANK LEVEL WITH MANUAL/AUTO
// ====================================
console.log('--- Example 2: Tank level handover ---');

const tankController = new PIDController({
  kp: 2.0,
  ki: 0.5,
  kd: 0.25,
  sampleTime: 400,
  derivativeFilter: 0.25,
  outputMin: 0,
  outputMax: 1
}).setIntegralLimits(-0.3, 0.3);

tankController.setMode('manual');
tankController.setManualOutput(0.4);
console.log(`Manual output locked at ${tankController.getLastOutput().toFixed(2)}\n`);

tankController.setMode('automatic');

let level = 0.2;
const levelSetpoint = 0.8;
const tankStart = Date.now();

for (let step = 0; step < 8; step += 1) {
  const timestamp = tankStart + (step + 1) * tankController.sampleTime;
  const output = tankController.update(levelSetpoint, level, timestamp);

  // Integrating process with slight disturbance
  level += (output - 0.5) * 0.18;
  level += 0.02; // inflow bump
  level = Math.max(0, Math.min(1, level));

  console.log(
    `Cycle ${step + 1}: output=${output.toFixed(3)} | level=${level.toFixed(3)}`
  );
}

console.log('\nBest practice tips:');
console.log('  - Call update() on a fixed interval (sampleTime).');
console.log('  - Clamp output and integral to avoid windup.');
console.log('  - Use setMode("manual") during maintenance or bump-less transfer.');

module.exports = {
  pumpController,
  tankController
};
