'use strict';
const fs = require('fs');
const path = require('path');

const targetFile = path.join(__dirname, '../../frontend/js/labs/opticsbench.js');
let src = fs.readFileSync(targetFile, 'utf-8');

// --- 1. Add ifSim variable declaration after freeSim ---
if (src.indexOf('var ifSim') < 0) {
  src = src.replace(
    'var freeSim    = null; /* multi-lens free-build (Agent OB-A3) */',
    'var freeSim    = null; /* multi-lens free-build (Agent OB-A3) */\r\nvar ifSim      = null; /* interference/polarization (Agent C) */'
  );
  console.log('Added ifSim declaration');
} else {
  console.log('ifSim declaration already exists');
}

// --- 2. Add 'interf' to tab array in obSwitchMode ---
const tabArrOld = "['lens', 'mirror', 'refraction', 'prism', 'freebuild', 'waves'].forEach(m => {";
const tabArrNew = "['lens', 'mirror', 'refraction', 'prism', 'freebuild', 'waves', 'interf'].forEach(m => {";
if (src.indexOf(tabArrNew) < 0) {
  if (src.indexOf(tabArrOld) >= 0) {
    src = src.replace(tabArrOld, tabArrNew);
    console.log('Updated tab array');
  } else {
    console.log('WARN: tab array old pattern not found');
  }
} else {
  console.log('Tab array already updated');
}

// --- 3. Add 'ob-ctrl-interf' to control panels array ---
const ctrlArrOld = "['ob-ctrl-lens', 'ob-ctrl-mirror', 'ob-ctrl-refraction', 'ob-ctrl-prism', 'ob-ctrl-freebuild', 'ob-ctrl-waves'].forEach(id => {";
const ctrlArrNew = "['ob-ctrl-lens', 'ob-ctrl-mirror', 'ob-ctrl-refraction', 'ob-ctrl-prism', 'ob-ctrl-freebuild', 'ob-ctrl-waves', 'ob-ctrl-interf'].forEach(id => {";
if (src.indexOf(ctrlArrNew) < 0) {
  if (src.indexOf(ctrlArrOld) >= 0) {
    src = src.replace(ctrlArrOld, ctrlArrNew);
    console.log('Updated ctrl panel array');
  } else {
    console.log('WARN: ctrl panel array old pattern not found');
  }
} else {
  console.log('Ctrl panel array already updated');
}

// --- 4. Add 'ob-stats-interf' to stats array ---
const statsArrOld = "['ob-stats-lens', 'ob-stats-mirror', 'ob-stats-refr', 'ob-stats-prism', 'ob-stats-freebuild', 'ob-stats-waves'].forEach(id => {";
const statsArrNew = "['ob-stats-lens', 'ob-stats-mirror', 'ob-stats-refr', 'ob-stats-prism', 'ob-stats-freebuild', 'ob-stats-waves', 'ob-stats-interf'].forEach(id => {";
if (src.indexOf(statsArrNew) < 0) {
  if (src.indexOf(statsArrOld) >= 0) {
    src = src.replace(statsArrOld, statsArrNew);
    console.log('Updated stats array');
  } else {
    console.log('WARN: stats array old pattern not found');
  }
} else {
  console.log('Stats array already updated');
}

// --- 5. Add 'ob-interf-canvas' to canvas arrays ---
const canvasIdsOld = "const canvasIds = ['ob-lens-canvas', 'ob-mirror-canvas', 'ob-refr-canvas', 'ob-prism-canvas', 'ob-free-canvas', 'ob-waves-canvas'];";
const canvasIdsNew = "const canvasIds = ['ob-lens-canvas', 'ob-mirror-canvas', 'ob-refr-canvas', 'ob-prism-canvas', 'ob-free-canvas', 'ob-waves-canvas', 'ob-interf-canvas'];";
if (src.indexOf(canvasIdsNew) < 0) {
  if (src.indexOf(canvasIdsOld) >= 0) {
    src = src.replace(canvasIdsOld, canvasIdsNew);
    console.log('Updated canvasIds');
  } else {
    console.log('WARN: canvasIds old pattern not found');
  }
} else {
  console.log('canvasIds already updated');
}

const modeCanvasOld = "const modeCanvas = { lens: 'ob-lens-canvas', mirror: 'ob-mirror-canvas', refraction: 'ob-refr-canvas', prism: 'ob-prism-canvas', freebuild: 'ob-free-canvas', waves: 'ob-waves-canvas' };";
const modeCanvasNew = "const modeCanvas = { lens: 'ob-lens-canvas', mirror: 'ob-mirror-canvas', refraction: 'ob-refr-canvas', prism: 'ob-prism-canvas', freebuild: 'ob-free-canvas', waves: 'ob-waves-canvas', interf: 'ob-interf-canvas' };";
if (src.indexOf(modeCanvasNew) < 0) {
  if (src.indexOf(modeCanvasOld) >= 0) {
    src = src.replace(modeCanvasOld, modeCanvasNew);
    console.log('Updated modeCanvas');
  } else {
    console.log('WARN: modeCanvas old pattern not found');
  }
} else {
  console.log('modeCanvas already updated');
}

