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

JOINPHP="${1:-/home/itahukamedia/public_html/studio.itahukamedia.com/public/join.php}"
TS="$(date +%Y%m%d_%H%M%S)"

if [ ! -f "$JOINPHP" ]; then
  echo "File not found: $JOINPHP"
  exit 1
fi

cp -a "$JOINPHP" "$JOINPHP.bak.$TS"
echo "Backup created: $JOINPHP.bak.$TS"

TMP_HELPERS="$(mktemp)"
TMP_OUT="$(mktemp)"

cat > "$TMP_HELPERS" <<'EOF'
  async function enumerateDevices(){
    if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) return;
    const devices = await navigator.mediaDevices.enumerateDevices();

    const micId = (els.micSel && els.micSel.value) || load("lk_join_mic", "");
    const camId = (els.camSel && els.camSel.value) || load("lk_join_cam", "");

    const mics = devices.filter(d => d.kind === "audioinput");
    const cams = devices.filter(d => d.kind === "videoinput");

    if (els.micSel){
      els.micSel.innerHTML = `<option value="">Auto</option>` + mics.map(d => {
        const label = d.label || `Microphone (${d.deviceId.slice(0,6)}…)`;
        const sel = (d.deviceId === micId) ? "selected" : "";
        return `<option ${sel} value="${escapeHtml(d.deviceId)}">${escapeHtml(label)}</option>`;
      }).join("");
    }

    if (els.camSel){
      els.camSel.innerHTML = `<option value="">Auto</option>` + cams.map(d => {
        const label = d.label || `Camera (${d.deviceId.slice(0,6)}…)`;
        const sel = (d.deviceId === camId) ? "selected" : "";
        return `<option ${sel} value="${escapeHtml(d.deviceId)}">${escapeHtml(label)}</option>`;
      }).join("");
    }
  }

  function setIndicator(el, type, isOn){
    if (!el) return;
    el.className = `ind ${type} ` + (isOn ? "on" : "off");
    el.textContent = type.toUpperCase();
  }

  function ensureTile(key, displayName){
    let tile = tileMap.get(key);
    if (tile) return tile;

    const root = document.createElement("div");
    root.className = "tile";
    root.dataset.key = key;

    const tileVid = document.createElement("div");
    tileVid.className = "tileVid";

    const videoEl = document.createElement("video");
    videoEl.playsInline = true;
    videoEl.autoplay = true;
    videoEl.muted = true;

    const fallbackEl = document.createElement("div");
    fallbackEl.className = "tileFallback";
    fallbackEl.textContent = "No video";

    tileVid.appendChild(videoEl);
    tileVid.appendChild(fallbackEl);

    const tileName = document.createElement("div");
    tileName.className = "tileName";

    const nameEl = document.createElement("span");
    nameEl.className = "nm";
    nameEl.textContent = displayName;

    const flagsEl = document.createElement("span");
    flagsEl.className = "tileFlags";

    tileName.appendChild(nameEl);
    tileName.appendChild(flagsEl);

    const tileInd = document.createElement("div");
    tileInd.className = "tileInd";

    const micEl = document.createElement("div");
    const camEl = document.createElement("div");
    micEl.className = "ind mic off";
    camEl.className = "ind cam off";
    micEl.textContent = "MIC";
    camEl.textContent = "CAM";

    tileInd.appendChild(micEl);
    tileInd.appendChild(camEl);

    root.appendChild(tileVid);
    root.appendChild(tileName);
    root.appendChild(tileInd);

    tile = { root, videoEl, fallbackEl, micEl, camEl, nameEl, flagsEl, attachedTrack: null };
    tileMap.set(key, tile);
    return tile;
  }

  function detachTileTrack(tile){
    if (!tile || !tile.attachedTrack) return;
    try { tile.attachedTrack.detach(tile.videoEl); } catch(_){}
    tile.attachedTrack = null;
  }

  function setTileVideo(tile, track){
    if (!tile) return;

    if (!track){
      detachTileTrack(tile);
      try { tile.videoEl.srcObject = null; } catch(_){}
      tile.fallbackEl.style.display = "flex";
      return;
    }

    if (tile.attachedTrack === track){
      tile.fallbackEl.style.display = "none";
      return;
    }

    detachTileTrack(tile);
    tile.attachedTrack = track;
    try { track.attach(tile.videoEl); } catch(_){}
    tile.fallbackEl.style.display = "none";
  }

  function computeRemoteMicCam(p){
    let micOn = false;
    let camOn = false;

    for (const pub of p.audioTrackPublications.values()){
      if (pub && pub.isMuted === false) { micOn = true; break; }
      if (pub && typeof pub.isMuted === "undefined") { micOn = !!pub.track; }
    }
    for (const pub of p.videoTrackPublications.values()){
      if (pub && pub.isMuted === false) { camOn = true; break; }
      if (pub && typeof pub.isMuted === "undefined") { camOn = !!pub.track; }
    }
    return { micOn, camOn };
  }

EOF

need_insert=0
grep -q 'async function enumerateDevices(' "$JOINPHP" || need_insert=1
grep -q 'function ensureTile(' "$JOINPHP" || need_insert=1
grep -q 'function setTileVideo(' "$JOINPHP" || need_insert=1
grep -q 'function computeRemoteMicCam(' "$JOINPHP" || need_insert=1
grep -q 'function setIndicator(' "$JOINPHP" || need_insert=1

if [ "$need_insert" -eq 0 ]; then
  echo "Helpers already present. Nothing changed."
  rm -f "$TMP_HELPERS" "$TMP_OUT"
  exit 0
fi

awk -v helper="$TMP_HELPERS" '
BEGIN{
  inserted = 0
  while ((getline line < helper) > 0) block = block line "\n"
  close(helper)
}
{
  if (!inserted && $0 ~ /^  function refreshGuestStrip\(\)\{/){
    printf "%s", block
    inserted = 1
  }
  print
}
END{
  if (!inserted) printf "%s", block
}
' "$JOINPHP" > "$TMP_OUT"

mv "$TMP_OUT" "$JOINPHP"
rm -f "$TMP_HELPERS"

echo
echo "Patch complete."
echo
echo "Run:"
echo "php -l \"$JOINPHP\""
echo "grep -n \"async function enumerateDevices\\|function ensureTile\\|function setTileVideo\\|function computeRemoteMicCam\\|function setIndicator\" \"$JOINPHP\""
