<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>Coven</title>

  <!-- Firebase (v8) -->
  <script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-database.js"></script>

  <style>
    /*************************************************************
     *                     BASIC STYLES
     *************************************************************/
    * {
      margin: 0; 
      padding: 0; 
      box-sizing: border-box;
    }
    body {
      font-family: Whitney, "Helvetica Neue", Helvetica, Arial, sans-serif;
      background-color: #36393f;
      color: #dcddde;
      height: 100vh;
      display: flex;
      flex-direction: column;
      overflow: hidden;
    }
    a { 
      color: #7289da; 
      text-decoration: none; 
    }

    /*************************************************************
     *                   CONTAINER LAYOUT
     *************************************************************/
    .container {
      display: flex;
      flex: 1;
      overflow: hidden;
    }

    /*************************************************************
     *                   SERVERS LEFT BAR
     *************************************************************/
    .servers-bar {
      width: 70px; 
      background-color: #202225;
      display: flex; 
      flex-direction: column; 
      align-items: center;
      padding: 10px 0; 
      overflow-y: auto;
    }
    .server-icon {
      width: 50px; 
      height: 50px; 
      background-color: #5865f2;
      border-radius: 50%; 
      margin-bottom: 10px;
      display: flex; 
      justify-content: center; 
      align-items: center;
      cursor: pointer; 
      font-weight: bold; 
      color: #fff; 
      font-size: 14px;
      user-select: none; 
      transition: background-color 0.2s;
    }
    .server-icon:hover {
      background-color: #4a57c2;
    }
    .server-icon.hidden {
      display: none;
    }

    /*************************************************************
     *                   SIDEBAR (FRIENDS)
     *************************************************************/
    .sidebar {
      width: 240px; 
      background-color: #2f3136;
      display: flex; 
      flex-direction: column; 
      overflow-y: auto;
    }
    .sidebar h2 {
      background-color: #202225; 
      padding: 15px;
      font-size: 16px; 
      font-weight: bold; 
      border-bottom: 1px solid #222;
    }
    .section-title {
      color: #b9bbbe; 
      font-size: 12px; 
      text-transform: uppercase;
      margin: 10px 0 5px 15px;
    }
    .sidebar-item {
      padding: 8px 15px; 
      cursor: pointer; 
      color: #b9bbbe;
    }
    .sidebar-item:hover {
      background-color: #3f4147; 
      color: #fff;
    }

    /*************************************************************
     *                   CHAT AREA
     *************************************************************/
    .chat-area {
      flex: 1; 
      display: flex; 
      flex-direction: column;
      background-color: #36393f;
    }
    .chat-header {
      background-color: #2f3136; 
      padding: 10px;
      border-bottom: 1px solid #222; 
      display: flex; 
      align-items: center;
      justify-content: space-between;
    }
    .chat-header h2 {
      font-size: 16px; 
      font-weight: bold; 
      color: #fff;
      margin-right: 10px;
    }
    .chat-header button {
      background-color: #7289da; 
      border: none; 
      border-radius: 5px;
      color: #fff; 
      cursor: pointer; 
      padding: 5px 10px; 
      font-size: 12px;
      transition: background-color 0.2s;
    }
    .chat-header button:hover {
      background-color: #5b6eae;
    }
    .banner {
      background-color: #202225; 
      text-align: center;
      padding: 10px; 
      color: #fff; 
      font-size: 14px;
    }
    .messages {
      flex: 1; 
      padding: 10px; 
      overflow-y: auto;
    }
    .message {
      margin-bottom: 10px; 
      line-height: 1.3; 
      display: flex; 
      align-items: flex-start;
    }
    .pfp {
      width: 32px; 
      height: 32px; 
      border-radius: 50%; 
      object-fit: cover;
      margin-right: 8px;
    }
    .message-content {
      display: flex; 
      flex-direction: column;
    }
    .author {
      font-weight: 600; 
      margin-right: 5px; 
      display: inline-block;
    }
    .bot .author {
      color: #43b581;
    }
    .user .author {
      color: #7289da;
    }
    /* Purple Glow specifically for anarxyfr#0000 */
    .root-glow .author {
      color: #bd93f9;
      text-shadow: 0 0 7px rgba(189,147,249,0.8);
    }

    .input-area {
      border-top: 1px solid #222; 
      padding: 10px; 
      display: flex;
    }
    .input-area textarea {
      flex: 1; 
      background-color: #40444b; 
      border: none; 
      resize: none;
      border-radius: 5px; 
      color: #dcddde; 
      padding: 8px; 
      font-size: 14px;
      height: 50px; 
      margin-right: 10px; 
      transition: background-color 0.2s;
    }
    .input-area button {
      width: 80px; 
      background-color: #7289da; 
      border: none;
      border-radius: 5px; 
      color: #fff; 
      cursor: pointer; 
      font-size: 14px;
      transition: background-color 0.2s;
    }
    .input-area button:hover {
      background-color: #5b6eae;
    }

    /*************************************************************
     *                   RIGHT BAR
     *************************************************************/
    .right-bar {
      width: 240px; 
      background-color: #2f3136;
      display: flex; 
      flex-direction: column; 
      overflow-y: auto;
    }
    .profile-section {
      padding: 15px; 
      border-bottom: 1px solid #222; 
      text-align: center;
    }
    .profile-section img {
      width: 80px; 
      height: 80px; 
      border-radius: 50%; 
      object-fit: cover;
      margin-bottom: 10px;
    }
    .profile-section .banner {
      width: 100%; 
      height: 60px; 
      background-size: cover;
      background-position: center; 
      margin-bottom: 10px; 
      border-radius: 5px;
    }
    .username {
      font-size: 16px; 
      font-weight: bold; 
      color: #fff; 
      margin-bottom: 5px;
    }
    .bio {
      font-size: 14px; 
      color: #b9bbbe; 
      margin-bottom: 5px;
    }
    .edit-profile {
      background-color: #4a57c2; 
      border: none; 
      border-radius: 5px;
      color: #fff; 
      cursor: pointer; 
      font-size: 12px; 
      padding: 5px 10px;
      transition: background-color 0.2s;
    }
    .edit-profile:hover {
      background-color: #5b6eae;
    }

    .dm-section {
      padding: 15px;
    }
    .dm-item {
      background-color: #40444b; 
      padding: 8px;
      border-radius: 5px; 
      margin-bottom: 5px; 
      cursor: pointer;
    }
    .dm-item:hover {
      background-color: #4f545c;
    }

    /* Friend Requests */
    .friend-request-ui {
      padding: 15px; 
      border-top: 1px solid #222;
    }
    .friend-request-ui input {
      width: 100%; 
      background-color: #40444b; 
      border: none;
      border-radius: 5px; 
      color: #dcddde; 
      padding: 8px; 
      margin-bottom: 5px;
    }
    .friend-request-ui button {
      background-color: #7289da; 
      border: none; 
      border-radius: 5px;
      color: #fff; 
      padding: 5px 10px; 
      cursor: pointer; 
      font-size: 12px;
      transition: background-color 0.2s;
    }
    .friend-request-ui button:hover {
      background-color: #5b6eae;
    }
    .friend-requests-list {
      margin-top: 10px;
    }
    .request-item {
      background-color: #40444b; 
      padding: 8px; 
      border-radius: 5px;
      margin-bottom: 5px; 
      display: flex; 
      justify-content: space-between; 
      align-items: center;
    }
    .request-item button {
      background-color: #7289da; 
      border: none; 
      border-radius: 5px; 
      color: #fff;
      cursor: pointer; 
      margin-left: 5px; 
      padding: 5px 10px; 
      font-size: 12px;
    }
    .request-item button:hover {
      background-color: #5b6eae;
    }

    /*************************************************************
     *                   AUTH OVERLAY
     *************************************************************/
    .auth-overlay {
      position: absolute; 
      top: 0; 
      left: 0; 
      right: 0; 
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.8);
      display: flex; 
      justify-content: center; 
      align-items: center;
      z-index: 9998;
    }
    .auth-box {
      background-color: #2f3136; 
      padding: 20px; 
      border-radius: 5px;
      width: 300px; 
      text-align: center;
      animation: fadeIn 0.5s ease forwards;
    }
    .auth-box h3 {
      margin-bottom: 10px; 
      color: #fff;
    }
    .auth-box input {
      width: 100%; 
      background-color: #40444b; 
      border: none;
      border-radius: 5px; 
      color: #dcddde; 
      padding: 8px;
      margin-bottom: 5px; 
      font-size: 14px;
    }
    .auth-box button {
      width: 100%; 
      background-color: #7289da; 
      border: none;
      border-radius: 5px; 
      color: #fff; 
      cursor: pointer;
      padding: 8px 15px; 
      margin-top: 5px; 
      font-size: 14px;
      transition: background-color 0.2s;
    }
    .auth-box button:hover {
      background-color: #5b6eae;
    }
    .auth-error {
      margin-top: 5px; 
      color: #f04747; 
      min-height: 20px;
    }
    .toggle-link {
      margin-top: 10px; 
      font-size: 13px; 
      cursor: pointer; 
      color: #7289da;
      display: inline-block;
    }
    @keyframes fadeIn {
      0% { opacity: 0; transform: translateY(-10px); }
      100% { opacity: 1; transform: translateY(0); }
    }

    /*************************************************************
     *                   TOS OVERLAY
     *************************************************************/
    .tos-overlay {
      position: absolute; 
      top: 0; 
      left: 0; 
      right: 0; 
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.8);
      display: none; 
      justify-content: center; 
      align-items: center;
      z-index: 9999;
    }
    .tos-box {
      background-color: #2f3136; 
      padding: 20px; 
      border-radius: 5px;
      width: 350px; 
      text-align: center; 
      color: #fff;
      animation: fadeIn 0.5s ease forwards;
    }
    .tos-box p {
      margin-bottom: 15px; 
      font-size: 14px; 
      line-height: 1.4;
    }
    .tos-box label {
      display: block; 
      margin-bottom: 10px; 
      cursor: pointer; 
      font-size: 14px;
    }
    .tos-box input[type="checkbox"] {
      margin-right: 5px;
    }
    .tos-box button {
      background-color: #7289da; 
      border: none;
      border-radius: 5px; 
      color: #fff; 
      cursor: pointer;
      padding: 8px 15px; 
      margin-top: 5px; 
      font-size: 14px;
      transition: background-color 0.2s;
    }
    .tos-box button:hover {
      background-color: #5b6eae;
    }

    /*************************************************************
     *                   BAN OVERLAY
     *************************************************************/
    .ban-overlay {
      position: absolute; 
      top: 0; 
      left: 0; 
      right: 0; 
      bottom: 0;
      display: none; 
      background-color: rgba(0,0,0,0.9);
      z-index: 9999; 
      color: #fff; 
      text-align: center; 
      padding-top: 100px;
    }
    .ban-overlay h1 {
      font-size: 24px; 
      margin-bottom: 10px; 
      color: #f04747;
    }
  </style>
