// Chat — native iOS chat with the Life OS LLM. Rich inline cards.
// Wired to POST /api/chat — local messages state, typing indicator while waiting.

function ChatScreen({ go }) {
  const d = LifeData;
  const [showMemory, setShowMemory] = React.useState(false);
  const [draft, setDraft] = React.useState('');
  const [messages, setMessages] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [initialized, setInitialized] = React.useState(false);
  const scrollRef = React.useRef(null);
  const inputRef = React.useRef(null);
  const pollRef = React.useRef(null);
  const atBottomRef = React.useRef(true);

  const fetchHistory = async () => {
    try {
      const res = await fetch(`/api/chat/history?user=${d.user}&limit=40`);
      if (res.ok) {
        const { messages: msgs } = await res.json();
        setMessages(msgs);
        setInitialized(true);
      }
    } catch {}
  };

  React.useEffect(() => {
    fetchHistory();
    pollRef.current = setInterval(fetchHistory, 5000);
    return () => clearInterval(pollRef.current);
  }, []);

  React.useEffect(() => {
    if (atBottomRef.current && scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [messages, loading]);

  const onScroll = () => {
    if (!scrollRef.current) return;
    const { scrollTop, scrollHeight, clientHeight } = scrollRef.current;
    atBottomRef.current = scrollHeight - scrollTop - clientHeight < 60;
  };

  const fmtTime = () => new Date().toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: false });

  const send = async () => {
    const text = draft.trim();
    if (!text || loading) return;
    setDraft('');
    atBottomRef.current = true;
    const userMsg = { id: `u${Date.now()}`, role: 'user', time: fmtTime(), text };
    setMessages(msgs => [...msgs, userMsg]);
    setLoading(true);
    try {
      const res = await fetch('/api/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message: text, user: d.user }),
      });
      if (res.ok) {
        await fetchHistory();
      } else {
        const asstMsg = { id: `a${Date.now()}`, role: 'assistant', time: fmtTime(), text: 'Sorry, something went wrong. Is the backend running?' };
        setMessages(msgs => [...msgs, asstMsg]);
      }
    } catch (err) {
      const asstMsg = { id: `a${Date.now()}`, role: 'assistant', time: fmtTime(), text: 'Cannot reach Life OS backend. Check that the server is running.' };
      setMessages(msgs => [...msgs, asstMsg]);
    } finally {
      setLoading(false);
    }
  };

  const onKeyDown = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); }
  };

  const fillDraft = (s) => { setDraft(s); if (inputRef.current) inputRef.current.focus(); };

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
      {/* Header */}
      <div style={{
        padding: '54px 16px 10px',
        background: 'rgba(242,242,247,0.85)',
        backdropFilter: 'blur(20px) saturate(180%)',
        WebkitBackdropFilter: 'blur(20px) saturate(180%)',
        borderBottom: `0.5px solid ${T.sep}`,
        display: 'flex', alignItems: 'center', gap: 10,
        position: 'relative', zIndex: 5,
      }}>
        <div style={{
          width: 36, height: 36, borderRadius: 12,
          background: grad('#1C1C1E','#3A3A3C'),
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <IconSparkle size={18} color="#FFCC00" fill="#FFCC00" sw={0} />
        </div>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 15, fontWeight: 600 }}>Life OS</div>
          <div style={{ fontSize: 11, color: T.green, display: 'flex', alignItems: 'center', gap: 4 }}>
            <Dot color={T.green} size={6} /> Synced with Telegram · Ollama · Local
          </div>
        </div>
        <Pill onClick={() => setShowMemory(true)} padded={false} style={{ height: 32, padding: '0 12px' }}>
          <IconBrain size={14} color={T.label} /> <span style={{ fontSize: 12, fontWeight: 600 }}>Context</span>
        </Pill>
      </div>

      {/* Messages */}
      <div ref={scrollRef} onScroll={onScroll} style={{ flex: 1, overflow: 'auto', padding: '14px 12px 180px' }}>
        {!initialized && (
          <div style={{ display: 'flex', justifyContent: 'center', padding: '40px 0', color: T.label3, fontSize: 13 }}>Loading…</div>
        )}
        {initialized && messages.length === 0 && (
          <div style={{ display: 'flex', justifyContent: 'center', padding: '40px 16px', color: T.label2, fontSize: 14, textAlign: 'center', lineHeight: '20px' }}>
            No messages yet.<br />Ask something below or send a Telegram message.
          </div>
        )}
        {messages.map((m, i) => (
          <Message key={m.id} m={m} prev={messages[i-1]} />
        ))}

        {/* typing indicator — only shown while waiting for LLM */}
        {loading && (
          <div style={{ display: 'flex', alignItems: 'flex-end', gap: 6, padding: '4px 4px', marginTop: 10 }}>
            <div style={{
              background: T.bg2, borderRadius: 18,
              padding: '10px 14px', display: 'flex', gap: 4,
              boxShadow: '0 1px 2px rgba(0,0,0,0.03)',
            }}>
              {[0,1,2].map(i => (
                <span key={i} style={{
                  width: 6, height: 6, borderRadius: 999, background: T.label3,
                  animation: `chatdot 1.2s ${i*0.15}s infinite ease-in-out`,
                  display: 'inline-block',
                }} />
              ))}
            </div>
          </div>
        )}
      </div>

      {/* Composer */}
      <div style={{
        position: 'absolute', bottom: 88, left: 0, right: 0,
        padding: '8px 12px 10px',
        background: 'rgba(242,242,247,0.85)',
        backdropFilter: 'blur(20px) saturate(180%)',
        WebkitBackdropFilter: 'blur(20px) saturate(180%)',
        borderTop: `0.5px solid ${T.sep}`,
      }}>
        <div style={{
          display: 'flex', alignItems: 'flex-end', gap: 8,
          background: T.bg2, borderRadius: 22,
          padding: '6px 6px 6px 16px',
          boxShadow: '0 1px 2px rgba(0,0,0,0.04)',
        }}>
          <input
            ref={inputRef}
            value={draft}
            onChange={e => setDraft(e.target.value)}
            onKeyDown={onKeyDown}
            placeholder="Ask Life OS…  /ask /brief /shop /remember"
            style={{
              flex: 1, border: 'none', outline: 'none', background: 'transparent',
              fontSize: 16, color: T.label, padding: '8px 0', minWidth: 0,
              fontFamily: 'inherit',
            }} />
          <button onClick={send} disabled={loading} style={{
            width: 32, height: 32, borderRadius: 999, border: 'none',
            background: (draft.trim() && !loading) ? T.blue : T.label4,
            cursor: (draft.trim() && !loading) ? 'pointer' : 'default',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            transition: 'background 0.15s',
          }}>
            <IconArrowUp size={16} color="#fff" />
          </button>
        </div>
        {/* Quick-fill chips */}
        <div style={{ display: 'flex', gap: 6, marginTop: 8, overflowX: 'auto', paddingBottom: 2 }}>
          {['/brief', '/ask weather tomorrow', '/email', '/shop חלב ביצים', '/remember', '/paid'].map(s => (
            <span key={s} onClick={() => fillDraft(s)} style={{
              padding: '6px 11px', borderRadius: 999, background: T.bg2, color: T.label2,
              fontSize: 12, fontWeight: 500, whiteSpace: 'nowrap', flexShrink: 0,
              border: `0.5px solid ${T.sep}`, cursor: 'pointer',
            }}><Bi>{s}</Bi></span>
          ))}
        </div>
      </div>

      {/* Context drawer */}
      {showMemory && <ContextDrawer onClose={() => setShowMemory(false)} />}

      <style>{`@keyframes chatdot { 0%, 80%, 100% { transform: translateY(0); opacity: 0.3; } 40% { transform: translateY(-3px); opacity: 1; } }`}</style>
    </div>
  );
}

