'use strict';
// ═══════════════════════════════════════════════
// js/messenger.js — Full-page instant messenger
// Two-pane view: conversation list + open thread.
// Reuses the chat popup's storage, send path, photo
// picker and bubble renderer from contacts.js.
// ═══════════════════════════════════════════════

let _msgrKey = null; // pubKeyB64 of the open thread, or null

// Exposed so contacts.js/_chatNotify can tell whether a thread is open
function _msgrOpenKey() {
  return (_currentTab === 'messages') ? _msgrKey : null;
}

function _msgrActiveContacts() {
  if (typeof getContacts !== 'function') return [];
  // Same visibility rule as the Buddies page (only removed/forgotten are hidden),
  // except contacts you have chat history with are always listed -- this is the
  // messenger, so existing conversations must never silently disappear.
  return getContacts().filter(c => {
    if (!c || !c.pubKeyB64) return false;
    if (!c.removedAt && !c.forgottenAt) return true;
    try { return _msgrLastMsg(c.pubKeyB64) != null; } catch (e) { return false; }
  });
}

function _msgrLastMsg(pubKeyB64) {
  const hist = typeof getChatHistory === 'function' ? getChatHistory(pubKeyB64) : [];
  if (!Array.isArray(hist) || !hist.length) return null;
  return hist.slice().sort((a, b) => (a.ts || '') < (b.ts || '') ? -1 : 1)[hist.length - 1];
}

function _msgrPreviewText(m) {
  if (!m) return 'No messages yet';
  const prefix = m.from === 'me' ? 'You: ' : '';
  if (m.imgKey || (m.text && m.text.startsWith('[photo:'))) return prefix + '📷 Photo';
  if (m.text && m.text.startsWith('[comparison:'))          return prefix + '📊 Comparison';
  return prefix + (m.text || '');
}

function _msgrTimeLabel(ts) {
  if (!ts) return '';
  const d = new Date(ts), now = new Date();
  if (d.toDateString() === now.toDateString())
    return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
  if (now - d < 6 * 86400000)
    return d.toLocaleDateString([], { weekday: 'short' });
  return d.toLocaleDateString([], { month: 'short', day: 'numeric' });
}

// ── Page render ────────────────────────────────────────────────────────────────

function renderMessengerPage() {
  try {
    renderMsgrList();
  } catch (e) {
    console.error('[messenger] list render failed:', e);
    const list = document.getElementById('msgr-list');
    if (list) list.innerHTML = `<div class="msgr-list-empty"><p>Could not load conversations. Try reopening this tab.</p></div>`;
  }
  // Re-validate the open thread (contact may have been removed)
  if (_msgrKey && !_msgrActiveContacts().some(c => c.pubKeyB64 === _msgrKey)) _msgrKey = null;
  if (_msgrKey) renderMsgrThread();
  else {
    const empty  = document.getElementById('msgr-thread-empty');
    const thread = document.getElementById('msgr-thread');
    if (empty)  empty.style.display = '';
    if (thread) thread.style.display = 'none';
    document.getElementById('msgr')?.classList.remove('thread-open');
  }
}

function renderMsgrList() {
  const list = document.getElementById('msgr-list');
  if (!list) return;
  const contacts = _msgrActiveContacts();
  if (!contacts.length) {
    list.innerHTML = `<div class="msgr-list-empty">
      <p>No buddies yet.</p>
      <p>Add a restoration buddy and your conversations will appear here.</p>
      <button class="btn btn-sm" data-action="tab" data-a0="contacts">Find buddies</button>
      <button class="btn btn-ghost btn-sm" data-action="showDemoProfile">See a sample profile</button>
    </div>`;
    return;
  }
  // Most recent conversation first; buddies with no messages yet follow, A-Z.
  const rows = contacts.map(c => {
    let last = null;
    try { last = _msgrLastMsg(c.pubKeyB64); } catch (e) { /* corrupt history: show contact anyway */ }
    const name = c.journal?.displayName || c.nickname || 'Buddy';
    return { c, last, name, ts: last?.ts || '' };
  }).sort((a, b) => {
    if (a.ts !== b.ts) return a.ts < b.ts ? 1 : -1;
    return a.name.localeCompare(b.name, undefined, { sensitivity: 'base' });
  });

  list.innerHTML = rows.map(({ c, last, name }) => {
    try {
      const avatar = c.journal?.avatar || '🌿';
      const online = typeof isOnline === 'function' && isOnline(c.pubKeyB64);
      const unread = typeof getChatUnread === 'function' ? getChatUnread(c.pubKeyB64) : 0;
      const active = c.pubKeyB64 === _msgrKey;
      return `<button class="msgr-convo${active ? ' active' : ''}" data-action="msgrOpen" data-a0="${esc(c.pubKeyB64)}">
        <span class="msgr-convo-avatar">${esc(avatar)}<span class="msgr-convo-dot${online ? ' on' : ''}"></span></span>
        <span class="msgr-convo-main">
          <span class="msgr-convo-top">
            <span class="msgr-convo-name">${esc(name)}</span>
            <span class="msgr-convo-time">${esc(_msgrTimeLabel(last?.ts))}</span>
          </span>
          <span class="msgr-convo-bottom">
            <span class="msgr-convo-preview">${esc(_msgrPreviewText(last))}</span>
            ${unread ? `<span class="msgr-convo-unread">${unread}</span>` : ''}
          </span>
        </span>
      </button>`;
    } catch (e) {
      // One bad contact must never blank the whole list
      console.warn('[messenger] convo row failed:', e);
      return '';
    }
  }).join('');
}