</head>
<body>
  <!-- BAN OVERLAY -->
  <div class="ban-overlay" id="banOverlay">
    <h1>You have been banned!</h1>
    <p id="banReason"></p>
  </div>

  <!-- TOS OVERLAY -->
  <div class="tos-overlay" id="tosOverlay">
    <div class="tos-box">
      <h2>Terms of Service</h2>
      <p>
        We here at Coven are a messaging hub for students, letting them chat and help each other. However, we do <strong>NOT</strong> condone cheating under any circumstances. The AI we provide is for legitimate help and study, not for academic dishonesty. If you use this AI for cheating, you may be permanently banned. 
        <br /><br />
        This server (like "Cheats" or "Work Help") is for discussing game cheats (e.g. Blooket, Gimkit) or for genuinely collaborating on schoolwork. Cheating in official assignments is strictly prohibited.
      </p>
      <label>
        <input type="checkbox" id="tosAgreeCheckbox" />
        I understand and agree to follow these terms.
      </label>
      <button onclick="acceptTOS()">Continue</button>
    </div>
  </div>

  <!-- AUTH OVERLAY -->
  <div class="auth-overlay" id="authOverlay">
    <div class="auth-box">
      <h3 id="authTitle">Sign Up</h3>
      <input type="text" id="authUsername" placeholder="Username" />
      <input type="text" id="authDiscriminator" placeholder="Discriminator (4 digits)" />
      <input type="password" id="authPassword" placeholder="Password" />
      <button onclick="authSubmit()">Sign Up</button>
      <div class="auth-error" id="authError"></div>
      <span class="toggle-link" id="toggleLink">Already have an account? Login</span>
    </div>
  </div>

  <!-- MAIN LAYOUT -->
  <div class="container">
    <!-- SERVERS BAR -->
    <div class="servers-bar">
      <div class="server-icon" onclick="switchServer('cheats')">C</div>
      <div class="server-icon" onclick="switchServer('workhelp')">W</div> <!-- Renamed answers -> workhelp -->
      <div class="server-icon" onclick="switchServer('games')">Gm</div>    <!-- New server: Games -->
      <div class="server-icon" id="adminServerIcon" onclick="switchServer('admin')">Ad</div>
      <div class="server-icon" onclick="switchServer('global')">Gl</div>
    </div>

    <!-- SIDEBAR (Friends) -->
    <div class="sidebar">
      <h2>Friends</h2>
      <div class="section-title">ONLINE</div>
      <div id="friendsOnline"></div>
      <div class="section-title">OFFLINE</div>
      <div id="friendsOffline"></div>
    </div>

    <!-- CHAT AREA -->
    <div class="chat-area">
      <div class="chat-header">
        <h2 id="chatHeader">Server: global</h2>
        <button id="backBtn" style="display:none;" onclick="backToServers()">Back</button>
      </div>
      <div class="banner" id="bannerArea">
        <span id="normalBannerText">
          To ask the AI anything, type "Hey Aegis" then your query!
        </span>
        <br/>
        <!-- Commands (Admin only) -->
        <small id="adminCommands" style="display:none;">
          Commands (Admin only): /mute user#disc minutes | /suspend user#disc minutes | /ban user#disc minutes-or-perm reason... | /admin user#disc
        </small>
      </div>
      <div class="messages" id="messages"></div>
      <div class="input-area">
        <textarea id="userInput" placeholder="Type your message..."></textarea>
        <button onclick="sendMessage()">Send</button>
      </div>
    </div>

    <!-- RIGHT BAR (Profile, DMs, Requests) -->
    <div class="right-bar">
      <div class="profile-section">
        <div class="banner" id="userBanner"
             style="background-image:url('https://via.placeholder.com/728x90.png?text=Banner');">
        </div>
        <img id="userPFP" src="https://via.placeholder.com/80" alt="PFP" />
        <div class="username" id="usernameDisplay">Username#0000</div>
        <div class="bio" id="bioDisplay">Your cool bio goes here</div>
        <button class="edit-profile" onclick="editProfile()">Edit Profile</button>
      </div>

      <div class="dm-section">
        <h3>Direct Messages</h3>
        <div id="dmList"></div>
      </div>

      <div class="friend-request-ui">
        <h3>Send Friend Request</h3>
        <input type="text" id="friendUsername" placeholder="username#0000" />
        <button onclick="sendFriendRequest()">Send Request</button>
        <div class="friend-requests-list" id="requestList"></div>
      </div>
    </div>
  </div>

  <script>
    /**********************************************************
     *                 FIREBASE CONFIG & INIT
     **********************************************************/
    var firebaseConfig = {
      apiKey: "AIzaSyAI2IHTVnBXNi_i9LJwrd-PvLf6CtuRzlw",
      authDomain: "onlinegame-f5c20.firebaseapp.com",
      databaseURL: "https://onlinegame-f5c20-default-rtdb.firebaseio.com/",
      projectId: "onlinegame-f5c20",
      storageBucket: "onlinegame-f5c20.appspot.com",
      messagingSenderId: "1032630503376",
      appId: "1:1032630503376:web:f122fa5ac5a142157ddbd5"
    };
    firebase.initializeApp(firebaseConfig);

    // Refs
    var db = firebase.database();
    var usersRef     = db.ref("users");
    var friendReqRef = db.ref("friendRequests");
    var serversRef   = db.ref("servers");
    var dmsRef       = db.ref("dms");
    var bansRef      = db.ref("bans");
    var mutesRef     = db.ref("mutes");
    var suspRef      = db.ref("suspensions");

    // Global state
    var currentUser     = null; 
    var currentMode     = "server"; // or 'dm:someId'
    var currentServer   = "global";
    var isLoginMode     = false; 

    // Auth UI
    var authOverlay     = document.getElementById("authOverlay");
    var authTitle       = document.getElementById("authTitle");
    var authError       = document.getElementById("authError");
    var authUserEl      = document.getElementById("authUsername");
    var authDiscEl      = document.getElementById("authDiscriminator");
    var authPassEl      = document.getElementById("authPassword");
    var toggleLink      = document.getElementById("toggleLink");

    // TOS
    var tosOverlay      = document.getElementById("tosOverlay");
    var tosAgreeCheckbox= document.getElementById("tosAgreeCheckbox");

    // Chat UI
    var chatHeader      = document.getElementById("chatHeader");
    var backBtn         = document.getElementById("backBtn");
    var messagesDiv     = document.getElementById("messages");
    var userInputEl     = document.getElementById("userInput");
    var bannerArea      = document.getElementById("bannerArea");
    var adminCommandsEl = document.getElementById("adminCommands");

    // Profile UI
    var userBanner      = document.getElementById("userBanner");
    var userPFP         = document.getElementById("userPFP");
    var userNameDisp    = document.getElementById("usernameDisplay");
    var bioDisp         = document.getElementById("bioDisplay");

    // Friends & DMs
    var friendsOnline   = document.getElementById("friendsOnline");
    var friendsOffline  = document.getElementById("friendsOffline");
    var requestList     = document.getElementById("requestList");
    var dmList          = document.getElementById("dmList");

    // Admin server icon
    var adminServerIcon = document.getElementById("adminServerIcon");

    // Ban overlay
    var banOverlay      = document.getElementById("banOverlay");
    var banReasonEl     = document.getElementById("banReason");

    // Banned words
    var bannedWords = ["shit","fuck","damn","motherfucker"];

    /**********************************************************
     *         COOKIE-BASED AUTH STORAGE (Optional)
     **********************************************************/
    // Save the user's credentials to a cookie
    function saveCredentialsToCookie(username, disc, passHash) {
      document.cookie = `cov_usr=${encodeURIComponent(username)}#${encodeURIComponent(disc)}; path=/`;
      document.cookie = `cov_ph=${encodeURIComponent(passHash)}; path=/`;
    }
    // Read them back
    function readCredentialsFromCookie() {
      let cookies = document.cookie.split(";").map(c => c.trim());
      let userTag = null;
      let passH   = null;
      cookies.forEach(cookie => {
        if (cookie.startsWith("cov_usr=")) {
          userTag = decodeURIComponent(cookie.substring("cov_usr=".length));
        } 
        else if (cookie.startsWith("cov_ph=")) {
          passH = decodeURIComponent(cookie.substring("cov_ph=".length));
        }
      });
      return { userTag, passH };
    }

    // Attempt auto-login if cookies exist
    window.onload = function() {
      let {userTag, passH} = readCredentialsFromCookie();
      if (userTag && passH) {
        // userTag => "username#disc"
        let parts = userTag.split("#");
        if (parts.length === 2) {
          attemptCookieLogin(parts[0], parts[1], passH);
          return;
        }
      }
      // Otherwise show normal overlay
      authOverlay.style.display = "flex";
    };

    function attemptCookieLogin(uname, disc, passHash) {
      // Try to find the user in DB
      usersRef.once("value", snap => {
        let all = snap.val() || {};
        let foundUser = null;
        Object.keys(all).forEach(uid => {
          let u = all[uid];
          if (u.username === uname && u.discriminator === disc && u.passHash === passHash) {
            foundUser = { uid, ...u };
          }
        });
        if (!foundUser) {
          // Invalid cookie => clear cookies
          document.cookie = "cov_usr=; path=/; max-age=0";
          document.cookie = "cov_ph=; path=/; max-age=0";
          authOverlay.style.display = "flex";
        } else {
          currentUser = foundUser;
          authOverlay.style.display = "none";
          initAfterAuth();
        }
      });
    }

    /**********************************************************
     *                SIMPLE HASH FUNCTION (SHA-256)
     **********************************************************/
    async function sha256(str) {
      const buf = new TextEncoder().encode(str);
      const hashBuffer = await crypto.subtle.digest("SHA-256", buf);
      const hashArray = Array.from(new Uint8Array(hashBuffer));
      const hashHex = hashArray.map(b => b.toString(16).padStart(2, "0")).join("");
      return hashHex;
    }

    /**********************************************************
     *          AUTH FLOW (NO EMAIL) + TOS
     **********************************************************/
    toggleLink.onclick = function() {
      isLoginMode = !isLoginMode;
      if (isLoginMode) {
        authTitle.textContent = "Login";
        toggleLink.textContent = "No account? Sign up";
      } else {
        authTitle.textContent = "Sign Up";
        toggleLink.textContent = "Already have an account? Login";
      }
      authError.textContent = "";
    };

    async function authSubmit() {
      let uname = authUserEl.value.trim();
      let disc  = authDiscEl.value.trim();
      let pass  = authPassEl.value.trim();

      if (!uname || !disc || !pass) {
        authError.textContent = "All fields required!";
        return;
      }
      if (disc.length !== 4 || isNaN(+disc)) {
        authError.textContent = "Discriminator must be 4 digits!";
        return;
      }
      let passHash = await sha256(pass);

      if (!isLoginMode) {
        // SIGN UP => show TOS first
        showTOSOverlay(uname, disc, passHash);
      } else {
        // LOGIN => check in DB
        usersRef.once("value", snap => {
          let all = snap.val() || {};
          let foundUser = null;
          Object.keys(all).forEach(uid => {
            let u = all[uid];
            if (u.username === uname && u.discriminator === disc) {
              foundUser = { uid, ...u };
            }
          });
          if (!foundUser) {
            authError.textContent = "User not found!";
            return;
          }
          if (foundUser.passHash !== passHash) {
            authError.textContent = "Incorrect password!";
            return;
          }
          currentUser = foundUser;
          // If root user
          if (uname === "anarxyfr" && disc === "0000") {
            currentUser.admin = true;
            usersRef.child(foundUser.uid).update({ admin: true });
          }
          // Save cookie
          saveCredentialsToCookie(uname, disc, passHash);
          authOverlay.style.display = "none";
          initAfterAuth();
        });
      }
    }

    function showTOSOverlay(uname, disc, passHash) {
      authOverlay.style.display = "none";
      tosOverlay.style.display  = "flex";

      // We'll store these temporarily
      window._pendingSignUp = { uname, disc, passHash };
    }

    function acceptTOS() {
      if (!tosAgreeCheckbox.checked) {
        alert("You must agree to the TOS to continue!");
        return;
      }
      tosOverlay.style.display = "none";
      let { uname, disc, passHash } = window._pendingSignUp;
      window._pendingSignUp = null;

      // Now create user in DB
      usersRef.once("value", snap => {
        let all = snap.val() || {};
        let found = false;
        Object.keys(all).forEach(uid => {
          let u = all[uid];
          if (u.username === uname && u.discriminator === disc) {
            found = true;
          }
        });
        if (found) {
          // If for some reason it got created, revert
          authError.textContent = "User already exists!";
          authOverlay.style.display = "flex";
          return;
        }
        let newUid = "user-" + Math.floor(Math.random() * 1000000000);
        currentUser = {
          uid: newUid,
          username: uname,
          discriminator: disc,
          passHash,
          pfp: "https://via.placeholder.com/80",
          banner: "https://via.placeholder.com/728x90.png?text=Banner",
          bio: "Hello, I'm new here!",
          admin: false,
          friends: {}
        };
        // If it's the special root user
        if (uname === "anarxyfr" && disc === "0000") {
          currentUser.admin = true;
        }
        usersRef.child(newUid).set(currentUser);
        // Save cookie
        saveCredentialsToCookie(uname, disc, passHash);
        initAfterAuth();
      });
    }

    /**********************************************************
     *         INITIALIZE AFTER AUTH
     **********************************************************/
    function initAfterAuth() {
      // Hide overlays
      authOverlay.style.display = "none";
      tosOverlay.style.display  = "none";

      // Listen for changes in the user record
      usersRef.child(currentUser.uid).on("value", snap => {
        if (!snap.exists()) return;
        currentUser = { ...currentUser, ...snap.val() };
        updateProfileUI();
        enforceAdminUI();
      });

      // Listen for server messages
      serversRef.on("child_added", sSnap => {
        let serverId = sSnap.key;
        serversRef.child(serverId).child("messages").on("child_added", msgSnap => {
          if (currentMode === "server" && currentServer === serverId) {
            addServerMessage(msgSnap.val());
          }
        });
      });

      // Listen for friend requests
      friendReqRef.on("value", () => {
        renderFriendRequests();
      });

      // Listen for user changes (friends)
      usersRef.on("value", () => {
        renderFriends();
      });

      // Listen for DMs
      dmsRef.on("value", () => {
        renderDMs();
      });

      // Check ban status
      checkBanStatus((banned, info) => {
        if (banned) {
          showBanOverlay(info.reason, info.expiration);
        } else {
          switchServer("global");
          updateProfileUI();
          enforceAdminUI();
        }
      });
    }

    /**********************************************************
     *       BAN OVERLAY & BAN CHECK
     **********************************************************/
    function checkBanStatus(callback) {
      bansRef.child(currentUser.uid).once("value", snap => {
        if (!snap.exists()) {
          callback(false, null);
          return;
        }
        let data = snap.val();
        // if "perm", always banned
        if (data.expiration === "perm") {
          callback(true, data);
        } else {
          // check if time expired
          let now = Date.now();
          if (now < data.expiration) {
            callback(true, data);
          } else {
            // ban expired
            bansRef.child(currentUser.uid).remove();
            callback(false, null);
          }
        }
      });
    }

    function showBanOverlay(reason, expiration) {
      banOverlay.style.display = "block";
      let detail = `Reason: ${reason} | `;
      if (expiration === "perm") {
        detail += "Permanent ban.";
      } else {
        let minsLeft = Math.floor((expiration - Date.now()) / 60000);
        detail += `Expires in ~${minsLeft} minute(s).`;
      }
      banReasonEl.textContent = detail;
    }

    /**********************************************************
     *     SWITCH SERVER (with suspension check)
     **********************************************************/
    function switchServer(serverId) {
      if (!currentUser) return;
      // If serverId === 'admin', check if admin
      if (serverId === "admin" && !isAdminOrRoot()) {
        alert("You are not authorized for the Admin server.");
        return;
      }

      // If the user tries a server not global/admin/games/workhelp/cheats...
      // We'll just allow it if it's in DB, but let's keep it minimal.

      // Check suspension
      if (serverId !== "global" && serverId !== "admin") {
        checkSuspension(res => {
          if (res) {
            alert("You are suspended! You can only access GLOBAL + DMs.");
          } else {
            actuallySwitchServer(serverId);
          }
        });
      } else {
        actuallySwitchServer(serverId);
      }
    }

    function checkSuspension(callback) {
      suspRef.child(currentUser.uid).once("value", snap => {
        if (!snap.exists()) {
          callback(false);
          return;
        }
        let data = snap.val();
        let now = Date.now();
        if (now < data.expires) {
          callback(true);
        } else {
          // suspension expired
          suspRef.child(currentUser.uid).remove();
          callback(false);
        }
      });
    }

    function actuallySwitchServer(serverId) {
      currentMode   = "server";
      currentServer = serverId;
      messagesDiv.innerHTML = "";
      chatHeader.textContent = "Server: " + serverId;
      backBtn.style.display  = "none";

      // load existing messages
      serversRef.child(serverId).child("messages").once("value", snap => {
        let msgs = snap.val() || {};
        Object.keys(msgs).forEach(k => {
          addServerMessage(msgs[k]);
        });
        messagesDiv.scrollTop = messagesDiv.scrollHeight;
      });
    }

    /**********************************************************
     *         BACK TO GLOBAL
     **********************************************************/
    function backToServers() {
      switchServer("global");
    }

    /**********************************************************
     *        SENDING MESSAGES (check Mute, commands)
     **********************************************************/
    function sendMessage() {
      if (!currentUser) return;
      let text = userInputEl.value.trim();
      if (!text) return;
      userInputEl.value = "";

      // Check Mute
      checkMute(currentUser.uid, (muted, timeLeft) => {
        if (muted) {
          alert(`You are muted! Time left: ~${timeLeft} minute(s).`);
          return;
        }
        // If command
        if (text.startsWith("/")) {
          if (isAdminOrRoot()) {
            parseAdminCommand(text);
          }
          return;
        }

        // Send normal message
        if (currentMode.startsWith("dm:")) {
          let dmId = currentMode.split(":")[1];
          let msgObj = {
            user: currentUser.username + "#" + currentUser.discriminator,
            pfp: currentUser.pfp,
            text
          };
          dmsRef.child(dmId).child("messages").push(msgObj);

          // AI if "Hey Aegis"
          if (text.toLowerCase().startsWith("hey aegis")) {
            getAIDMResponse(text, dmId);
          }
        } else {
          let msgObj = {
            user: currentUser.username + "#" + currentUser.discriminator,
            pfp: currentUser.pfp,
            text
          };
          serversRef.child(currentServer).child("messages").push(msgObj);

          // AI if "Hey Aegis"
          if (text.toLowerCase().startsWith("hey aegis")) {
            getAIServerResponse(text, currentServer);
          }
        }
      });
    }

    function checkMute(uid, callback) {
      mutesRef.child(uid).once("value", snap => {
        if (!snap.exists()) {
          callback(false, 0);
          return;
        }
        let data = snap.val();
        let now  = Date.now();
        if (now < data.expires) {
          let minsLeft = Math.ceil((data.expires - now) / 60000);
          callback(true, minsLeft);
        } else {
          // mute expired
          mutesRef.child(uid).remove();
          callback(false, 0);
        }
      });
    }

