﻿// AI Отдел — чат-таб + экран переписки (Telegram-style)

// Mock conversations — last message and unread count per employee
const CONVERSATIONS = {
  elena:    { last: 'Распределила задачи команде', when: '10:42', unread: 2, mine: false },
  lyudmila: { last: 'Готов первый драфт ЦА',         when: '10:38', unread: 1, mine: false },
  dmitry:   { last: 'KPI рассчитал, сейчас риски',   when: '10:36', unread: 0, mine: false },
  igor:     { last: 'Ты:  Сделай мягче по тону',     when: '10:30', unread: 0, mine: true  },
  kostya:   { last: 'Контент-план готов 🎉',         when: '09:55', unread: 3, mine: false },
  alina:    { last: 'Ты:  Нужно 5 вариантов',         when: '09:20', unread: 0, mine: true  },
  mark:     { last: 'Начинаю web research',           when: '09:12', unread: 0, mine: false },
  oleg:     { last: 'Финал собираю, 15 мин',          when: 'Вчера', unread: 0, mine: false },
};

// Per-employee message threads (small samples)
const THREADS = {
  elena: [
    { from: 'them', t: 'Привет! Я Елена, твой менеджер. Готова распределить задачи.', when: '10:30' },
    { from: 'me',   t: 'Привет! Запустим проект по B2B-выходу. Подключи команду.', when: '10:32' },
    { from: 'them', t: 'Окей. Беру на себя координацию. Подключаю:\n• Людмилу — ЦА и оффер\n• Дмитрия — KPI и риски\n• Игоря — позиционирование', when: '10:33' },
    { from: 'them', t: 'Распределила задачи команде ✅', when: '10:42' },
  ],
  lyudmila: [
    { from: 'them', t: 'Начинаю с ЦА и оффера. Какой у нас сегмент — SMB или enterprise?', when: '10:34' },
    { from: 'me',   t: 'SMB, средний чек 200-500к', when: '10:35' },
    { from: 'them', t: 'Поняла. Первый драфт через ~15 мин.', when: '10:36' },
    { from: 'them', t: 'Готов первый драфт ЦА', when: '10:38' },
  ],
  dmitry: [
    { from: 'them', t: 'Считаю риски и KPI. CAC, LTV, payback — это всё нужно?', when: '10:33' },
    { from: 'me',   t: 'Да, плюс churn в первый месяц', when: '10:34' },
    { from: 'them', t: 'KPI рассчитал, сейчас риски', when: '10:36' },
  ],
  igor:    [{ from: 'them', t: 'Формирую позиционирование на основе данных Людмилы.', when: '10:25' }, { from: 'me', t: 'Сделай мягче по тону', when: '10:30' }],
  kostya:  [{ from: 'them', t: 'Собираю контент-план. Каналы: TG, VK, IG.', when: '09:30' }, { from: 'them', t: 'Контент-план готов 🎉', when: '09:55' }],
  alina:   [{ from: 'them', t: 'Начинаю с креативных идей.', when: '09:15' }, { from: 'me', t: 'Нужно 5 вариантов', when: '09:20' }],
  mark:    [{ from: 'them', t: 'Начинаю web research', when: '09:12' }],
  oleg:    [{ from: 'them', t: 'Финал собираю, 15 мин', when: 'Вчера' }],
};