function renderMsgrThread() {
  if (!_msgrKey) return;
  const empty  = document.getElementById('msgr-thread-empty');
  const thread = document.getElementById('msgr-thread');
  if (empty)  empty.style.display = 'none';
  if (thread) thread.style.display = '';
  const c = _msgrActiveContacts().find(x => x.pubKeyB64 === _msgrKey);
  const avatar = document.getElementById('msgrAvatar');
  const name   = document.getElementById('msgrName');
  const status = document.getElementById('msgrStatus');
  if (avatar) avatar.textContent = c?.journal?.avatar || '🌿';
  if (name)   name.textContent   = c?.journal?.displayName || c?.nickname || 'Buddy';
  if (status) {
    const online = typeof isOnline === 'function' && isOnline(_msgrKey);
    status.textContent = online ? '● online' : '○ offline';
  }
  const msgs = document.getElementById('msgrMsgs');
  if (msgs && typeof _chatMsgListHTML === 'function') {
    msgs.innerHTML = _chatMsgListHTML(_msgrKey);
    msgs.scrollTop = msgs.scrollHeight;
  }
}

// ── Actions ────────────────────────────────────────────────────────────────────

function msgrOpenThread(pubKeyB64) {
  _msgrKey = pubKeyB64;
  if (typeof clearChatUnread === 'function') clearChatUnread(pubKeyB64);
  if (typeof updatePeerStatus === 'function') updatePeerStatus();
  // Hide any leftover photo picker state from a previous thread
  const picker = document.getElementById('msgrPhotoPicker');
  if (picker) picker.style.display = 'none';
  const msgsEl = document.getElementById('msgrMsgs');
  if (msgsEl) msgsEl.style.display = '';
  document.getElementById('msgr')?.classList.add('thread-open');
  renderMsgrList();
  renderMsgrThread();
  requestAnimationFrame(() => {
    const msgs = document.getElementById('msgrMsgs');
    if (msgs) msgs.scrollTop = msgs.scrollHeight;
    // Second pass after images load from IDB
    requestAnimationFrame(() => { if (msgs) msgs.scrollTop = msgs.scrollHeight; });
    if (window.matchMedia && !window.matchMedia('(max-width: 640px)').matches)
      document.getElementById('msgrInput')?.focus();
  });
}

// Tap on the thread header name/avatar: show the buddy's profile popup
function msgrOpenProfile() {
  if (!_msgrKey) return;
  if (typeof openBuddyProfile === 'function') openBuddyProfile(_msgrKey);
}

// Mobile back button: return to the conversation list
function msgrBack() {
  _msgrKey = null;
  document.getElementById('msgr')?.classList.remove('thread-open');
  renderMessengerPage();
}

async function sendMsgrMsg() {
  if (!_msgrKey) return;
  const input = document.getElementById('msgrInput');
  if (!input) return;
  const text = input.value.trim().slice(0, 500);
  if (!text) return;
  input.value = '';
  const id = uuid();
  const ts = new Date().toISOString();
  appendChat(_msgrKey, { id, from: 'me', text, ts, delivered: false, failed: false });
  if (typeof syncAfterSave === 'function') syncAfterSave(); // sync sent message to paired devices
  renderMsgrThread();
  renderMsgrList();
  try {
    const result = await p2pSendChatMessage(_msgrKey, text, id);
    if (result === 'direct') _updateChatMsgStatus(_msgrKey, id, { delivered: true });
  } catch (e) {
    _updateChatMsgStatus(_msgrKey, id, { failed: true });
  }
  renderMsgrThread();
}

// Photo picker: reuse the chat popup's picker renderer, pointed at our element
function msgrTogglePhotoPicker() {
  if (!_msgrKey) return;
  const picker = document.getElementById('msgrPhotoPicker');
  const msgsEl = document.getElementById('msgrMsgs');
  if (!picker) return;
  if (picker.style.display !== 'none' && picker.innerHTML) {
    picker.style.display = 'none';
    if (msgsEl) msgsEl.style.display = '';
    return;
  }
  _chatPhotoPickerTab = 'mine';
  _chatPhotoPickerEl  = 'msgrPhotoPicker';
  _chatPhotoPickerPub = _msgrKey;
  try { _renderChatPhotoPicker(); } catch (e) { console.error('[messenger] picker render error:', e); }
  picker.style.display = '';
  if (msgsEl) msgsEl.style.display = 'none';
}

// Called from contacts.js/_chatNotify and p2p sync when chat data changes
function refreshMessenger(pubKeyB64) {
  if (_currentTab !== 'messages') return;
  renderMsgrList();
  if (_msgrKey && (!pubKeyB64 || pubKeyB64 === _msgrKey)) renderMsgrThread();
}