// Object to store user chat history locally
let userChatHistory = {};

async function getAIServerResponse(query, serverId) {
    if (!currentUser) {
        console.error("Error: currentUser is undefined. AI cannot process request.");
        return;
    }

    let userId = currentUser.username + "#" + currentUser.discriminator;

    // Ensure chat history exists for this user
    if (!userChatHistory[userId]) {
        userChatHistory[userId] = [];
    }

    // Retrieve the last 10 messages from Firebase to maintain continuity
    firebase.database().ref("servers/" + serverId + "/messages")
    .limitToLast(10)  // Fetch more past messages for better context
    .once("value", async (snapshot) => {
        let messages = [];

        snapshot.forEach((child) => {
            let msg = child.val();
            if (msg.user === "Aegis") {
                messages.push({ role: "assistant", content: msg.text });
            } else {
                messages.push({ role: "user", content: msg.text });
            }
        });

        // Store this session history locally
        userChatHistory[userId] = messages;

        // Add the latest query to memory
        userChatHistory[userId].push({ role: "user", content: query });

        // Call OpenAI API
        try {
            let response = await fetch("https://api.openai.com/v1/chat/completions", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": `Bearer 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`
                },
                body: JSON.stringify({
                    model: "gpt-3.5-turbo",
                    messages: [
                        { role: "system", content: "You are Aegis, a helpful assistant in a chatroom." },
                        ...userChatHistory[userId]  // Attach conversation history
                    ],
                    max_tokens: 200
                })
            });

            let data = await response.json();
            if (response.ok) {
                let botResponse = data.choices[0].message.content;
                
                // Add AI's response to history
                userChatHistory[userId].push({ role: "assistant", content: botResponse });

                // Store message in Firebase
                let botMessage = {
                    user: "Aegis",
                    pfp: "https://imgs.search.brave.com/JI8GwqG3WTlkFjfNXgsImz3e3hBop6K4FNY4wQsgFTE/rs:fit:860:0:0:0/g:ce/aHR0cHM6Ly9pbWFn/ZXMuc3F1YXJlc3Bh/Y2UtY2RuLmNvbS9j/b250ZW50L3YxLzVl/NTdhMzhmZjI1NDkw/NGVlMDk5MTk1Yy8x/NjYzMTM2OTY3NTE3/LTFJUDBRR1ZMSk5J/SE9LUzlPWTNNL0Fl/Z2lzLmpwZw",
                    text: botResponse
                };
                firebase.database().ref("servers/" + serverId + "/messages").push(botMessage);
            } else {
                console.error("OpenAI API Error:", data);
            }
        } catch (error) {
            console.error("Error calling OpenAI API:", error);
        }
    });
}


    /**********************************************************
     *             RENDERING MESSAGES (LINK DETECTION)
     **********************************************************/
    function addServerMessage(msg) {
      if (currentMode !== "server" || currentServer === "") return;
      addMessageToDOM(msg);
    }
    function addMessageToDOM(msg) {
      // Censor if not root
      let finalText = censorText(msg.text, msg.user);

      // Link detection: convert https:// or http:// references into clickable
      finalText = linkify(finalText);

      let msgDiv = document.createElement("div");
      msgDiv.classList.add("message");

      if (msg.user === "Aegis") {
        msgDiv.classList.add("bot");
      } else {
        msgDiv.classList.add("user");
        // If user is anarxyfr#0000 => purple glow
        if (msg.user.toLowerCase() === "anarxyfr#0000") {
          msgDiv.classList.add("root-glow");
        }
      }

      let pfpImg = document.createElement("img");
      pfpImg.classList.add("pfp");
      pfpImg.src = msg.pfp || "https://via.placeholder.com/80";

      let contentDiv = document.createElement("div");
      contentDiv.classList.add("message-content");

      let authorSpan = document.createElement("span");
      authorSpan.classList.add("author");
      authorSpan.textContent = msg.user + ": ";

      // We'll render HTML for link detection, so let's do an innerHTML approach
      let textSpan = document.createElement("span");
      textSpan.innerHTML = finalText;

      contentDiv.appendChild(authorSpan);
      contentDiv.appendChild(textSpan);

      msgDiv.appendChild(pfpImg);
      msgDiv.appendChild(contentDiv);

      messagesDiv.appendChild(msgDiv);
      messagesDiv.scrollTop = messagesDiv.scrollHeight;
    }

    function linkify(text) {
      // Basic pattern for http/https
      let urlRegex = /(https?:\/\/[^\s]+)/gi;
      return text.replace(urlRegex, function(url) {
        return `<a href="${url}" target="_blank" style="color:#7289da;">${url}</a>`;
      });
    }

    function censorText(message, userTag) {
      // If user is root => no censor
      if (userTag.toLowerCase() === "anarxyfr#0000") return message;
      let result = message;
      bannedWords.forEach(word => {
        let regex = new RegExp(word, "gi");
        result = result.replace(regex, "****");
      });
      return result;
    }

    /**********************************************************
     *        ADMIN COMMANDS
     **********************************************************/
    function parseAdminCommand(cmdLine) {
      let parts = cmdLine.split(" ");
      let cmd   = parts[0];
      switch (cmd) {
        case "/mute":
          if (parts.length < 3) return;
          let target1  = parts[1];
          let minutes1 = parseInt(parts[2]) || 1;
          doMute(target1, minutes1);
          break;
        case "/suspend":
          if (parts.length < 3) return;
          let target2  = parts[1];
          let minutes2 = parseInt(parts[2]) || 1;
          doSuspend(target2, minutes2);
          break;
        case "/ban":
          if (parts.length < 3) return;
          let target3  = parts[1];
          let dur      = parts[2];
          let reason   = parts.slice(3).join(" ") || "No reason";
          doBan(target3, dur, reason);
          break;
        case "/admin":
          if (parts.length < 2) return;
          let target4 = parts[1];
          makeAdmin(target4);
          break;
        default:
          // unknown command
          break;
      }
    }

    function isAdminOrRoot() {
      if (!currentUser) return false;
      if (currentUser.username === "anarxyfr" && currentUser.discriminator === "0000") return true;
      return currentUser.admin === true;
    }

    function doMute(userTag, mins) {
      findUserByTag(userTag, uid => {
        if (!uid) return;
        let expires = Date.now() + (mins * 60000);
        mutesRef.child(uid).set({ expires });
      });
    }

    function doSuspend(userTag, mins) {
      findUserByTag(userTag, uid => {
        if (!uid) return;
        let expires = Date.now() + (mins * 60000);
        suspRef.child(uid).set({ expires });
      });
    }

    function doBan(userTag, dur, reason) {
      findUserByTag(userTag, uid => {
        if (!uid) return;
        let expiration;
        if (dur === "perm") {
          expiration = "perm";
        } else {
          let mins = parseInt(dur) || 999999;
          expiration = Date.now() + (mins * 60000);
        }
        bansRef.child(uid).set({ reason, expiration });
      });
    }

    function makeAdmin(userTag) {
      findUserByTag(userTag, uid => {
        if (!uid) return;
        usersRef.child(uid).update({ admin: true });
      });
    }

    function findUserByTag(userTag, callback) {
      // userTag => "username#disc"
      usersRef.once("value", snap => {
        let all = snap.val() || {};
        let foundUid = null;
        Object.keys(all).forEach(u => {
          let rec = all[u];
          if ((rec.username + "#" + rec.discriminator).toLowerCase() === userTag.toLowerCase()) {
            foundUid = u;
          }
        });
        callback(foundUid);
      });
    }

    /**********************************************************
     *        ENFORCE ADMIN UI (hide/show admin server, commands text)
     **********************************************************/
    function enforceAdminUI() {
      if (!isAdminOrRoot()) {
        adminServerIcon.classList.add("hidden");
        adminCommandsEl.style.display = "none";
      } else {
        adminServerIcon.classList.remove("hidden");
        adminCommandsEl.style.display = "inline";
      }
    }

    /**********************************************************
     *        FRIEND SYSTEM
     **********************************************************/
    function renderFriends() {
      if (!currentUser) return;
      friendsOnline.innerHTML  = "";
      friendsOffline.innerHTML = "";

      usersRef.once("value", snap => {
        let all = snap.val() || {};
        Object.keys(all).forEach(uid => {
          if (uid === currentUser.uid) return;
          let u = all[uid];
          let isFriend = u.friends && u.friends[currentUser.uid];
          let item = document.createElement("div");
          item.classList.add("sidebar-item");
          item.textContent = u.username + "#" + u.discriminator;

          item.onclick = function() {
            // open DM if friend
            if (!isFriend) return;
            createOrOpenDM(uid, u);
          };

          if (isFriend) {
            friendsOnline.appendChild(item);
          } else {
            friendsOffline.appendChild(item);
          }
        });
      });
    }

    function sendFriendRequest() {
      if (!currentUser) return;
      let val = document.getElementById("friendUsername").value.trim();
      if (!val) return;
      let parts = val.split("#");
      if (parts.length !== 2) return;

      let targetName = parts[0];
      let targetDisc = parts[1];

      usersRef.once("value", snap => {
        let allU = snap.val() || {};
        let foundUid = null;
        Object.keys(allU).forEach(uid => {
          let rec = allU[uid];
          if (rec.username === targetName && rec.discriminator === targetDisc) {
            foundUid = uid;
          }
        });
        if (!foundUid || foundUid === currentUser.uid) return;
        let reqKey = friendReqRef.push().key;
        friendReqRef.child(reqKey).set({
          from: currentUser.uid,
          fromUsername: currentUser.username + "#" + currentUser.discriminator,
          to: foundUid,
          status: "pending"
        });
      });
    }

    function renderFriendRequests() {
      requestList.innerHTML = "";
      friendReqRef.once("value", snap => {
        let all = snap.val() || {};
        Object.keys(all).forEach(rid => {
          let r = all[rid];
          if (r.to === currentUser.uid && r.status === "pending") {
            let div = document.createElement("div");
            div.classList.add("request-item");
            div.textContent = r.fromUsername + " sent a friend request.";

            let acceptBtn = document.createElement("button");
            acceptBtn.textContent = "Accept";
            acceptBtn.onclick = () => acceptRequest(r.from, rid);

            let declineBtn = document.createElement("button");
            declineBtn.textContent = "Decline";
            declineBtn.onclick = () => declineRequest(rid);

            div.appendChild(acceptBtn);
            div.appendChild(declineBtn);
            requestList.appendChild(div);
          }
        });
      });
    }

    function acceptRequest(fromUid, rid) {
      usersRef.child(currentUser.uid).child("friends").child(fromUid).set(true);
      usersRef.child(fromUid).child("friends").child(currentUser.uid).set(true);
      friendReqRef.child(rid).remove();
    }
    function declineRequest(rid) {
      friendReqRef.child(rid).remove();
    }

    /**********************************************************
     *              DIRECT MESSAGES
     **********************************************************/
    function renderDMs() {
      if (!currentUser) return;
      dmList.innerHTML = "";
      dmsRef.once("value", snap => {
        let all = snap.val() || {};
        Object.keys(all).forEach(dmId => {
          let dm = all[dmId];
          if (dm.participants && dm.participants[currentUser.uid]) {
            let item = document.createElement("div");
            item.classList.add("dm-item");
            item.textContent = dm.dmName || dmId;
            item.onclick = () => loadDM(dmId, dm.dmName || dmId);
            dmList.appendChild(item);
          }
        });
      });
    }

    function createOrOpenDM(otherUid, otherObj) {
      let dmId = (currentUser.uid < otherUid)
        ? currentUser.uid + "-" + otherUid
        : otherUid + "-" + currentUser.uid;

      dmsRef.child(dmId).once("value", snap => {
        if (!snap.exists()) {
          let parts = {};
          parts[currentUser.uid] = true;
          parts[otherUid]        = true;
          let name = currentUser.username + "#" + currentUser.discriminator +
                     " & " + otherObj.username + "#" + otherObj.discriminator;
          dmsRef.child(dmId).set({
            dmName: name,
            participants: parts
          });
        }
        loadDM(dmId, otherObj.username + "#" + otherObj.discriminator);
      });
    }

    function loadDM(dmId, displayName) {
      currentMode = "dm:" + dmId;
      chatHeader.textContent = "DM: " + displayName;
      backBtn.style.display  = "inline-block";
      messagesDiv.innerHTML  = "";

      // Listen for DM messages
      dmsRef.child(dmId).child("messages").off();
      dmsRef.child(dmId).child("messages").on("child_added", snap => {
        addDMMessage(snap.val());
      });
    }

    function addDMMessage(msg) {
      if (!currentMode.startsWith("dm:")) return;
      let finalText = censorText(msg.text, msg.user);
      finalText = linkify(finalText);

      let msgDiv = document.createElement("div");
      msgDiv.classList.add("message");
      if (msg.user === "Aegis") {
        msgDiv.classList.add("bot");
      } else {
        msgDiv.classList.add("user");
        if (msg.user.toLowerCase() === "anarxyfr#0000") {
          msgDiv.classList.add("root-glow");
        }
      }

      let pfpImg = document.createElement("img");
      pfpImg.classList.add("pfp");
      pfpImg.src = msg.pfp || "https://via.placeholder.com/80";

      let contentDiv = document.createElement("div");
      contentDiv.classList.add("message-content");

      let authorSpan = document.createElement("span");
      authorSpan.classList.add("author");
      authorSpan.textContent = msg.user + ": ";

      let textSpan = document.createElement("span");
      textSpan.innerHTML = finalText;

      contentDiv.appendChild(authorSpan);
      contentDiv.appendChild(textSpan);
      msgDiv.appendChild(pfpImg);
      msgDiv.appendChild(contentDiv);
      messagesDiv.appendChild(msgDiv);
      messagesDiv.scrollTop = messagesDiv.scrollHeight;
    }

    /**********************************************************
     *         PROFILE EDIT
     **********************************************************/
    function editProfile() {
      if (!currentUser) return;
      let newUser   = prompt("Username:", currentUser.username);
      if (newUser === null) return;
      let newBanner = prompt("Banner URL:", currentUser.banner);
      if (newBanner === null) return;
      let newPFP    = prompt("PFP URL:", currentUser.pfp);
      if (newPFP === null) return;
      let newBio    = prompt("Bio:", currentUser.bio);
      if (newBio === null) return;

      currentUser.username = newUser;
      currentUser.banner   = newBanner;
      currentUser.pfp      = newPFP;
      currentUser.bio      = newBio;

      usersRef.child(currentUser.uid).update({
        username: newUser,
        banner: newBanner,
        pfp: newPFP,
        bio: newBio
      });
    }

    function updateProfileUI() {
      if (!currentUser) return;
      userBanner.style.backgroundImage = `url('${currentUser.banner}')`;
      userPFP.src = currentUser.pfp;
      userNameDisp.textContent =
        currentUser.username + "#" + currentUser.discriminator;
      bioDisp.textContent = currentUser.bio;
    }
  </script>
</body>
</html>