function Message({ m, prev }) {
  const isUser = m.role === 'user';
  const sameAuthor = prev && prev.role === m.role;

  return (
    <div style={{
      display: 'flex', flexDirection: 'column',
      alignItems: isUser ? 'flex-end' : 'flex-start',
      marginTop: sameAuthor ? 2 : 14,
      padding: '0 4px',
    }}>
      {m.card === 'today' && <InlineTodayCard />}
      {m.card === 'task-saved' && <InlineTaskCard />}

      {m.text && (
        <div style={{
          maxWidth: '78%',
          padding: '8px 14px',
          fontSize: 16, lineHeight: '21px',
          borderRadius: 20,
          background: isUser ? T.blue : T.bg2,
          color: isUser ? '#fff' : T.label,
          boxShadow: isUser ? 'none' : '0 1px 2px rgba(0,0,0,0.03)',
          letterSpacing: -0.2,
          marginTop: m.card ? 8 : 0,
          whiteSpace: 'pre-wrap',
        }}>
          <Bi>{m.text}</Bi>
        </div>
      )}
      {!sameAuthor && (
        <div style={{ fontSize: 10, color: T.label3, marginTop: 4, padding: '0 6px' }}>
          {m.time}
        </div>
      )}
    </div>
  );
}

function InlineTodayCard() {
  const d = LifeData;
  if (!d.calendar.length) return null;
  return (
    <div style={{
      maxWidth: '85%', background: T.bg2, borderRadius: 18, overflow: 'hidden',
      boxShadow: '0 1px 3px rgba(0,0,0,0.04)', marginBottom: 4,
    }}>
      <div style={{ padding: '10px 14px 4px', borderBottom: `0.5px solid ${T.sep}`, display: 'flex', alignItems: 'center', gap: 6 }}>
        <IconCal size={14} color={T.blue} />
        <span style={{ fontSize: 11, fontWeight: 600, color: T.blue, letterSpacing: 0.4, textTransform: 'uppercase' }}>Today · {d.calendar.length} events</span>
      </div>
      {d.calendar.slice(0, 4).map((e, i) => (
        <div key={e.id} style={{
          display: 'flex', alignItems: 'center', padding: '8px 14px',
          borderBottom: i < Math.min(d.calendar.length, 4) - 1 ? `0.5px solid ${T.sep}` : 'none',
        }}>
          <div style={{ fontSize: 12, fontWeight: 600, color: T.label2, width: 46, fontVariantNumeric: 'tabular-nums' }}>{e.time}</div>
          <Dot color={e.type === 'work' ? T.blue : e.type === 'family' ? T.orange : e.type === 'health' ? T.green : T.pink} style={{ marginRight: 8 }} />
          <span style={{ fontSize: 13, flex: 1 }}><Bi>{e.summary}</Bi></span>
        </div>
      ))}
    </div>
  );
}

