<?php
require_once 'includes/config.php';
if (!isset($_SESSION['user_id'])) { header('Location: ' . SITE_URL . '/login'); exit; }

$me      = (int)$_SESSION['user_id'];
$siteUrl = defined('SITE_URL') ? SITE_URL : '';
$apiUrl  = $siteUrl . '/api/chat.php';

require_once 'includes/header.php';
renderHeader('Chat', 'chat');
?>

<style>
/* ══════════════════════════════════════════════════════
   CHAT PAGE — scoped styles (no conflicts with style.css)
   modal-overlay / .modal handled by style.css globally
   ══════════════════════════════════════════════════════ */

/* Layout */
.chat-wrap {
  display: flex;
  height: calc(100vh - 64px);
  overflow: hidden;
  background: var(--bg-primary);
}

/* ── Sidebar ── */
.chat-sidebar {
  width: 300px; min-width: 300px;
  display: flex; flex-direction: column;
  border-right: 1px solid var(--border);
  background: var(--bg-secondary);
  transition: none;
}
.chat-sidebar-header {
  padding: 16px 14px 12px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center;
  justify-content: space-between; gap: 8px;
  flex-shrink: 0;
}
.chat-sidebar-header h2 { font-size: 16px; font-weight: 700; color: var(--text-primary); margin: 0; }
.chat-sidebar-btns { display: flex; gap: 6px; }
.cs-btn {
  background: rgba(99,102,241,.12);
  border: 1px solid rgba(99,102,241,.3);
  color: #a5b4fc; border-radius: 8px;
  padding: 5px 10px; font-size: 12px; font-weight: 600;
  cursor: pointer; font-family: inherit; transition: background .2s;
  white-space: nowrap;
}
.cs-btn:hover { background: rgba(99,102,241,.22); }

