/* ============================================================
   HIVE — Notifications + Messages
   ============================================================ */

function Notifications({ t, items, onOpenUser }) {
  const iconFor = { system: 'shield', watch: 'eye', like: 'heart', follow: 'user' };
  return (
    <div className="animate-in">
      <div style={{ padding: '18px 20px', borderBottom: '1px solid var(--border)' }}>
        <h2 style={{ fontSize: 20, fontWeight: 700, fontFamily: 'var(--font-brand)' }}>{t.notif_title}</h2>
        <p className="mono" style={{ fontSize: 12, color: 'var(--text-faint)', marginTop: 3 }}>{t.notif_sub}</p>
      </div>
      {items.length === 0 && (
        <div style={{ padding: '54px 24px', textAlign: 'center', color: 'var(--text-faint)' }}>
          <Icon name="bell" size={30} style={{ opacity: .5 }} />
          <p style={{ marginTop: 12, fontWeight: 600, color: 'var(--text-dim)' }}>{t.empty_notifs_hed}</p>
          <p className="mono" style={{ marginTop: 4, fontSize: 12.5 }}>{t.empty_notifs_sub}</p>
        </div>
      )}
      {items.map((n, i) => {
        const u = uget(n.user);
        const alarm = n.alarm;
        return (
          <div key={i} className="hoverable" style={{ display: 'flex', gap: 13, padding: '15px 20px', borderBottom: '1px solid var(--border)',
            cursor: 'pointer', borderLeft: alarm ? '3px solid var(--alarm)' : '3px solid transparent' }}
            onClick={() => !u.system && onOpenUser(u)}>
            <div style={{ display: 'grid', placeItems: 'center', width: 38, height: 38, borderRadius: 11, flex: '0 0 auto',
              background: alarm ? 'oklch(0.70 0.165 25 / .15)' : 'var(--surface-2)',
              color: alarm ? 'var(--alarm)' : (n.type === 'like' ? 'var(--alarm)' : 'var(--accent)') }}>
              <Icon name={iconFor[n.type]} size={19} fill={n.type === 'like'} />
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 9, marginBottom: 3 }}>
                <Avatar user={u} size={24} />
                <span style={{ fontWeight: 600, fontSize: 13.5 }}>{u.name}</span><Badge user={u} />
                <span className="mono" style={{ marginLeft: 'auto', fontSize: 11.5, color: 'var(--text-faint)' }}>{L(n.time)}</span>
              </div>
              <p style={{ fontSize: 14, color: alarm ? 'var(--alarm)' : 'var(--text-dim)', lineHeight: 1.45, textWrap: 'pretty' }}>{L(n.text)}</p>
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ---------------- Messages ---------------- */
function Messages({ t, me, threads, openId, setOpenId }) {
  const active = threads.find(x => x.id === openId);
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 320px) 1fr', height: '100%', minHeight: 0 }} className="msg-grid">
      {/* list */}
      <div style={{ borderRight: '1px solid var(--border)', overflowY: 'auto', minHeight: 0 }} className="msg-list">
        <div style={{ padding: '18px 18px 14px', borderBottom: '1px solid var(--border)', position: 'sticky', top: 0, background: 'var(--bg)', zIndex: 2 }}>
          <h2 style={{ fontSize: 19, fontWeight: 700, fontFamily: 'var(--font-brand)' }}>{t.msg_title}</h2>
          <p className="mono" style={{ fontSize: 11, color: 'var(--text-faint)', marginTop: 3 }}>{t.msg_sub}</p>
        </div>
        {threads.map(th => {
          const u = uget(th.user);
          return (
            <button key={th.id} className="hoverable" onClick={() => setOpenId(th.id)}
              style={{ display: 'flex', gap: 12, padding: '13px 16px', width: '100%', textAlign: 'left', border: 'none',
                borderBottom: '1px solid var(--border)', background: openId === th.id ? 'var(--surface-2)' : 'transparent', alignItems: 'center' }}>
              <Avatar user={u} size={44} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                  <span style={{ fontWeight: 600, fontSize: 14, color: 'var(--text)' }}>{u.name}</span><Badge user={u} />
                  {th.unread > 0 && <span className="dot pulse" style={{ marginLeft: 'auto' }} />}
                </div>
                <p style={{ fontSize: 13, color: 'var(--text-faint)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{L(th.preview)}</p>
              </div>
            </button>
          );
        })}
        {threads.length === 0 && (
          <div style={{ padding: '40px 20px', textAlign: 'center', color: 'var(--text-faint)' }}>
            <Icon name="mail" size={28} style={{ opacity: .5 }} />
            <p style={{ marginTop: 10, fontWeight: 600, color: 'var(--text-dim)', fontSize: 14 }}>{t.empty_msg_hed}</p>
            <p className="mono" style={{ marginTop: 4, fontSize: 12 }}>{t.empty_msg_sub}</p>
          </div>
        )}
      </div>
      {/* conversation */}
      <div style={{ display: 'flex', flexDirection: 'column', minHeight: 0 }} className="msg-conv" data-open={openId ? '1' : '0'}>
        {active ? <Conversation t={t} me={me} thread={active} onBack={() => setOpenId(null)} /> :
          <div style={{ flex: 1, display: 'grid', placeItems: 'center', color: 'var(--text-faint)' }}>
            <div style={{ textAlign: 'center', padding: 24 }}><Hex size={50} watching={false} /><p className="mono" style={{ marginTop: 14, fontSize: 13 }}>{threads.length ? L({ fr: 'Sélectionnez une conversation.', en: 'Select a conversation.' }) : t.empty_msg_sub}</p></div>
          </div>}
      </div>
    </div>
  );
}

function Conversation({ t, me, thread, onBack }) {
  const u = uget(thread.user);
  const [msgs, setMsgs] = useState(thread.messages);
  const [text, setText] = useState('');
  const endRef = useRef(null);
  useEffect(() => { setMsgs(thread.messages); }, [thread.id]);
  useEffect(() => { if (endRef.current) endRef.current.parentElement.scrollTop = endRef.current.offsetTop; }, [msgs]);
  const send = () => {
    if (!text.trim()) return;
    const mine = { from: 'me', text: text.trim(), time: t.now };
    setMsgs(m => [...m, mine]); setText('');
  };
  return (
    <>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '13px 16px', borderBottom: '1px solid var(--border)' }}>
        <button className="iconbtn msg-back" onClick={onBack} style={{ display: 'none' }}><Icon name="back" size={20} /></button>
        <Avatar user={u} size={38} />
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            <span style={{ fontWeight: 600, fontSize: 14.5 }}>{u.name}</span><Badge user={u} />
          </div>
          <span className="mono" style={{ fontSize: 11, color: 'var(--accent)', display: 'flex', alignItems: 'center', gap: 5 }}>
            <span className="hive-rec dot" /> {L({ fr: 'observe cette conversation', en: 'observing this chat' })}</span>
        </div>
      </div>
      <div style={{ flex: 1, overflowY: 'auto', padding: '18px 16px', display: 'flex', flexDirection: 'column', gap: 10, minHeight: 0 }}>
        {msgs.map((m, i) => {
          const mine = m.from === 'me';
          const sys = m.from === 'hive';
          return (
            <div key={i} style={{ display: 'flex', justifyContent: mine ? 'flex-end' : 'flex-start' }}>
              <div className={sys ? 'glitchy' : ''} style={{ maxWidth: '74%', padding: '10px 14px', borderRadius: 16, fontSize: 14.5, lineHeight: 1.45,
                background: mine ? 'var(--accent)' : sys ? 'oklch(0.205 0.016 255)' : 'var(--surface-2)',
                color: mine ? 'var(--accent-ink)' : 'var(--text)',
                border: sys ? '1px solid var(--accent)' : '1px solid var(--border)',
                borderBottomRightRadius: mine ? 5 : 16, borderBottomLeftRadius: mine ? 16 : 5 }}>
                {L(m.text)}
                <div className="mono" style={{ fontSize: 10, marginTop: 4, opacity: 0.6 }}>{typeof m.time === 'string' ? m.time : L(m.time)}</div>
              </div>
            </div>
          );
        })}
        <div ref={endRef} />
      </div>
      <div style={{ display: 'flex', gap: 10, padding: 14, borderTop: '1px solid var(--border)', alignItems: 'center' }}>
        <input className="input" value={text} onChange={(e) => setText(e.target.value)}
          onKeyDown={(e) => e.key === 'Enter' && send()} placeholder={t.type_msg} style={{ borderRadius: 999 }} />
        <button className="btn btn-primary" onClick={send} style={{ width: 44, height: 44, padding: 0, borderRadius: 999, flex: '0 0 auto' }}><Icon name="send" size={19} /></button>
      </div>
    </>
  );
}

Object.assign(window, { Notifications, Messages, Conversation, MessagesDock });

/* ============================================================
   Messagerie minimisée (dock en bas de page, façon messenger)
   ============================================================ */
function dockReadFriends() {
  try { const v = JSON.parse(localStorage.getItem('censa_friends')); return Array.isArray(v) ? v : DEFAULT_FRIEND_IDS; }
  catch (e) { return DEFAULT_FRIEND_IDS; }
}
function dockLoadChat(id) { try { const all = JSON.parse(localStorage.getItem('censa_chats')) || {}; return Array.isArray(all[id]) ? all[id] : []; } catch (e) { return []; } }
function dockSaveChat(id, msgs) { try { const all = JSON.parse(localStorage.getItem('censa_chats')) || {}; all[id] = msgs; localStorage.setItem('censa_chats', JSON.stringify(all)); } catch (e) {} }
function dockNow() { const d = new Date(); return d.getHours().toString().padStart(2, '0') + ':' + d.getMinutes().toString().padStart(2, '0'); }

function MiniChat({ me, friend, onClose }) {
  const [msgs, setMsgs] = useState(() => dockLoadChat(friend.id));
  const [text, setText] = useState('');
  const endRef = useRef(null);
  useEffect(() => { if (endRef.current) endRef.current.parentElement.scrollTop = endRef.current.offsetTop; }, [msgs]);
  const send = () => {
    if (!text.trim()) return;
    const next = [...msgs, { from: 'me', text: text.trim(), time: dockNow() }];
    setMsgs(next); dockSaveChat(friend.id, next); setText('');
  };
  return (
    <div className="msg-mini card">
      <div className="msg-mini-head">
        <Avatar user={friend} size={32} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
            <span style={{ fontWeight: 600, fontSize: 13.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{friend.name}</span><Badge user={friend} />
          </div>
          <span className="mono" style={{ fontSize: 10, color: 'var(--accent)' }}>{L({ fr: 'en ligne · observé', en: 'online · observed' })}</span>
        </div>
        <button className="iconbtn" onClick={onClose} style={{ width: 30, height: 30 }}><Icon name="x" size={16} /></button>
      </div>
      <div className="msg-mini-body">
        {msgs.length === 0 && <div className="mono" style={{ textAlign: 'center', color: 'var(--text-faint)', fontSize: 11.5, padding: '18px 8px' }}>{L({ fr: 'Début de la conversation.', en: 'Start of the conversation.' })}</div>}
        {msgs.map((m, i) => (
          <div key={i} style={{ display: 'flex', justifyContent: m.from === 'me' ? 'flex-end' : 'flex-start' }}>
            <div style={{ maxWidth: '78%', padding: '7px 11px', borderRadius: 13, fontSize: 13.5, lineHeight: 1.4,
              background: m.from === 'me' ? 'var(--accent)' : 'var(--surface-2)', color: m.from === 'me' ? 'var(--accent-ink)' : 'var(--text)',
              border: '1px solid var(--border)', borderBottomRightRadius: m.from === 'me' ? 4 : 13, borderBottomLeftRadius: m.from === 'me' ? 13 : 4 }}>
              {m.text}
            </div>
          </div>
        ))}
        <div ref={endRef} />
      </div>
      <div className="msg-mini-input">
        <input className="input" value={text} onChange={(e) => setText(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && send()}
          placeholder={L({ fr: 'Message…', en: 'Message…' })} style={{ borderRadius: 999, padding: '9px 13px', fontSize: 13.5 }} />
        <button className="btn btn-primary" onClick={send} style={{ width: 38, height: 38, padding: 0, borderRadius: 999, flex: '0 0 auto' }}><Icon name="send" size={16} /></button>
      </div>
    </div>
  );
}

function MessagesDock({ t, me, onOpenFull }) {
  const [open, setOpen] = useState(false);
  const [active, setActive] = useState(null);
  const friends = dockReadFriends().map(id => MEMBERS.find(m => m.id === id)).filter(Boolean);

  return (
    <div className="msg-dock">
      {active && <MiniChat me={me} friend={active} onClose={() => setActive(null)} />}

      {open && (
        <div className="msg-dock-panel card">
          <div className="msg-dock-phead">
            <span style={{ fontWeight: 700, fontSize: 15, fontFamily: 'var(--font-brand)' }}>{L({ fr: 'Messages', en: 'Messages' })}</span>
            <button className="iconbtn" onClick={() => setOpen(false)} style={{ width: 30, height: 30 }}><Icon name="x" size={16} /></button>
          </div>
          <div className="msg-dock-list">
            {friends.length === 0 && <div className="mono" style={{ padding: '24px 14px', textAlign: 'center', color: 'var(--text-faint)', fontSize: 12 }}>{L({ fr: 'Ajoutez des ami(e)s pour discuter.', en: 'Add friends to chat.' })}</div>}
            {friends.map(f => {
              const last = dockLoadChat(f.id).slice(-1)[0];
              return (
                <button key={f.id} className="hoverable" onClick={() => { setActive(f); }}
                  style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '10px 13px', width: '100%', textAlign: 'left', border: 'none', background: 'transparent' }}>
                  <Avatar user={f} size={40} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
                      <span style={{ fontWeight: 600, fontSize: 13.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{f.name}</span><Badge user={f} />
                    </div>
                    <span style={{ fontSize: 12, color: 'var(--text-faint)', display: 'block', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {last ? last.text : L({ fr: 'Démarrer la conversation', en: 'Start the conversation' })}</span>
                  </div>
                </button>
              );
            })}
          </div>
          <button className="msg-dock-all" onClick={onOpenFull}><Icon name="mail" size={15} /> {L({ fr: 'Ouvrir la messagerie', en: 'Open full messages' })}</button>
        </div>
      )}

      <button className="msg-dock-toggle" onClick={() => setOpen(o => !o)}>
        <Icon name="mail" size={18} fill />
        <span>{L({ fr: 'Messages', en: 'Messages' })}</span>
        <Icon name="chev" size={15} style={{ transform: open ? 'rotate(90deg)' : 'rotate(-90deg)', transition: 'transform .18s' }} />
      </button>
    </div>
  );
}