function InlineTaskCard() {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 10,
      maxWidth: '85%', background: T.bg2, borderRadius: 18,
      padding: '10px 14px', boxShadow: '0 1px 3px rgba(0,0,0,0.04)',
      marginBottom: 4,
    }}>
      <div style={{ width: 32, height: 32, borderRadius: 10, background: T.green, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <IconCheck size={16} color="#fff" />
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13, fontWeight: 600 }}>Task saved</div>
        <div style={{ fontSize: 12, color: T.label2 }}>Added to your tasks</div>
      </div>
    </div>
  );
}

function ContextDrawer({ onClose }) {
  const d = LifeData;
  return (
    <div onClick={onClose} style={{
      position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.32)',
      zIndex: 100, display: 'flex', alignItems: 'flex-end',
    }}>
      <div onClick={e => e.stopPropagation()} style={{
        background: T.bg, width: '100%',
        borderTopLeftRadius: 24, borderTopRightRadius: 24,
        padding: '8px 0 28px',
        maxHeight: '78%', overflowY: 'auto',
      }}>
        <div style={{ width: 40, height: 5, borderRadius: 999, background: T.label4, margin: '6px auto 12px' }} />
        <div style={{ padding: '0 20px 12px' }}>
          <div style={{ fontSize: 13, fontWeight: 600, color: T.label2, letterSpacing: 0.3, textTransform: 'uppercase' }}>What I know about you</div>
          <div style={{ fontSize: 22, fontWeight: 700, letterSpacing: -0.4 }}>Context · {d.memories.length}</div>
          <div style={{ fontSize: 13, color: T.label2, marginTop: 2 }}>Pulled into every reply · only Ollama sees this</div>
        </div>
        {d.memories.length > 0 ? (
          <>
            <Section title="About you">
              <Card padded={false}>
                {d.memories.filter(m => !m.category || !m.category.startsWith('learned')).map((m, i, arr) => (
                  <div key={m.id} style={{
                    padding: '12px 14px',
                    borderBottom: i < arr.length - 1 ? `0.5px solid ${T.sep}` : 'none',
                  }}>
                    <div style={{ fontSize: 10, fontWeight: 600, color: T.label2, letterSpacing: 0.3, textTransform: 'uppercase' }}>{m.category || 'note'}</div>
                    <div style={{ fontSize: 14, marginTop: 3 }}><Bi>{m.fact}</Bi></div>
                  </div>
                ))}
              </Card>
            </Section>
            {d.memories.filter(m => m.category && m.category.startsWith('learned')).length > 0 && (
              <Section title="Learned by Life OS" style={{ marginTop: 20 }}>
                <Card padded={false}>
                  {d.memories.filter(m => m.category && m.category.startsWith('learned')).map((m, i, arr) => (
                    <div key={m.id} style={{
                      padding: '12px 14px',
                      borderBottom: i < arr.length - 1 ? `0.5px solid ${T.sep}` : 'none',
                    }}>
                      <div style={{ fontSize: 14 }}><Bi>{m.fact}</Bi></div>
                    </div>
                  ))}
                </Card>
              </Section>
            )}
          </>
        ) : (
          <div style={{ padding: '20px 20px', fontSize: 14, color: T.label2, textAlign: 'center' }}>
            No memories yet. Use /remember to add context.
          </div>
        )}
        <div style={{ padding: '20px 16px 0', fontSize: 11, color: T.label3, textAlign: 'center', lineHeight: '17px' }}>
          Journal, finance, health & WhatsApp content never leave your Thinkpad.
          <br />Only Ollama (local) sees these.
        </div>
      </div>
    </div>
  );
}

window.ChatScreen = ChatScreen;
