#!/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)"

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

TMP="$(mktemp)"

awk '
BEGIN{
  inserted_flag = 0
  replaced_join = 0
}
{
  if (!inserted_flag && $0 ~ /let remoteVideoTrack = null;/) {
    print
    print ""
    print "  let joinInFlight = false;"
    inserted_flag = 1
    next
  }

  if (!replaced_join && $0 ~ /^  async function join\(\)\{/){
    print "  async function join(){"
    print "    if (joined) return;"
    print "    if (joinInFlight) return;"
    print "    joinInFlight = true;"
    print ""
    print "    if (els.btnJoin) els.btnJoin.disabled = true;"
    print ""
    print "    try{"
    print "      const roomName = (els.room && els.room.value.trim()) || \"\";"
    print "      const name = (els.name && els.name.value.trim()) || \"Guest\";"
    print "      if (!roomName){ alert(\"Room is required.\"); return; }"
    print ""
    print "      setStatus(\"Connecting…\");"
    print ""
    print "      lkRoom = new LK.Room({ adaptiveStream: true, dynacast: true });"
    print ""
    print "      lkRoom"
    print "        .on(LK.RoomEvent.Connected, () => {"
    print "          setStatus(\"Connected\");"
    print "          refreshGuestStrip();"
    print "          if (els.chatRoomMini) els.chatRoomMini.textContent = `• ${roomName}`;"
    print "          appendBubble({ from:\"System\", text:`Joined room: ${roomName}`, time: nowTime(), mine:false });"
    print "        })"
    print "        .on(LK.RoomEvent.Disconnected, () => {"
    print "          setStatus(\"Disconnected\");"
    print "          joined = false;"
    print "          cleanupTracks();"
    print "          clearRemote();"
    print "          if (remoteVU) remoteVU.detach();"
    print "          localHandUp = false;"
    print "          handMap.clear();"
    print "          syncButtons();"
    print "          refreshGuestStrip();"
    print "        })"
    print "        .on(LK.RoomEvent.ParticipantConnected, () => {"
    print "          refreshGuestStrip();"
    print "          attachRemoteFromParticipant(pickRemoteVideoParticipant());"
    print "        })"
    print "        .on(LK.RoomEvent.ParticipantDisconnected, () => {"
    print "          refreshGuestStrip();"
    print "          attachRemoteFromParticipant(pickRemoteVideoParticipant());"
    print "        })"
    print "        .on(LK.RoomEvent.TrackSubscribed, () => {"
    print "          refreshGuestStrip();"
    print "          attachRemoteFromParticipant(pickRemoteVideoParticipant());"
    print "        })"
    print "        .on(LK.RoomEvent.TrackUnsubscribed, () => {"
    print "          refreshGuestStrip();"
    print "          attachRemoteFromParticipant(pickRemoteVideoParticipant());"
    print "        })"
    print "        .on(LK.RoomEvent.AudioPlaybackStatusChanged, (playing) => showAudioGate(!playing))"
    print "        .on(LK.RoomEvent.DataReceived, (payload, participant, kind, topic) => {"
    print "          if (topic && topic !== CHAT_TOPIC) return;"
    print ""
    print "          let msg = null;"
    print "          try{"
    print "            msg = JSON.parse(dec.decode(payload));"
    print "          }catch(_){"
    print "            return;"
    print "          }"
    print "          if (!msg || !msg.t) return;"
    print ""
    print "          const fromName = bestDisplayName(participant, \"Guest\");"
    print "          const fromId = participantKey(participant) || fromName;"
    print "          const t = nowTime();"
    print ""
    print "          if (msg.t === \"chat\" && typeof msg.text === \"string\"){"
    print "            const text = msg.text;"
    print "            setTicker(`${fromName}: ${text}`, t, true);"
    print "            appendBubble({ from: fromName, text, time: t, mine: false });"
    print "          } else if (msg.t === \"hand\"){"
    print "            const up = !!msg.up;"
    print "            if (fromId) handMap.set(fromId, up);"
    print "            refreshGuestStrip();"
    print "            const text = up ? \"✋ raised hand\" : \"✋ lowered hand\";"
    print "            setTicker(`${fromName}: ${text}`, t, true);"
    print "            appendBubble({ from: fromName, text, time: t, mine: false });"
    print "          } else if (msg.t === \"reaction\" && typeof msg.emoji === \"string\"){"
    print "            const emoji = msg.emoji;"
    print "            const text = `Reacted ${emoji}`;"
    print "            setTicker(`${fromName}: ${emoji}`, t, true);"
    print "            appendBubble({ from: fromName, text, time: t, mine: false });"
    print "          } else {"
    print "            return;"
    print "          }"
    print ""
    print "          if (!chatOpen){"
    print "            unread = Math.min(99, unread + 1);"
    print "            updateBadges();"
    print "          }"
    print "        });"
    print ""
    print "      const lkUrl = (els.lkurl && els.lkurl.value.trim()) || DEFAULT_LK_URL;"
    print "      const token = await fetchToken({ roomName, name, publish: true, subscribe: true });"
    print ""
    print "      await lkRoom.connect(lkUrl, token);"
    print "      await ensureAudioPlayback();"
    print ""
    print "      joined = true;"
    print "      setStatus(\"In room\");"
    print "      syncButtons();"
    print ""
    print "      attachRemoteFromParticipant(pickRemoteVideoParticipant());"
    print "      startVuLoop();"
    print ""
    print "      buildShare();"
    print "      refreshGuestStrip();"
    print ""
    print "      detachLocal();"
    print "      if (localVU) localVU.setIdle();"
    print ""
    print "      await enumerateDevices().catch(()=>{});"
    print "    }catch(e){"
    print "      console.error(e);"
    print "      alert(String(e));"
    print "      try { if (lkRoom) await lkRoom.disconnect(); } catch(_){ }"
    print "      lkRoom = null;"
    print "      joined = false;"
    print "      setStatus(\"Idle\");"
    print "      cleanupTracks();"
    print "      clearRemote();"
    print "      syncButtons();"
    print "      refreshGuestStrip();"
    print "    }finally{"
    print "      joinInFlight = false;"
    print "      if (!joined && els.btnJoin) els.btnJoin.disabled = false;"
    print "    }"
    print "  }"

    replaced_join = 1

    depth = 1
    while ((getline line) > 0) {
      opens = gsub(/\{/, "{", line)
      closes = gsub(/\}/, "}", line)
      depth += opens
      depth -= closes
      if (depth <= 0) break
    }
    next
  }

  print
}
' "$JOINPHP" > "$TMP"

mv "$TMP" "$JOINPHP"

echo
echo "Patch complete."
echo
echo "Run syntax check:"
echo "php -l \"$JOINPHP\""