// ──────────────────────────────────────────────────────────────
// SCREEN: CHAT LIST
// ──────────────────────────────────────────────────────────────
function ChatTab({ T, nav, stateMode, onUnreadUpdate }) {
  var [unread, setUnread] = React.useState({});

  // Poll for unread counts every 30s
  React.useEffect(function() {
    if (!window.AI_API || !window.AI_API.getToken()) return;
    function poll() {
      var sinceMap = {};
      var team = ['elena','mark','lyudmila','dmitry','igor','kostya','alina','oleg','all'];
      team.forEach(function(id) {
        var ts = localStorage.getItem('ai_last_read_' + id);
        if (ts) sinceMap[id] = ts;
      });
      window.AI_API.getUnreadCounts(sinceMap).then(function(counts) {
        if (counts) {
        setUnread(counts);
        var total = Object.values(counts).reduce(function(sum, n) { return sum + n; }, 0);
        if (onUnreadUpdate) onUnreadUpdate(total);
      }
      }).catch(function() {});
    }
    poll();
    var interval = setInterval(poll, 30000);
    return function() { clearInterval(interval); };
  }, []);
  const team = buildTeam(nav.dept, stateMode);
  const dept = getDept(nav.dept);
  const lead = dept.members[0];
  return (
    <React.Fragment>
      <ScreenHeader T={T} title="Чат с командой"
        right={
          <Tap onClick={() => nav.toast('Поиск откроется позже')}>
            <div style={{
              width: 36, height: 36, borderRadius: 10,
              background: T.card, border: `1px solid ${T.line}`,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><circle cx="11" cy="11" r="6.5" stroke={T.ink} strokeWidth="1.8"/><path d="M16 16l4 4" stroke={T.ink} strokeWidth="1.8" strokeLinecap="round"/></svg>
            </div>
          </Tap>
        }
      />

      {/* Telegram sync banner */}
      {(function() {
        var tgOn = localStorage.getItem('ai_tg_sync') !== 'false';
        return (
          <div style={{ padding: '0 14px 12px' }}>
            <Tap onClick={function() {
              var next = localStorage.getItem('ai_tg_sync') !== 'false' ? 'false' : 'true';
              localStorage.setItem('ai_tg_sync', next);
              nav.toast('TG-синхронизация: ' + (next === 'true' ? 'включена' : 'выключена'));
            }}>
              <div style={{
                padding: '10px 14px',
                background: tgOn ? 'linear-gradient(135deg, ' + T.accent + '18, ' + T.accent + '08)' : T.card,
                border: '1px solid ' + (tgOn ? T.accent + '30' : T.line), borderRadius: 14,
                display: 'flex', alignItems: 'center', gap: 10,
              }}>
                <div style={{
                  width: 32, height: 32, borderRadius: 32,
                  background: tgOn ? T.accent : T.line, color: '#fff',
                  display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                }}>
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M22 4l-10.2 16.5-1.5-7.3L2 9.8 22 4z" fill="#fff"/></svg>
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 12.5, fontWeight: 700, color: T.ink, letterSpacing: -0.1 }}>Синхронизация с Telegram</div>
                  <div style={{ fontSize: 10.5, color: T.mute, marginTop: 1 }}>{tgOn ? 'Подключено · переписка дублируется в TG' : 'Отключено · только в приложении'}</div>
                </div>
                <div style={{
                  padding: '4px 8px', background: tgOn ? T.okBg : T.line, color: tgOn ? T.okText : T.mute,
                  borderRadius: 6, fontSize: 10, fontWeight: 700,
                }}>{tgOn ? 'ON' : 'OFF'}</div>
              </div>
            </Tap>
          </div>
        );
      })()}

      <Scroller style={{ padding: '0 14px' }}>
        <div style={{
          background: T.card, borderRadius: 18,
          border: `1px solid ${T.line}`, overflow: 'hidden',
        }}>
          {team.map((p, i) => {
            const working = false;
            const c = {
              when: '',
              unread: 0,
              last: 'Готов к работе',
            };
            return (
              <Tap key={p.id} onClick={() => nav.push({ kind: 'chat-thread', employeeId: p.id })}>
                <div style={{
                  padding: '12px 14px', display: 'flex', gap: 12, alignItems: 'center',
                  borderBottom: i < team.length - 1 ? `1px solid ${T.divider}` : 'none',
                }}>
                  <Portrait id={p.id} portrait={p.portrait || p.id} size={48} working={working} T={T} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 8 }}>
                      <div style={{ fontSize: 16, fontWeight: 700, color: T.ink, letterSpacing: -0.2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                        {p.name} <span style={{ fontSize: 16, fontWeight: 500, color: T.mute }}>· {p.role}</span>
                      </div>
                      <span style={{ fontSize: 11, color: T.mute, fontVariantNumeric: 'tabular-nums', flexShrink: 0 }}>{c.when}</span>
                    </div>
                    <div style={{ marginTop: 2, display: 'flex', justifyContent: 'space-between', gap: 8, alignItems: 'center' }}>
                      <div style={{
                        fontSize: 12.5, color: c.unread > 0 ? T.ink : T.mute,
                        whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
                        flex: 1, fontWeight: c.unread > 0 ? 500 : 400,
                      }}>{c.last}</div>
                      {(unread[p.id] > 0) && (
                        <span style={{
                          minWidth: 18, height: 18, padding: '0 6px', borderRadius: 99,
                          background: T.accent, color: '#fff',
                          fontSize: 10.5, fontWeight: 700,
                          display: 'flex', alignItems: 'center', justifyContent: 'center',
                          fontVariantNumeric: 'tabular-nums',
                        }}>{unread[p.id]}</span>
                      )}
                    </div>
                  </div>
                </div>
              </Tap>
            );
          })}
        </div>

        {/* Group chat */}
        <div style={{ marginTop: 12, fontSize: 11, fontWeight: 700, color: T.mute, letterSpacing: 0.4, textTransform: 'uppercase', paddingLeft: 6 }}>Групповые</div>
        <div style={{
          marginTop: 8, background: T.card, borderRadius: 18,
          border: `1px solid ${T.line}`, overflow: 'hidden',
        }}>
          <Tap onClick={() => nav.push({ kind: 'chat-thread', employeeId: 'all' })}>
            <div style={{ padding: '12px 14px', display: 'flex', gap: 12, alignItems: 'center' }}>
              <div style={{
                width: 48, height: 48, borderRadius: 48, flexShrink: 0,
                background: `linear-gradient(135deg, ${T.accent}, ${T.accent}AA)`,
                display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff',
              }}>{I.team('#fff')}</div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 14, fontWeight: 700, color: T.ink, letterSpacing: -0.2 }}>Вся команда · {dept.members.length}</div>
                <div style={{ fontSize: 12, color: T.mute, marginTop: 2 }}>{lead.name}: {lead.live.replace(/[…\.]+$/, '').toLowerCase()}</div>
              </div>
              <span style={{ fontSize: 11, color: T.mute }}>10:42</span>
            </div>
          </Tap>
        </div>

        <div style={{ height: 20 }} />
      </Scroller>
    </React.Fragment>
  );
}

