#!/usr/bin/env bash
set -euo pipefail

FILE="assets/js/modules/coproducer.inline-main.js"
OUT="assets/js/modules/coproducer.inline-main.master_patched.js"
BACKUP="${FILE}.bak_master_$(date +%Y%m%d_%H%M%S)"

cp -p "$FILE" "$BACKUP"

python_free_perl_patch() {
perl -0pe '

# ------------------------------------------------------------
# 1) Add master state markers once
# ------------------------------------------------------------
if ($_ !~ /MASTER_CH_ID\s*=\s*["\x27]master["\x27]/) {
  s@(const SLOTS = 5;.*?)@\1

const MASTER_CH_ID = "master";
let masterLevel = 0;
let masterMuted = false;
let masterVolume = 1;
@sm;
}

# ------------------------------------------------------------
# 2) Add helper functions once
# ------------------------------------------------------------
if ($_ !~ /function computeMasterLevel\(\)/) {
  s@(function updatePreviewPanel\(\)\{)@function computeMasterLevel(){
  try{
    let sum = 0;
    let count = 0;

    if (typeof slots !== "undefined" && Array.isArray(slots)) {
      for (const s of slots) {
        if (!s) continue;
        const hear = (s.micMonitorOn !== false);
        const lvl = Number(s._meterLevel || s.meter || s.level || 0) || 0;
        if (hear) {
          sum += lvl;
          count++;
        }
      }
    }

    if (typeof mediaState !== "undefined" && mediaState) {
      const mediaLvl =
        Number(mediaState._meterLevel || mediaState.meter || mediaState.level || 0) || 0;
      const mediaAudible = mediaState.muted ? 0 : 1;
      if (mediaAudible) {
        sum += mediaLvl;
        count++;
      }
    }

    const avg = count > 0 ? (sum / count) : 0;
    masterLevel = Math.max(0, Math.min(1, avg * (masterMuted ? 0 : masterVolume)));
    return masterLevel;
  }catch(_){
    masterLevel = 0;
    return 0;
  }
}

function setMasterVolume(v){
  masterVolume = Math.max(0, Math.min(1.5, Number(v) || 0));
  try { localStorage.setItem("coproducer_master_volume_v1", String(masterVolume)); } catch(_){}
}

function setMasterMuted(v){
  masterMuted = !!v;
  try { localStorage.setItem("coproducer_master_muted_v1", masterMuted ? "1" : "0"); } catch(_){}
}

function loadMasterState(){
  try{
    const mv = parseFloat(localStorage.getItem("coproducer_master_volume_v1") || "1");
    if (Number.isFinite(mv)) masterVolume = Math.max(0, Math.min(1.5, mv));
  }catch(_){}
  try{
    masterMuted = localStorage.getItem("coproducer_master_muted_v1") === "1";
  }catch(_){}
}

\1@sm;
}

# ------------------------------------------------------------
# 3) Ensure loadMasterState() runs
# ------------------------------------------------------------
if ($_ !~ /loadMasterState\(\);/) {
  s@(loadMediaLibrary\(\);)@loadMasterState();
\1@sm;
}

# ------------------------------------------------------------
# 4) Add master strip after media in mixer HTML builder
#    This targets a common strip HTML pattern by appending
#    one extra strip after media strip generation.
# ------------------------------------------------------------
if ($_ !~ /mixerStrip--master/) {
  s@((?:renderMixer|buildMixer|renderAudioMixer).*?\{.*?)(return\s+html;|mixerEl\.innerHTML\s*=\s*html;|return\s+out;)@\1

  try{
    var __masterPeak = computeMasterLevel();
    var __masterPressed = masterMuted ? "false" : "true";
    var __masterPct = Math.round((masterVolume || 1) * 100);

    var __masterStrip = `
      <div class="ch mixerStrip mixerStrip--master" data-ch="master">
        <div class="chHead">
          <div class="chName">MASTER</div>
          <div class="chSub">BUS</div>
        </div>

        <div class="meter masterMeter" data-master-meter="1">
          <div class="ledStack">
            ${Array.from({length:20}).map((_,i)=>{
              const on = __masterPeak > ((20 - i) / 20);
              return `<span class="led ${on ? "on" : ""}"></span>`;
            }).join("")}
          </div>
        </div>

        <div class="faderWrap">
          <input
            type="range"
            min="0"
            max="1.5"
            step="0.01"
            value="${masterVolume}"
            data-master-fader="1"
            orient="vertical"
          >
        </div>

        <div class="chBtns">
          <button class="btn ${masterMuted ? "" : "on"}" data-master-mute="1" aria-pressed="${__masterPressed}" title="Master Mute">
            M
          </button>
        </div>

        <div class="chVal">${__masterPct}%</div>
      </div>
    `;

    if (typeof html !== "undefined") html += __masterStrip;
    if (typeof out !== "undefined") out += __masterStrip;
  }catch(_){}

\2@sm;
}

# ------------------------------------------------------------
# 5) Add delegated event handlers for master controls
# ------------------------------------------------------------
if ($_ !~ /data-master-fader/) {
  s@(document\.addEventListener\(["\x27]input["\x27],\s*function\s*\(ev\)\s*\{)@\1
  try{
    var mf = ev.target && ev.target.matches ? ev.target.matches("[data-master-fader=\"1\"]") : false;
    if (mf) {
      setMasterVolume(ev.target.value);
      if (typeof renderUI === "function") renderUI();
      return;
    }
  }catch(_){}
@sm;

  s@(document\.addEventListener\(["\x27]click["\x27],\s*function\s*\(ev\)\s*\{)@\1
  try{
    var mm = ev.target && ev.target.closest ? ev.target.closest("[data-master-mute=\"1\"]") : null;
    if (mm) {
      ev.preventDefault();
      setMasterMuted(!masterMuted);
      if (typeof renderUI === "function") renderUI();
      return;
    }
  }catch(_){}
@sm;
}

# ------------------------------------------------------------
# 6) Refresh master meter during UI updates
# ------------------------------------------------------------
if ($_ !~ /computeMasterLevel\(\);\s*\/\/ master refresh/) {
  s@(function renderUI\(\)\{)@\1
  computeMasterLevel(); // master refresh
@sm;
}

# ------------------------------------------------------------
# 7) Add minimal CSS injection once
# ------------------------------------------------------------
if ($_ !~ /__masterMixerCssV1/) {
  s@(document\.body\.classList\.add\(["\x27]appReady["\x27]\);|if\s*\(document\.readyState.*?boot\(\);)@try{
  if (!document.getElementById("__masterMixerCssV1")) {
    var st = document.createElement("style");
    st.id = "__masterMixerCssV1";
    st.textContent = `
      .mixerStrip--master .chName{color:#ffd089}
      .mixerStrip--master .led.on{filter:saturate(1.15) brightness(1.05)}
      .mixerStrip--master [data-master-fader="1"]{accent-color:#d08a2f}
      .mixerStrip--master .btn{min-width:32px}
    `;
    document.head.appendChild(st);
  }
}catch(_){}
\1@sm;
}

' "$FILE" > "$OUT"
}

python_free_perl_patch

echo "Backup: $BACKUP"
echo "Output: $OUT"
echo
echo "Syntax sanity:"
node -c "$OUT" 2>/dev/null || echo "node not available; JS syntax not auto-checked here"
echo
echo "Verification markers:"
grep -n 'MASTER_CH_ID\|computeMasterLevel\|data-master-fader\|data-master-mute\|mixerStrip--master' "$OUT" || true