// --- 6. Add 'interf' case in obSwitchMode, before closing brace ---
const interfCaseStr = `  } else if (mode === 'interf') {  /* Agent C — interference / polarization */\r\n    if (!ifSim) {\r\n      const cv = document.getElementById('ob-interf-canvas');\r\n      if (cv) { ifSim = new InterferenceSim(cv); ifSim.onUpdate = _ifUpdateUI; }\r\n    }\r\n    if (ifSim) { ifSim.fit(); ifSim.draw(); }\r\n    _ifUpdateUI();\r\n  }\r\n}`;

const oldModeEnd = `  } else if (mode === 'waves') {  /* Agent B1 — diffraction & interference */\r\n    if (!diffrSim) {\r\n      const cv = document.getElementById('ob-waves-canvas');\r\n      if (cv) diffrSim = new DiffractionSim(cv);\r\n    }\r\n    if (diffrSim) {\r\n      diffrSim.fit();\r\n      diffrSim.draw();\r\n      diffrSim._updateHUD();\r\n    }\r\n  }\r\n}`;

const newModeEnd = `  } else if (mode === 'waves') {  /* Agent B1 — diffraction & interference */\r\n    if (!diffrSim) {\r\n      const cv = document.getElementById('ob-waves-canvas');\r\n      if (cv) diffrSim = new DiffractionSim(cv);\r\n    }\r\n    if (diffrSim) {\r\n      diffrSim.fit();\r\n      diffrSim.draw();\r\n      diffrSim._updateHUD();\r\n    }\r\n  } else if (mode === 'interf') {  /* Agent C — interference / polarization */\r\n    if (!ifSim) {\r\n      const cv = document.getElementById('ob-interf-canvas');\r\n      if (cv) { ifSim = new InterferenceSim(cv); ifSim.onUpdate = _ifUpdateUI; }\r\n    }\r\n    if (ifSim) { ifSim.fit(); ifSim.draw(); }\r\n    _ifUpdateUI();\r\n  }\r\n}`;

if (src.indexOf('else if (mode === \'interf\')') < 0) {
  if (src.indexOf(oldModeEnd) >= 0) {
    src = src.replace(oldModeEnd, newModeEnd);
    console.log('Added interf case in obSwitchMode');
  } else {
    // Try with LF only
    const oldLF = oldModeEnd.replace(/\r\n/g, '\n');
    const newLF = newModeEnd.replace(/\r\n/g, '\n');
    if (src.indexOf(oldLF) >= 0) {
      src = src.replace(oldLF, newLF);
      console.log('Added interf case (LF variant)');
    } else {
      console.log('WARN: waves mode end pattern not found - trying fallback');
      // Fallback: find closing brace of obSwitchMode after diffrSim block
      const marker2 = "diffrSim._updateHUD();\n    }\n  }\n}";
      const marker2cr = "diffrSim._updateHUD();\r\n    }\r\n  }\r\n}";
      const repl2 = "diffrSim._updateHUD();\n    }\n  } else if (mode === 'interf') {\n    if (!ifSim) {\n      const cv = document.getElementById('ob-interf-canvas');\n      if (cv) { ifSim = new InterferenceSim(cv); ifSim.onUpdate = _ifUpdateUI; }\n    }\n    if (ifSim) { ifSim.fit(); ifSim.draw(); }\n    _ifUpdateUI();\n  }\n}";
      const repl2cr = "diffrSim._updateHUD();\r\n    }\r\n  } else if (mode === 'interf') {\r\n    if (!ifSim) {\r\n      const cv = document.getElementById('ob-interf-canvas');\r\n      if (cv) { ifSim = new InterferenceSim(cv); ifSim.onUpdate = _ifUpdateUI; }\r\n    }\r\n    if (ifSim) { ifSim.fit(); ifSim.draw(); }\r\n    _ifUpdateUI();\r\n  }\r\n}";
      if (src.indexOf(marker2) >= 0) {
        src = src.replace(marker2, repl2);
        console.log('Added interf case (fallback LF)');
      } else if (src.indexOf(marker2cr) >= 0) {
        src = src.replace(marker2cr, repl2cr);
        console.log('Added interf case (fallback CRLF)');
      } else {
        console.log('WARN: all fallbacks failed for interf case');
      }
    }
  }
} else {
  console.log('interf case already exists');
}