// ──────────────────────────────────────────────────────────────
// SCREEN: CHAT THREAD (individual conversation)
// ──────────────────────────────────────────────────────────────
function CodeBlock({ code, T }) {
  var [copied, setCopied] = React.useState(false);
  function copy(e) {
    if (e) e.stopPropagation();
    var done = function() { setCopied(true); setTimeout(function() { setCopied(false); }, 1500); };
    try {
      navigator.clipboard.writeText(code).then(done).catch(function() {
        var ta = document.createElement('textarea'); ta.value = code;
        document.body.appendChild(ta); ta.select();
        try { document.execCommand('copy'); } catch (e2) {}
        document.body.removeChild(ta); done();
      });
    } catch (e1) {
      var ta = document.createElement('textarea'); ta.value = code;
      document.body.appendChild(ta); ta.select();
      try { document.execCommand('copy'); } catch (e2) {}
      document.body.removeChild(ta); done();
    }
  }
  return React.createElement('div', {
    style: { margin: '7px 0', background: '#0d1117', borderRadius: 10, border: '1px solid rgba(255,255,255,0.08)', overflow: 'hidden' },
  },
    React.createElement('div', {
      onClick: copy,
      style: { display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: 5, padding: '6px 10px', cursor: 'pointer', fontSize: 11, fontWeight: 600, color: copied ? '#3fb950' : '#8b95a5', borderBottom: '1px solid rgba(255,255,255,0.06)', userSelect: 'none' },
    }, copied ? '✓ Скопировано' : '⧉ копировать'),
    React.createElement('pre', {
      style: { margin: 0, padding: '10px 12px', overflowX: 'auto', fontSize: 12.5, lineHeight: 1.45, color: '#c9d1d9', fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace', whiteSpace: 'pre-wrap', wordBreak: 'break-word' },
    }, code)
  );
}

function renderMarkdown(text, T) {
  if (!text) return null;
  var segments = String(text).split(/```/);
  var out = [];
  segments.forEach(function(seg, si) {
    if (si % 2 === 1) {
      // fenced code block (odd segments); drop optional leading language tag line
      var code = seg.replace(/^[a-zA-Z0-9_-]*\r?\n/, '').replace(/\s+$/, '');
      out.push(React.createElement(CodeBlock, { key: 'cb' + si, code: code, T: T }));
      return;
    }
    var normalized = seg.replace(/\n{3,}/g, '\n\n');
    var lines = normalized.split('\n');
    lines.forEach(function(line, li) {
      if (li > 0 || si > 0) out.push(React.createElement('br', { key: 's' + si + 'br' + li }));
      var hdr = line.match(/^(#{1,6})\s+(.*)$/);
      if (hdr) {
        out.push(React.createElement('strong', { key: 's' + si + 'h' + li, style: { fontSize: 15 } }, hdr[2]));
        return;
      }
      if (/^[-—]{3,}$/.test(line.trim())) return; // skip horizontal rules
      var parts = line.split(/\*\*([^*]+)\*\*/g);
      parts.forEach(function(part, pi) {
        if (!part) return;
        if (pi % 2 === 1) out.push(React.createElement('strong', { key: 's' + si + '-' + li + '-' + pi }, part));
        else out.push(part);
      });
    });
  });
  return out;
}


function ChatThreadScreen({ T, nav, employeeId }) {
  const p = employeeId === 'all'
    ? { id: 'all', name: 'Вся команда', role: getDept(nav.dept).name }
    : getMember(nav.dept, employeeId);
  const baseThread = getThread(nav.dept, employeeId);
  const [messages, setMessages] = React.useState([]);
  React.useEffect(function() {
    // Mark as read when opening chat
    localStorage.setItem('ai_last_read_' + employeeId, new Date().toISOString());
    if (!window.AI_API || !window.AI_API.getToken()) return;
    window.AI_API.getChatMessages(employeeId, null).then(function(msgs) {
      if (msgs && msgs.length > 0) {
        var mapped = msgs.map(function(m) {
          var d = new Date(m.created_at);
          return {
            id: m.id,
            from: m.role === 'user' ? 'me' : 'them',
            t: m.text,
            replyTo: m.reply_to_text || null,
            when: (function(dt){ var m = new Date(dt.getTime() + 3*60*60*1000); return m.toLocaleTimeString('ru', { hour: '2-digit', minute: '2-digit', timeZone: 'UTC' }); })(d),
          };
        });
        setMessages(mapped);
        msgCountRef.current = msgs.length;
        lastMsgTime.current = msgs[msgs.length - 1].created_at;
      }
    }).catch(function() {});
  }, [employeeId]);
  const [input, setInput] = React.useState('');
  const [typing, setTyping] = React.useState(false);
  const scrollRef = React.useRef(null);
  const msgCountRef = React.useRef(0);
  const [selected, setSelected] = React.useState({});  // {id: true}
  const [selectMode, setSelectMode] = React.useState(false);
  const longPressTimer = React.useRef(null);

  const longPressFired = React.useRef(false);
  const [contextMenu, setContextMenu] = React.useState(null); // {id, text, from}
  const [replyTo, setReplyTo] = React.useState(null); // {id, text}

  function showContextMenu(m) {
    longPressFired.current = true;
    setContextMenu({ id: m.id, text: m.t, from: m.from });
  }
  function closeContextMenu() { setContextMenu(null); }

  function startLongPress(m) {
    longPressFired.current = false;
    longPressTimer.current = setTimeout(function() { showContextMenu(m); }, 500);
  }
  function cancelLongPress() {
    clearTimeout(longPressTimer.current);
  }

  function ctxDelete(id) {
    closeContextMenu();
    if (!window.AI_API || !window.AI_API.getToken()) return;
    window.AI_API.deleteMessages([id]).then(function() {
      setMessages(function(msgs) { return msgs.filter(function(m) { return m.id !== id; }); });
      msgCountRef.current -= 1;
    }).catch(function() {});
  }

  function ctxSelect(id) {
    closeContextMenu();
    setSelectMode(true);
    setSelected(function(s) { var n = Object.assign({}, s); n[id] = true; return n; });
  }

  function toggleSelect(id) {
    if (!selectMode) return;
    setSelected(function(s) {
      var n = Object.assign({}, s);
      if (n[id]) { delete n[id]; } else { n[id] = true; }
      if (Object.keys(n).length === 0) setSelectMode(false);
      return n;
    });
  }

  function exitSelectMode() { setSelectMode(false); setSelected({}); }

  function deleteSelected() {
    var ids = Object.keys(selected).map(Number).filter(Boolean);
    if (!ids.length) return;
    if (!window.AI_API || !window.AI_API.getToken()) return;
    window.AI_API.deleteMessages(ids).then(function() {
      setMessages(function(msgs) { return msgs.filter(function(m) { return !selected[m.id]; }); });
      msgCountRef.current -= ids.length;
      exitSelectMode();
    }).catch(function() {});
  }

  React.useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [messages, typing]);

  // Poll for new assistant messages while typing indicator is active
  React.useEffect(() => {
    if (!typing) return;
    if (!window.AI_API || !window.AI_API.getToken()) return;
    var stopped = false;
    var knownCount = msgCountRef.current;
    function poll() {
      if (stopped) return;
      window.AI_API.getChatMessages(employeeId, null).then(function(msgs) {
        if (stopped || !msgs || msgs.length === 0) { if (!stopped) setTimeout(poll, 3000); return; }
        var last = msgs[msgs.length - 1];
        if (last.role === 'assistant' && msgs.length > knownCount) {
          msgCountRef.current = msgs.length;
          var mapped = msgs.map(function(m) {
            var d = new Date(m.created_at);
            return { from: m.role === 'user' ? 'me' : 'them', t: m.text, when: (function(dt){ var m = new Date(dt.getTime() + 3*60*60*1000); return m.toLocaleTimeString('ru', { hour: '2-digit', minute: '2-digit', timeZone: 'UTC' }); })(d) };
          });
          setMessages(mapped);
          setTyping(false);
        } else {
          setTimeout(poll, 3000);
        }
      }).catch(function() { if (!stopped) setTimeout(poll, 3000); });
    }
    var t = setTimeout(poll, 2000);
    return function() { stopped = true; clearTimeout(t); };
  }, [typing, employeeId]);

  function send() {
    if (!input.trim()) return;
    const txt = input.trim();
    const now = new Date();
    const when = now.toLocaleTimeString('ru', { hour: '2-digit', minute: '2-digit' });
    setMessages(m => [...m, { from: 'me', t: txt, replyTo: replyTo ? replyTo.text : null, when: when }]);
    setInput('');
    setTyping(true);
    var replyText = replyTo ? replyTo.text : null;
    setReplyTo(null);
    if (window.AI_API && window.AI_API.getToken()) {
      var tgSync = localStorage.getItem('ai_tg_sync') !== 'false';
      window.AI_API.sendChatMessage(employeeId, txt, replyText, tgSync).catch(() => setTyping(false));
    } else {
      setTimeout(() => {
        setTyping(false);
        setMessages(m => [...m, { from: 'them', t: 'Принял! Сейчас займусь.', when: when }]);
      }, 1400);
    }
  }

  const working = !!buildTeam(nav.dept, 'mixed').find(x => x.id === employeeId)?.task;

  return (
    <div style={{ display: "flex", flexDirection: "column", flex: 1, overflow: "hidden" }}>
      {/* Custom header with portrait + name */}
      <div style={{
        position: 'fixed', top: 0, left: 0, right: 0, zIndex: 50,
        padding: '6px 14px 12px', display: 'flex', alignItems: 'center', gap: 10,
        borderBottom: `1px solid ${T.divider}`,
        background: selectMode ? T.accent + '18' : T.bg,
        transition: 'background 0.2s',
      }}>
        <Tap onClick={selectMode ? exitSelectMode : nav.pop} style={{
          width: 36, height: 36, borderRadius: 12,
          background: T.card, border: `1px solid ${T.line}`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          {selectMode
            ? <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M6 18L18 6M6 6l12 12" stroke={T.ink} strokeWidth="2" strokeLinecap="round"/></svg>
            : <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M15 6l-6 6 6 6" stroke={T.ink} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
          }
        </Tap>
        {selectMode ? (
          <div style={{ flex: 1, fontSize: 14, fontWeight: 700, color: T.ink }}>
            {Object.keys(selected).length} выбрано
          </div>
        ) : (
          <Tap onClick={() => nav.push({ kind: 'employee', employeeId: p.id })}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <Portrait id={p.id} portrait={p.portrait || p.id} size={36} working={working} T={T} />
              <div>
                <div style={{ fontSize: 16, fontWeight: 700, color: T.ink, letterSpacing: -0.2 }}>{p.name}</div>
                <div style={{ fontSize: 10.5, color: working ? T.accent : T.mute, fontWeight: 600 }}>{p.role}</div>
              </div>
            </div>
          </Tap>
        )}
        <div style={{ flex: 1 }} />
        {selectMode ? (
          <Tap onClick={deleteSelected}>
            <div style={{
              width: 36, height: 36, borderRadius: 12,
              background: Object.keys(selected).length > 0 ? '#E15B5820' : T.card,
              border: `1px solid ${Object.keys(selected).length > 0 ? '#E15B58' : T.line}`,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
                <path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6" stroke={Object.keys(selected).length > 0 ? '#E15B58' : T.mute} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </div>
          </Tap>
        ) : (
          <Tap onClick={function() {
            var next = localStorage.getItem('ai_tg_sync') !== 'false' ? 'false' : 'true';
            localStorage.setItem('ai_tg_sync', next);
            nav.toast('TG: ' + (next === 'true' ? 'ON' : 'OFF'));
          }}>
            {(function() {
              var on = localStorage.getItem('ai_tg_sync') !== 'false';
              return (
                <div style={{
                  padding: '6px 10px',
                  background: on ? T.accent : T.card,
                  border: '1px solid ' + (on ? T.accent : T.line),
                  borderRadius: 99, fontSize: 11, fontWeight: 700,
                  color: on ? '#fff' : T.mute,
                  display: 'flex', alignItems: 'center', gap: 5,
                }}>
                  <svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="M22 4l-10.2 16.5-1.5-7.3L2 9.8 22 4z" fill={on ? '#fff' : T.mute}/></svg>
                  TG
                </div>
              );
            })()}
          </Tap>
        )}
      </div>

      {/* Messages */}
      <div ref={scrollRef} className="phone-scroll" style={{
        flex: 1, overflow: 'auto', padding: '72px 14px 140px',
        minHeight: 0,
        background: T.name === 'light' ? T.bg : T.bg,
      }}>
        {messages.map((m, i) => {
          const mine = m.from === 'me';
          return (
            <div key={i}
              onTouchStart={function() { startLongPress(m); }}
              onTouchEnd={function(e) {
                cancelLongPress();
                if (longPressFired.current) { longPressFired.current = false; return; }
                if (selectMode && m.id) { e.preventDefault(); toggleSelect(m.id); }
              }}
              onTouchMove={cancelLongPress}
              onMouseDown={function() { startLongPress(m); }}
              onMouseUp={function() { cancelLongPress(); if (longPressFired.current) { longPressFired.current = false; return; } if (selectMode && m.id) { toggleSelect(m.id); } }}
              onMouseLeave={cancelLongPress}
              style={{
                display: 'flex', justifyContent: mine ? 'flex-end' : 'flex-start',
                marginBottom: 8, gap: 8, alignItems: 'flex-end',
                opacity: selectMode && m.id && !selected[m.id] ? 0.45 : 1,
                transition: 'opacity 0.15s',
                background: selectMode && selected[m.id] ? T.accent + '18' : 'transparent',
                borderRadius: 12, margin: '0 -6px 8px', padding: '0 6px',
              }}>
              {!mine && i > 0 && messages[i-1].from === 'them' ? (
                <div style={{ width: 28, flexShrink: 0 }} />
              ) : !mine ? (
                <div style={{
                  width: 28, height: 28, borderRadius: 28, overflow: 'hidden',
                  background: T.portraitBg, flexShrink: 0,
                }}>
                  <img src={PORTRAIT[p.portrait || p.id]} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                </div>
              ) : null}
              <div style={{
                maxWidth: '74%',
                padding: '8px 12px',
                background: mine ? T.accent : T.card,
                color: mine ? '#fff' : T.ink,
                borderRadius: mine ? '16px 16px 4px 16px' : '16px 16px 16px 4px',
                border: mine ? 'none' : `1px solid ${T.line}`,
                boxShadow: mine ? `0 6px 14px -8px ${T.accent}AA` : T.shadow,
                fontSize: 16, lineHeight: 1.4,
                wordBreak: 'break-word',
                userSelect: 'none', WebkitUserSelect: 'none',
              }}>
                {m.replyTo && (
                  <div style={{
                    borderLeft: '3px solid ' + (mine ? 'rgba(255,255,255,0.6)' : T.accent),
                    paddingLeft: 8, marginBottom: 6,
                    opacity: 0.85,
                  }}>
                    <div style={{ fontSize: 12, fontWeight: 700, color: mine ? 'rgba(255,255,255,0.9)' : T.accent, marginBottom: 2 }}>
                      Ответ
                    </div>
                    <div style={{ fontSize: 12.5, color: mine ? 'rgba(255,255,255,0.75)' : T.mute, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: 200 }}>
                      {m.replyTo.replace(/\*\*/g, '').substring(0, 60)}
                    </div>
                  </div>
                )}
                {(function() {
                  var text = m.t || '';
                  if (text.startsWith('[PDF]')) {
                    var parts = text.slice(5).split('|');
                    var pdfName = parts[0] || 'Документ';
                    var pdfUrl = parts[1] || '#';
                    return (
                      <a href={pdfUrl} target="_blank" rel="noopener" style={{
                        display: 'flex', alignItems: 'center', gap: 10,
                        textDecoration: 'none', color: 'inherit',
                      }}>
                        <div style={{
                          width: 40, height: 40, borderRadius: 10, flexShrink: 0,
                          background: mine ? 'rgba(255,255,255,0.25)' : T.accent + '18',
                          display: 'flex', alignItems: 'center', justifyContent: 'center',
                        }}>
                          <svg width="20" height="20" viewBox="0 0 24 24" fill="none">
                            <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8l-6-6z" stroke={mine ? '#fff' : T.accent} strokeWidth="1.8" strokeLinecap="round"/>
                            <path d="M14 2v6h6M9 13h6M9 17h4" stroke={mine ? '#fff' : T.accent} strokeWidth="1.8" strokeLinecap="round"/>
                          </svg>
                        </div>
                        <div>
                          <div style={{ fontSize: 14, fontWeight: 700 }}>{pdfName}</div>
                          <div style={{ fontSize: 11, opacity: 0.7, marginTop: 2 }}>Нажми чтобы открыть PDF</div>
                        </div>
                      </a>
                    );
                  }
                  return renderMarkdown(text, T);
                })()}
                <div style={{
                  marginTop: 4, fontSize: 9.5, opacity: 0.65,
                  textAlign: 'right', fontWeight: 500,
                }}>{m.when}</div>
              </div>
              {selectMode && (
                <div style={{
                  width: 22, height: 22, borderRadius: 22, flexShrink: 0,
                  alignSelf: 'center',
                  background: selected[m.id] ? T.accent : 'transparent',
                  border: `2px solid ${selected[m.id] ? T.accent : T.mute}`,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  transition: 'all 0.15s',
                }}>
                  {selected[m.id] && (
                    <svg width="12" height="12" viewBox="0 0 24 24" fill="none">
                      <path d="M5 13l4 4L19 7" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/>
                    </svg>
                  )}
                </div>
              )}
            </div>
          );
        })}

        {typing && (
          <div style={{ display: 'flex', gap: 8, alignItems: 'flex-end', marginBottom: 8 }}>
            <div style={{
              width: 28, height: 28, borderRadius: 28, overflow: 'hidden',
              background: T.portraitBg, flexShrink: 0,
            }}>
              <img src={PORTRAIT[p.portrait || p.id]} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
            </div>
            <div style={{
              padding: '10px 14px', background: T.card, color: T.ink,
              borderRadius: '16px 16px 16px 4px', border: `1px solid ${T.line}`,
              display: 'flex', gap: 4,
            }}>
              <span className="td" style={{ width: 5, height: 5, borderRadius: 5, background: T.mute, animation: 'thinking 1.2s ease-in-out infinite' }} />
              <span className="td" style={{ width: 5, height: 5, borderRadius: 5, background: T.mute, animation: 'thinking 1.2s ease-in-out 0.15s infinite' }} />
              <span className="td" style={{ width: 5, height: 5, borderRadius: 5, background: T.mute, animation: 'thinking 1.2s ease-in-out 0.30s infinite' }} />
            </div>
          </div>
        )}
      </div>

      {/* Context Menu Overlay — TG style glass */}
      {contextMenu && (
        <div onClick={closeContextMenu} style={{
          position: 'fixed', inset: 0, zIndex: 200,
          background: 'rgba(0,0,0,0.45)',
          backdropFilter: 'blur(10px)', WebkitBackdropFilter: 'blur(10px)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <div onClick={function(e) { e.stopPropagation(); }} style={{
            borderRadius: 14,
            width: 200,
            overflow: 'hidden',
            background: T.name === 'light' ? 'rgba(255,255,255,0.95)' : 'rgba(30,28,40,0.95)',
            boxShadow: '0 4px 30px rgba(0,0,0,0.25)',
            animation: 'sheet-up 0.18s cubic-bezier(.22,1,.36,1)',
          }}>
            {[
              { icon: 'M3 10h10a8 8 0 018 8v2M3 10l6 6M3 10l6-6', label: 'Ответить', color: T.ink,
                action: function() { setReplyTo({ id: contextMenu.id, text: contextMenu.text }); closeContextMenu(); } },
              { icon: 'M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3', label: 'Скопировать', color: T.ink,
                action: function() {
                  if (contextMenu.text && navigator.clipboard) {
                    navigator.clipboard.writeText(contextMenu.text).catch(function(){});
                  }
                  closeContextMenu();
                  nav.toast('Скопировано');
                }
              },
              { icon: 'M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z', label: 'Закрепить', color: T.ink,
                action: function() { closeContextMenu(); nav.toast('Закрепить — скоро'); } },
              { icon: 'M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6', label: 'Удалить', color: '#E15B58',
                action: function() { ctxDelete(contextMenu.id); } },
              { icon: 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z', label: 'Выбрать', color: T.ink,
                action: function() { ctxSelect(contextMenu.id); } },
            ].map(function(item, idx, arr) { return (
              <button key={item.label} onClick={item.action} className="tap-btn" style={{
                all: 'unset', display: 'flex', alignItems: 'center', gap: 12,
                width: '100%', boxSizing: 'border-box',
                padding: '13px 18px',
                borderBottom: idx < arr.length - 1
                  ? '0.5px solid ' + (T.name === 'light' ? 'rgba(0,0,0,0.1)' : 'rgba(255,255,255,0.08)')
                  : 'none',
                cursor: 'pointer',
              }}>
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
                  <path d={item.icon} stroke={item.color} strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/>
                </svg>
                <span style={{ fontSize: 16, fontWeight: 400, color: item.color, letterSpacing: -0.1 }}>{item.label}</span>
              </button>
            ); })}
          </div>
        </div>
      )}

      {/* Reply Preview */}
      {replyTo && (
        <div style={{
          position: 'fixed', bottom: 136, left: 0, right: 0, zIndex: 49,
          padding: '8px 14px',
          background: T.card,
          borderTop: `1px solid ${T.divider}`,
          display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <div style={{ width: 3, height: 36, borderRadius: 3, background: T.accent, flexShrink: 0 }} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 12, fontWeight: 700, color: T.accent, marginBottom: 2 }}>Ответить</div>
            <div style={{ fontSize: 13, color: T.mute, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
              {replyTo.text.replace(/\*\*/g, '').substring(0, 80)}
            </div>
          </div>
          <Tap onClick={function() { setReplyTo(null); }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
              <path d="M6 18L18 6M6 6l12 12" stroke={T.mute} strokeWidth="1.8" strokeLinecap="round"/>
            </svg>
          </Tap>
        </div>
      )}

      {/* Composer */}
      <div style={{
        position: 'fixed', bottom: 78, left: 0, right: 0, zIndex: 50,
        padding: '10px 12px', borderTop: `1px solid ${T.divider}`,
        background: T.card, display: 'flex', alignItems: 'center', gap: 8,
      }}>
        <Tap onClick={() => nav.toast('Вложение скоро')}>
          <div style={{
            width: 36, height: 36, borderRadius: 12,
            background: T.bg2 || T.bg, color: T.mute,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>{I.clip(T.mute)}</div>
        </Tap>
        <textarea
          value={input}
          rows={1}
          onChange={e => {
            setInput(e.target.value);
            e.target.style.height = 'auto';
            e.target.style.height = Math.min(e.target.scrollHeight, 120) + 'px';
          }}
          onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); e.target.style.height = 'auto'; } }}
          placeholder="Сообщение..."
          style={{
            flex: 1, padding: '9px 14px',
            background: T.bg2 || T.bg, color: T.ink,
            border: `1px solid ${T.line}`, borderRadius: 18,
            fontSize: 16, fontFamily: 'inherit', lineHeight: 1.35,
            outline: 'none', resize: 'none',
            maxHeight: 120, overflowY: 'auto', boxSizing: 'border-box',
          }}
        />
        <Tap onClick={send}>
          <div style={{
            width: 36, height: 36, borderRadius: 36,
            background: input.trim() ? T.accent : T.line,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            transition: 'background .2s',
          }}>{I.send(input.trim() ? '#fff' : T.mute)}</div>
        </Tap>
      </div>
    </div>
  );
}

Object.assign(window, { ChatTab, ChatThreadScreen });