.chat-search-wrap {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.chat-search-inp {
  width: 100%; box-sizing: border-box;
  background: var(--bg-tertiary, rgba(255,255,255,.04));
  border: 1px solid var(--border); border-radius: 9px;
  padding: 7px 11px; font-size: 13px;
  color: var(--text-primary); outline: none;
  font-family: inherit; transition: border-color .2s;
}
.chat-search-inp:focus { border-color: rgba(99,102,241,.5); }

.conv-list { overflow-y: auto; flex: 1; }
.conv-item {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 13px; cursor: pointer;
  border-bottom: 1px solid rgba(255,255,255,.025);
  transition: background .15s; position: relative;
}
.conv-item:hover { background: rgba(255,255,255,.03); }
.conv-item.active { background: rgba(99,102,241,.1); border-left: 3px solid #6366f1; padding-left: 10px; }
.conv-av {
  width: 41px; height: 41px; border-radius: 50%;
  background: linear-gradient(135deg,#6366f1,#a855f7);
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 700; color: #fff;
  flex-shrink: 0; overflow: hidden;
}
.conv-av img { width: 100%; height: 100%; object-fit: cover; }
.conv-av.is-group { border-radius: 11px; font-size: 17px; }
.conv-meta { flex: 1; min-width: 0; }
.conv-name { font-size: 13px; font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.conv-last { font-size: 11px; color: var(--text-muted,#64748b); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.conv-badge {
  background: #6366f1; color: #fff;
  font-size: 10px; font-weight: 700;
  padding: 2px 6px; border-radius: 99px; flex-shrink: 0;
}

/* ── Chat Panel ── */
.chat-panel {
  flex: 1; display: flex; flex-direction: column; overflow: hidden;
}
.chat-panel-hdr {
  padding: 13px 18px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 11px;
  flex-shrink: 0; background: var(--bg-secondary);
}
.chat-panel-name { font-size: 15px; font-weight: 700; color: var(--text-primary); }
.chat-panel-sub  { font-size: 12px; color: var(--text-muted,#64748b); margin-top: 1px; }

.back-btn {
  display: none; align-items: center; gap: 5px;
  background: none; border: none; color: var(--text-muted,#94a3b8);
  cursor: pointer; font-size: 13px; font-weight: 600;
  font-family: inherit; padding: 4px 8px; border-radius: 8px;
  transition: background .2s;
}
.back-btn:hover { background: rgba(255,255,255,.05); }

.chat-messages {
  flex: 1; overflow-y: auto;
  padding: 18px 18px 8px;
  display: flex; flex-direction: column; gap: 3px;
}
.chat-empty-state {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  color: var(--text-muted,#64748b); text-align: center; gap: 10px;
}
.chat-empty-state .ei { font-size: 50px; }
.chat-empty-state h3 { font-size: 17px; font-weight: 700; color: var(--text-primary); margin: 0; }
.chat-empty-state p  { font-size: 13px; max-width: 260px; line-height: 1.6; margin: 0; }

/* Messages */
.msg-row { display: flex; align-items: flex-end; gap: 7px; max-width: 72%; }
.msg-row.mine   { align-self: flex-end; flex-direction: row-reverse; }
.msg-row.theirs { align-self: flex-start; }
.msg-av-sm {
  width: 27px; height: 27px; border-radius: 50%;
  background: linear-gradient(135deg,#6366f1,#a855f7);
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700; color: #fff;
  flex-shrink: 0; overflow: hidden;
}
.msg-av-sm img { width: 100%; height: 100%; object-fit: cover; }
.msg-wrap { display: flex; flex-direction: column; gap: 2px; }
.msg-sender { font-size: 10px; color: var(--text-muted,#64748b); padding: 0 5px; }
.msg-bubble {
  padding: 8px 12px; border-radius: 15px;
  font-size: 14px; line-height: 1.5;
  word-break: break-word; position: relative;
}
.msg-row.mine   .msg-bubble { background: linear-gradient(135deg,#6366f1,#7c3aed); color:#fff; border-bottom-right-radius: 3px; }
.msg-row.theirs .msg-bubble { background: var(--bg-card,#1a1a2e); border: 1px solid var(--border); color: var(--text-primary); border-bottom-left-radius: 3px; }
.msg-bubble.deleted { opacity: .45; font-style: italic; }
.msg-del-btn {
  display: none; position: absolute; top: -7px; right: -7px;
  background: #ef4444; border: none; color: #fff;
  width: 17px; height: 17px; border-radius: 50%;
  font-size: 12px; cursor: pointer;
  align-items: center; justify-content: center; line-height: 1;
}
.msg-bubble:hover .msg-del-btn { display: flex; }
.msg-time { font-size: 10px; color: var(--text-muted,#64748b); padding: 0 5px; }
.msg-row.mine   .msg-time { text-align: right; }
.msg-row.theirs .msg-time { text-align: left; }

.msg-date-div {
  text-align: center; font-size: 11px;
  color: var(--text-muted,#64748b);
  margin: 10px 0 4px;
  display: flex; align-items: center; gap: 8px;
}
.msg-date-div::before,.msg-date-div::after { content:''; flex:1; height:1px; background: var(--border); }

/* Input area */
.chat-input-area {
  padding: 12px 14px; border-top: 1px solid var(--border);
  display: flex; gap: 9px; align-items: flex-end;
  background: var(--bg-secondary); flex-shrink: 0;
}
.chat-textarea {
  flex: 1; background: var(--bg-tertiary,rgba(255,255,255,.04));
  border: 1px solid var(--border); border-radius: 11px;
  padding: 9px 13px; font-size: 14px; color: var(--text-primary);
  outline: none; font-family: inherit; resize: none;
  max-height: 120px; line-height: 1.5; transition: border-color .2s;
}
.chat-textarea:focus { border-color: rgba(99,102,241,.5); }
.chat-send-btn {
  background: linear-gradient(135deg,#6366f1,#a855f7);
  border: none; color: #fff; width: 41px; height: 41px;
  border-radius: 11px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; transition: opacity .2s;
}
.chat-send-btn:hover { opacity: .85; }
.chat-send-btn:disabled { opacity: .4; cursor: not-allowed; }
.typing-row { padding: 4px 18px; font-size: 12px; color: var(--text-muted,#64748b); min-height: 20px; flex-shrink: 0; }

/* ── Modal inner content (modal-overlay/.modal from style.css) ── */
.modal-overlay { z-index: 9999 !important; }  /* above header loader */
.ch-modal-title { font-size: 15px; font-weight: 700; color: var(--text-primary); margin: 0 0 14px; }
.ch-inp {
  width: 100%; box-sizing: border-box;
  background: rgba(255,255,255,.05); border: 1px solid var(--border);
  border-radius: 9px; padding: 9px 12px; font-size: 13px;
  color: var(--text-primary); outline: none; font-family: inherit;
  margin-bottom: 9px; transition: border-color .2s;
}
.ch-inp:focus { border-color: rgba(99,102,241,.5); }
.user-pick-list { max-height: 210px; overflow-y: auto; margin-bottom: 10px; }
.user-pick-item {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 9px; border-radius: 8px; cursor: pointer;
  transition: background .15s;
}
.user-pick-item:hover { background: rgba(255,255,255,.05); }
.user-pick-item input[type=checkbox] { accent-color: #6366f1; width:14px; height:14px; cursor:pointer; flex-shrink:0; }
.user-pick-av {
  width: 31px; height: 31px; border-radius: 50%;
  background: linear-gradient(135deg,#6366f1,#a855f7);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: #fff; overflow: hidden; flex-shrink:0;
}
.user-pick-av img { width:100%;height:100%;object-fit:cover; }
.user-pick-name { font-size: 13px; font-weight: 500; color: var(--text-primary); }
.sel-count { font-size: 11px; color: #a5b4fc; margin-bottom: 3px; min-height: 16px; }
.ch-modal-actions { display: flex; gap: 9px; margin-top: 12px; }
.ch-btn-cancel {
  flex: 1; padding: 9px; border-radius: 9px;
  background: rgba(255,255,255,.06); border: 1px solid var(--border);
  color: var(--text-muted,#94a3b8); font-size: 13px; font-weight: 600;
  cursor: pointer; font-family: inherit; transition: background .2s;
}
.ch-btn-cancel:hover { background: rgba(255,255,255,.1); }
.ch-btn-ok {
  flex: 2; padding: 9px; border-radius: 9px;
  background: linear-gradient(135deg,#6366f1,#a855f7);
  border: none; color: #fff; font-size: 13px; font-weight: 700;
  cursor: pointer; font-family: inherit; transition: opacity .2s;
}
.ch-btn-ok:hover { opacity: .87; }

/* ── Scrollbars ── */
.conv-list::-webkit-scrollbar,
.chat-messages::-webkit-scrollbar,
.user-pick-list::-webkit-scrollbar { width: 3px; }
.conv-list::-webkit-scrollbar-thumb,
.chat-messages::-webkit-scrollbar-thumb,
.user-pick-list::-webkit-scrollbar-thumb { background: rgba(99,102,241,.3); border-radius: 99px; }
.conv-list::-webkit-scrollbar-track,
.chat-messages::-webkit-scrollbar-track,
.user-pick-list::-webkit-scrollbar-track { background: transparent; }

/* ── Mobile ── */
@media (max-width: 700px) {
  .chat-sidebar { width: 100%; min-width: 0; }
  .chat-sidebar.mob-hide { display: none; }
  .chat-panel.mob-hide   { display: none; }
  .chat-panel { width: 100%; }
  .back-btn   { display: flex !important; }
}
</style>

<!-- ═══════════════════════════ HTML ═══════════════════════════ -->
<div class="chat-wrap" id="chatWrap">

  <!-- Sidebar -->
  <div class="chat-sidebar" id="chatSidebar">
    <div class="chat-sidebar-header">
      <h2>💬 Chats</h2>
      <div class="chat-sidebar-btns">
        <button class="cs-btn" id="btnDirect">+ Direct</button>
        <button class="cs-btn" id="btnGroup">+ Group</button>
      </div>
    </div>
    <div class="chat-search-wrap">
      <input class="chat-search-inp" id="convSearch" type="text" placeholder="Search conversations…">
    </div>
    <div class="conv-list" id="convList">
      <div style="text-align:center;padding:30px 16px;color:var(--text-muted,#64748b);font-size:13px">Loading…</div>
    </div>
  </div>

  <!-- Panel -->
  <div class="chat-panel mob-hide" id="chatPanel">

    <div class="chat-panel-hdr" id="panelHdr" style="display:none">
      <button class="back-btn" id="backBtn">
        <svg width="15" height="15" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path d="M19 12H5M12 5l-7 7 7 7"/></svg>Back
      </button>
      <div class="conv-av" id="panelAv" style="width:35px;height:35px;font-size:13px"></div>
      <div>
        <div class="chat-panel-name" id="panelName"></div>
        <div class="chat-panel-sub"  id="panelSub"></div>
      </div>
    </div>

    <div class="chat-empty-state" id="chatEmpty">
      <div class="ei">💬</div>
      <h3>Start chatting</h3>
      <p>Pick a conversation or start a new direct message / group.</p>
    </div>

    <div class="chat-messages" id="chatMessages" style="display:none"></div>
    <div class="typing-row"   id="typingRow"    style="display:none"></div>

    <div class="chat-input-area" id="chatInputArea" style="display:none">
      <textarea class="chat-textarea" id="chatInput" placeholder="Type a message…" rows="1"></textarea>
      <button class="chat-send-btn" id="sendBtn">
        <svg width="17" height="17" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">
          <line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/>
        </svg>
      </button>
    </div>
  </div>
</div>

<!-- Modal: New Direct Chat -->
<div class="modal-overlay" id="modalDirect">
  <div class="modal">
    <p class="ch-modal-title">💬 New Direct Chat</p>
    <input class="ch-inp" id="directSearch" type="text" placeholder="Search users…">
    <div class="user-pick-list" id="directUserList">
      <div style="text-align:center;padding:18px;color:var(--text-muted,#64748b);font-size:13px">Loading…</div>
    </div>
    <div class="ch-modal-actions">
      <button class="ch-btn-cancel" id="cancelDirect">Cancel</button>
    </div>
  </div>
</div>

<!-- Modal: New Group -->
<div class="modal-overlay" id="modalGroup">
  <div class="modal">
    <p class="ch-modal-title">👥 New Group Chat</p>
    <input class="ch-inp" id="groupName"   type="text" placeholder="Group name…" maxlength="60">
    <input class="ch-inp" id="groupSearch" type="text" placeholder="Search members…">
    <div class="user-pick-list" id="groupUserList">
      <div style="text-align:center;padding:18px;color:var(--text-muted,#64748b);font-size:13px">Loading…</div>
    </div>
    <div class="sel-count" id="selCount"></div>
    <div class="ch-modal-actions">
      <button class="ch-btn-cancel" id="cancelGroup">Cancel</button>
      <button class="ch-btn-ok"     id="createGroupBtn">Create Group</button>
    </div>
  </div>
</div>

<script>
(function () {
'use strict';

/* ── Config ── */
const API  = '<?= $apiUrl ?>';
const ME   = <?= $me ?>;
const SITE = '<?= $siteUrl ?>';

/* ── State ── */
let activeConv   = null;   // { id, type, name }
let allConvs     = [];
let pollTimer    = null;
let lastMsgAt    = null;
let groupPicked  = {};     // { userId: userName }
let directTimer  = null;
let groupTimer   = null;

/* ══════════════════════════════════════
   HELPERS
   ══════════════════════════════════════ */
function esc(s) {
  return (s || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;');
}
function timeAgo(ts) {
  if (!ts) return '';
  const diff = Math.floor((Date.now() - new Date(ts.replace(' ','T'))) / 1000);
  if (diff < 60)    return 'just now';
  if (diff < 3600)  return Math.floor(diff/60)+'m ago';
  if (diff < 86400) return Math.floor(diff/3600)+'h ago';
  return new Date(ts.replace(' ','T')).toLocaleDateString();
}
function fmtTime(ts) {
  if (!ts) return '';
  return new Date(ts.replace(' ','T')).toLocaleTimeString([],{hour:'2-digit',minute:'2-digit'});
}
function dateLabel(ts) {
  if (!ts) return '';
  const d = new Date(ts.replace(' ','T')), now = new Date();
  if (d.toDateString() === now.toDateString()) return 'Today';
  const yest = new Date(now); yest.setDate(yest.getDate()-1);
  if (d.toDateString() === yest.toDateString()) return 'Yesterday';
  return d.toLocaleDateString(undefined,{weekday:'long',month:'short',day:'numeric'});
}
function avHtml(name, avatarPath, googleAv, extraCls='') {
  const init = (name||'?')[0].toUpperCase();
  const src  = avatarPath ? SITE+'/'+avatarPath : (googleAv||null);
  const img  = src ? `<img src="${src}" onerror="this.parentElement.textContent='${init}'">` : init;
  return `<div class="conv-av ${extraCls}">${img}</div>`;
}

/* ── fetch wrapper ── */
async function api(params, isGet=false) {
  try {
    const url  = isGet ? API+'?'+new URLSearchParams(params) : API;
    const opts = isGet
      ? { headers: {'X-Requested-With':'XMLHttpRequest'} }
      : { method:'POST', headers:{'X-Requested-With':'XMLHttpRequest','Content-Type':'application/x-www-form-urlencoded'},
          body: new URLSearchParams(params) };
    const r    = await fetch(url, opts);
    const text = await r.text();
    return JSON.parse(text);
  } catch(e) {
    console.error('API error', e);
    return { success: false, msg: e.message };
  }
}

/* ══════════════════════════════════════
   CONVERSATIONS LIST
   ══════════════════════════════════════ */
async function loadConvs() {
  const d = await api({action:'list_conversations'}, true);
  if (!d.success) {
    document.getElementById('convList').innerHTML =
      `<div style="text-align:center;padding:24px;color:#ef4444;font-size:12px">Could not load chats.<br>${esc(d.msg||'')}</div>`;
    return;
  }
  allConvs = d.conversations || [];
  renderConvList(allConvs);
}

function renderConvList(list) {
  const el = document.getElementById('convList');
  if (!list.length) {
    el.innerHTML = '<div style="text-align:center;padding:28px 14px;color:var(--text-muted,#64748b);font-size:13px">No conversations yet.<br>Start one above!</div>';
    return;
  }
  el.innerHTML = list.map(c => {
    const isGrp = c.type === 'group';
    const name  = isGrp ? (c.group_name||'Group') : (c.other_user?.name||'User');
    const av    = isGrp
      ? `<div class="conv-av is-group">👥</div>`
      : avHtml(name, c.other_user?.avatar, c.other_user?.google_avatar);
    const last  = c.last_body ? (c.last_body.length>36 ? c.last_body.slice(0,36)+'…' : c.last_body) : 'No messages yet';
    const badge = c.unread > 0 ? `<span class="conv-badge">${c.unread}</span>` : '';
    const act   = activeConv?.id === c.id ? ' active' : '';
    return `<div class="conv-item${act}" data-id="${c.id}">
      ${av}
      <div class="conv-meta">
        <div class="conv-name">${esc(name)}</div>
        <div class="conv-last">${esc(last)}</div>
      </div>
      ${badge}
    </div>`;
  }).join('');

  // Attach click listeners
  el.querySelectorAll('.conv-item').forEach(item => {
    item.addEventListener('click', () => openConv(parseInt(item.dataset.id)));
  });
}

document.getElementById('convSearch').addEventListener('input', function() {
  const q = this.value.toLowerCase();
  renderConvList(q ? allConvs.filter(c => {
    const n = c.type==='group' ? c.group_name : c.other_user?.name||'';
    return n.toLowerCase().includes(q);
  }) : allConvs);
});

/* ══════════════════════════════════════
   OPEN CONVERSATION
   ══════════════════════════════════════ */
async function openConv(id) {
  stopPoll();
  lastMsgAt = null;
  activeConv = allConvs.find(c => c.id === id) || { id };

  // Mobile: show panel
  document.getElementById('chatSidebar').classList.add('mob-hide');
  document.getElementById('chatPanel').classList.remove('mob-hide');

  // Highlight
  document.querySelectorAll('.conv-item').forEach(el => el.classList.remove('active'));
  const item = document.querySelector(`.conv-item[data-id="${id}"]`);
  if (item) item.classList.add('active');

  // Show UI skeleton
  document.getElementById('chatEmpty').style.display     = 'none';
  document.getElementById('panelHdr').style.display      = 'flex';
  document.getElementById('chatMessages').style.display  = 'flex';
  document.getElementById('typingRow').style.display     = 'block';
  document.getElementById('chatInputArea').style.display = 'flex';
  document.getElementById('chatMessages').innerHTML =
    '<div style="text-align:center;padding:36px;color:var(--text-muted,#64748b);font-size:13px">Loading…</div>';
  document.getElementById('chatInput').focus();

  const d = await api({action:'get_messages', conv_id:id}, true);
  if (!d.success) {
    document.getElementById('chatMessages').innerHTML =
      `<div style="text-align:center;padding:36px;color:#ef4444;font-size:13px">Failed to load messages.</div>`;
    return;
  }

  // Store full conv info
  activeConv = { id, type: d.conv.type, name: d.conv.type==='group' ? d.conv.group_name : (d.members.find(m=>m.id!=ME)?.name||'User'), members: d.members };

  // Panel header
  const isGrp = d.conv.type === 'group';
  document.getElementById('panelName').textContent = activeConv.name;
  document.getElementById('panelSub').textContent  = isGrp ? `${d.members.length} members` : 'Direct message';
  const avEl = document.getElementById('panelAv');
  if (isGrp) {
    avEl.className = 'conv-av is-group';
    avEl.innerHTML = '👥';
  } else {
    avEl.className = 'conv-av';
    const other = d.members.find(m => m.id != ME);
    const src   = other?.avatar ? SITE+'/'+other.avatar : (other?.google_avatar||null);
    avEl.innerHTML = src ? `<img src="${src}" style="width:100%;height:100%;object-fit:cover">` : (other?.name||'?')[0].toUpperCase();
  }

  renderMsgs(d.messages);
  if (d.messages.length) lastMsgAt = d.messages[d.messages.length-1].created_at;
  startPoll();
  loadConvs(); // clear unread badge
}

/* ══════════════════════════════════════
   RENDER MESSAGES
   ══════════════════════════════════════ */
function renderMsgs(msgs) {
  const box = document.getElementById('chatMessages');
  if (!msgs.length) {
    box.innerHTML = '<div style="text-align:center;padding:36px;color:var(--text-muted,#64748b);font-size:13px">No messages yet. Say hi! 👋</div>';
    return;
  }
  const isGrp = activeConv?.type === 'group';
  let html = '', lastDate = null;
  msgs.forEach(m => {
    const dl = dateLabel(m.created_at);
    if (dl !== lastDate) { html += `<div class="msg-date-div">${dl}</div>`; lastDate = dl; }
    html += buildMsgHtml(m, isGrp);
  });
  box.innerHTML = html;
  box.scrollTop = box.scrollHeight;
  attachDelBtns();
}

function buildMsgHtml(m, isGrp) {
  const mine = (m.sender_id == ME);
  const av   = mine ? '' : (() => {
    const src = m.avatar ? SITE+'/'+m.avatar : (m.google_avatar||null);
    return `<div class="msg-av-sm">${src?`<img src="${src}">` : (m.sender_name||'?')[0].toUpperCase()}</div>`;
  })();
  const senderLine = (!mine && isGrp) ? `<div class="msg-sender">${esc(m.sender_name||'')}</div>` : '';
  const delBtn     = (mine && !m.is_deleted) ? `<button class="msg-del-btn" data-mid="${m.id}" title="Delete">×</button>` : '';
  const body       = m.is_deleted ? '<em>Message deleted</em>' : esc(m.body).replace(/\n/g,'<br>');
  return `<div class="msg-row ${mine?'mine':'theirs'}" id="msg-${m.id}">
    ${av}
    <div class="msg-wrap">
      ${senderLine}
      <div class="msg-bubble${m.is_deleted?' deleted':''}">${body}${delBtn}</div>
      <div class="msg-time">${fmtTime(m.created_at)}</div>
    </div>
  </div>`;
}

function appendMsg(m) {
  const box   = document.getElementById('chatMessages');
  const empty = box.querySelector('[style*="No messages"]');
  if (empty) box.innerHTML = '';
  const isGrp = activeConv?.type === 'group';
  const div   = document.createElement('div');
  div.innerHTML = buildMsgHtml(m, isGrp);
  const node  = div.firstElementChild;
  box.appendChild(node);
  box.scrollTop = box.scrollHeight;
  attachDelBtns();
}

function attachDelBtns() {
  document.querySelectorAll('.msg-del-btn').forEach(btn => {
    btn.onclick = () => deleteMsg(parseInt(btn.dataset.mid));
  });
}

/* ══════════════════════════════════════
   SEND MESSAGE
   ══════════════════════════════════════ */
const chatInput = document.getElementById('chatInput');
const sendBtn   = document.getElementById('sendBtn');

async function sendMessage() {
  const body = chatInput.value.trim();
  if (!body || !activeConv) return;
  chatInput.value = '';
  chatInput.style.height = '';
  sendBtn.disabled = true;
  const d = await api({action:'send_message', conv_id:activeConv.id, body});
  sendBtn.disabled = false;
  if (d.success) {
    appendMsg(d.message);
    lastMsgAt = d.message.created_at;
    loadConvs();
  }
}
sendBtn.addEventListener('click', sendMessage);
chatInput.addEventListener('keydown', e => {
  if (e.key==='Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); }
});
chatInput.addEventListener('input', function() {
  this.style.height = 'auto';
  this.style.height = Math.min(this.scrollHeight, 120)+'px';
});

/* ══════════════════════════════════════
   POLLING (every 2.5s)
   ══════════════════════════════════════ */
function startPoll() {
  stopPoll();
  pollTimer = setInterval(async () => {
    if (!activeConv) return;
    const p = {action:'get_messages', conv_id:activeConv.id};
    if (lastMsgAt) p.since = lastMsgAt;
    const d = await api(p, true);
    if (!d.success || !d.messages.length) return;
    d.messages.forEach(m => { if (!document.getElementById('msg-'+m.id)) appendMsg(m); });
    lastMsgAt = d.messages[d.messages.length-1].created_at;
    loadConvs();
  }, 2500);
}
function stopPoll() { if (pollTimer) { clearInterval(pollTimer); pollTimer=null; } }

/* ══════════════════════════════════════
   DELETE MESSAGE
   ══════════════════════════════════════ */
async function deleteMsg(id) {
  if (!(await stConfirm('Delete this message?'))) return;
  const d = await api({action:'delete_message', msg_id:id});
  if (d.success) {
    const el = document.querySelector(`#msg-${id} .msg-bubble`);
    if (el) { el.className='msg-bubble deleted'; el.innerHTML='<em>Message deleted</em>'; }
  }
}

/* ══════════════════════════════════════
   MOBILE BACK
   ══════════════════════════════════════ */
document.getElementById('backBtn').addEventListener('click', () => {
  stopPoll(); activeConv = null;
  document.getElementById('chatSidebar').classList.remove('mob-hide');
  document.getElementById('chatPanel').classList.add('mob-hide');
  document.getElementById('chatEmpty').style.display     = 'flex';
  document.getElementById('panelHdr').style.display      = 'none';
  document.getElementById('chatMessages').style.display  = 'none';
  document.getElementById('typingRow').style.display     = 'none';
  document.getElementById('chatInputArea').style.display = 'none';
});

/* ══════════════════════════════════════
   MODAL HELPERS  (uses style.css .active)
   ══════════════════════════════════════ */
function openModal(id)  { document.getElementById(id).classList.add('active'); }
function closeModal(id) { document.getElementById(id).classList.remove('active'); }

// Close on backdrop click
document.querySelectorAll('.modal-overlay').forEach(m => {
  m.addEventListener('click', e => { if (e.target === m) m.classList.remove('active'); });
});

/* ══════════════════════════════════════
   DIRECT CHAT MODAL
   ══════════════════════════════════════ */
document.getElementById('btnDirect').addEventListener('click', () => {
  document.getElementById('directSearch').value = '';
  openModal('modalDirect');
  document.getElementById('directSearch').focus();
  loadDirectUsers('');
});
document.getElementById('cancelDirect').addEventListener('click', () => closeModal('modalDirect'));

document.getElementById('directSearch').addEventListener('input', function() {
  clearTimeout(directTimer);
  directTimer = setTimeout(() => loadDirectUsers(this.value), 280);
});

async function loadDirectUsers(q) {
  const el = document.getElementById('directUserList');
  el.innerHTML = '<div style="text-align:center;padding:16px;color:var(--text-muted,#64748b);font-size:13px">Loading…</div>';
  const d = await api({action:'list_users', q}, true);
  if (!d.success || !d.users.length) {
    el.innerHTML = '<div style="text-align:center;padding:16px;color:var(--text-muted,#64748b);font-size:13px">No users found</div>';
    return;
  }
  el.innerHTML = d.users.map(u => {
    const src = u.avatar ? SITE+'/'+u.avatar : (u.google_avatar||null);
    const av  = src ? `<img src="${src}">` : u.name[0].toUpperCase();
    return `<div class="user-pick-item" data-uid="${u.id}">
      <div class="user-pick-av">${av}</div>
      <div class="user-pick-name">${esc(u.name)}</div>
    </div>`;
  }).join('');
  el.querySelectorAll('.user-pick-item').forEach(item => {
    item.addEventListener('click', () => startDirect(parseInt(item.dataset.uid)));
  });
}

async function startDirect(uid) {
  closeModal('modalDirect');
  const d = await api({action:'open_direct', user_id:uid});
  if (d.success) { await loadConvs(); openConv(d.conv_id); }
  else alert(d.msg||'Could not open chat.');
}

/* ══════════════════════════════════════
   GROUP MODAL
   ══════════════════════════════════════ */
document.getElementById('btnGroup').addEventListener('click', () => {
  groupPicked = {};
  document.getElementById('groupName').value   = '';
  document.getElementById('groupSearch').value = '';
  document.getElementById('selCount').textContent = '';
  openModal('modalGroup');
  document.getElementById('groupName').focus();
  loadGroupUsers('');
});
document.getElementById('cancelGroup').addEventListener('click', () => closeModal('modalGroup'));

document.getElementById('groupSearch').addEventListener('input', function() {
  clearTimeout(groupTimer);
  groupTimer = setTimeout(() => loadGroupUsers(this.value), 280);
});

async function loadGroupUsers(q) {
  const el = document.getElementById('groupUserList');
  el.innerHTML = '<div style="text-align:center;padding:16px;color:var(--text-muted,#64748b);font-size:13px">Loading…</div>';
  const d = await api({action:'list_users', q}, true);
  if (!d.success || !d.users.length) {
    el.innerHTML = '<div style="text-align:center;padding:16px;color:var(--text-muted,#64748b);font-size:13px">No users found</div>';
    return;
  }
  el.innerHTML = d.users.map(u => {
    const src     = u.avatar ? SITE+'/'+u.avatar : (u.google_avatar||null);
    const av      = src ? `<img src="${src}">` : u.name[0].toUpperCase();
    const checked = groupPicked[u.id] ? 'checked' : '';
    return `<label class="user-pick-item">
      <input type="checkbox" ${checked} data-uid="${u.id}" data-name="${esc(u.name)}">
      <div class="user-pick-av">${av}</div>
      <div class="user-pick-name">${esc(u.name)}</div>
    </label>`;
  }).join('');
  el.querySelectorAll('input[type=checkbox]').forEach(cb => {
    cb.addEventListener('change', () => {
      const uid = parseInt(cb.dataset.uid);
      if (cb.checked) groupPicked[uid] = cb.dataset.name;
      else delete groupPicked[uid];
      const cnt = Object.keys(groupPicked).length;
      document.getElementById('selCount').textContent = cnt ? `${cnt} member${cnt>1?'s':''} selected` : '';
    });
  });
}

document.getElementById('createGroupBtn').addEventListener('click', async () => {
  const name    = document.getElementById('groupName').value.trim();
  const members = Object.keys(groupPicked).map(Number);
  if (!name)           { alert('Enter a group name.'); return; }
  if (!members.length) { alert('Select at least one member.'); return; }
  closeModal('modalGroup');
  const d = await api({action:'create_group', name, members:JSON.stringify(members)});
  if (d.success) { await loadConvs(); openConv(d.conv_id); }
  else alert(d.msg||'Could not create group.');
});

/* ══════════════════════════════════════
   NAV BADGE (unread count)
   ══════════════════════════════════════ */
async function updateNavBadge() {
  const d = await api({action:'total_unread'}, true);
  if (!d.success) return;
  const el = document.getElementById('chatNavBadge');
  if (el) el.textContent = d.unread > 0 ? d.unread : '';
}
setInterval(updateNavBadge, 10000);

/* ── Init ── */
loadConvs();

})();
</script>

<?php
require_once 'includes/footer.php';
renderFooter();
?>