// --- 7. Add _ifUpdateUI function and control functions ---
const ifUICode = `
/* ── Interference mode UI callbacks (Agent C) ── */
function _ifUpdateUI() {
  if (!ifSim) return;
  const subMode = ifSim.subMode;
  ['if-ctrl-newton', 'if-ctrl-thinfilm', 'if-ctrl-polarization'].forEach(id => {
    const el = document.getElementById(id);
    if (el) el.style.display = 'none';
  });
  const active = document.getElementById('if-ctrl-' + subMode);
  if (active) active.style.display = '';
  ['if-sub-newton', 'if-sub-thinfilm', 'if-sub-polarization'].forEach(id => {
    const el = document.getElementById(id);
    if (el) el.classList.toggle('active', id === 'if-sub-' + subMode);
  });
}

function ifSwitchSub(sub) {
  if (window.LabFX) LabFX.sound.play('chime');
  if (!ifSim) return;
  ifSim.setSubMode(sub);
  _ifUpdateUI();
}

function ifNewtParam(key, val) {
  if (!ifSim) return;
  const v = parseFloat(val);
  if (key === 'R') { ifSim.nR = v; document.getElementById('if-newton-r-val').textContent = v; }
  else if (key === 'nmax') { ifSim.nNmax = Math.round(v); document.getElementById('if-newton-n-val').textContent = Math.round(v); }
  ifSim.draw();
}

function ifThinFilmParam(key, val) {
  if (!ifSim) return;
  const v = parseFloat(val);
  if (key === 't')     { ifSim.tfT = v;     document.getElementById('if-tf-t-val').textContent = v; }
  else if (key === 'n') { ifSim.tfN = v;     document.getElementById('if-tf-n-val').textContent = v.toFixed(2); }
  else if (key === 'theta') { ifSim.tfTheta = v; document.getElementById('if-tf-th-val').textContent = v; }
  ifSim.draw();
}

function ifThinFilmPreset(name) {
  if (!ifSim) return;
  const presets = {
    soap:    { n: 1.33, label: 'Мыльная плёнка' },
    oil:     { n: 1.50, label: 'Масло на воде'  },
    coating: { n: 1.38, label: 'Антибликовое покрытие' },
  };
  const p = presets[name];
  if (!p) return;
  ifSim.tfN = p.n;
  ifSim.tfPreset = name;
  const slN = document.getElementById('sl-if-tf-n');
  if (slN) slN.value = p.n;
  const lbN = document.getElementById('if-tf-n-val');
  if (lbN) lbN.textContent = p.n.toFixed(2);
  ifSim.draw();
  if (window.LabFX) LabFX.sound.play('chime');
}

function ifPolParam(key, val) {
  if (!ifSim) return;
  const v = parseFloat(val);
  if (key === 'theta') { ifSim.polTheta = v; document.getElementById('if-pol-th-val').textContent = v; }
  ifSim.draw();
}

function ifPolSrc(val) {
  if (!ifSim) return;
  ifSim.polSrc = val;
  ifSim.draw();
}
`;

if (src.indexOf('function _ifUpdateUI') < 0) {
  // Insert before the closing of the file or before _obRedraw
  const insertBefore = 'function _obRedraw()';
  const insertIdx = src.indexOf(insertBefore);
  if (insertIdx >= 0) {
    src = src.slice(0, insertIdx) + ifUICode + '\r\n' + src.slice(insertIdx);
    console.log('Added _ifUpdateUI and control functions');
  } else {
    src = src + '\r\n' + ifUICode;
    console.log('Appended _ifUpdateUI at end');
  }
} else {
  console.log('_ifUpdateUI already exists');
}

// --- 8. Make _obRedraw also redraw ifSim if active ---
const redrawOld = 'function _obRedraw() {';
const redrawNew = 'function _obRedraw() {';
// Find _obRedraw body and add ifSim redraw
if (src.indexOf('if (ifSim && _obMode') < 0) {
  const marker3 = "if (prismSim && _obMode === 'prism')";
  const repl3   = "if (ifSim && _obMode === 'interf') { ifSim.draw(); }\r\n  if (prismSim && _obMode === 'prism')";
  const marker3lf = "if (prismSim && _obMode === 'prism')";
  if (src.indexOf(marker3) >= 0) {
    src = src.replace(marker3, repl3);
    console.log('Added ifSim redraw to _obRedraw');
  } else {
    console.log('WARN: could not find _obRedraw prism marker');
  }
}

fs.writeFileSync(targetFile, src, 'utf-8');
console.log('Done. New size:', src.length);
