// Right-side chat panel — fake streaming AI that references current doc + selection
// Generates a *suggestion* card that can be applied to the article.

const QUICK_PROMPTS = [
  { id: 'polish', label: '润色这段' },
  { id: 'summarize', label: '总结一下' },
  { id: 'expand', label: '扩写' },
];

// Fake AI reply generator — returns {text, suggestion?}
function fakeAI({ userMsg, entry, quote, intent }) {
  const docName = entry.title + (entry.titleEn ? ` · ${entry.titleEn}` : '');
  const snippet = quote ? `"${quote.length > 60 ? quote.slice(0, 60) + '…' : quote}"` : '';

  if (intent === 'polish' || /润色/.test(userMsg)) {
    const original = quote || '这段内容';
    const polished = quote
      ? quote.replace(/。/g, '呀。').replace(/—/g, '——')
      : null;
    return {
      text: `好的，我来润色一下。<br/>当前文档是 <b>《${docName}》</b>${quote ? `，你选中的是：<span class="quote-echo">${quote}</span>` : '。'}我让它读起来更亲切、更适合 2 岁的小朋友。`,
      suggestion: polished ? {
        label: '建议替换为',
        original: quote,
        replacement: polished + '（多一点拟声词和语气词，读起来更像讲故事）',
        apply: 'replace-selection',
      } : null,
    };
  }

  if (intent === 'simplify' || /简单|易懂/.test(userMsg)) {
    return {
      text: `没问题。<br/>我看到当前文档是 <b>《${docName}》</b>${quote ? `，你选中的是：<span class="quote-echo">${quote}</span>` : '。'}我会把句子拆短，只保留最直观的画面感。`,
      suggestion: quote ? {
        label: '建议替换为',
        original: quote,
        replacement: quote.replace(/[，、]/g, '。').replace(/。。/g, '。'),
        apply: 'replace-selection',
      } : null,
    };
  }

  if (intent === 'summarize' || /总结|概括/.test(userMsg)) {
    return {
      text: `好，我来总结一下 <b>《${docName}》</b>：<br/>这是一则为 2 岁小朋友准备的双语认知条目。它介绍了 <b>${entry.title}</b>，用拟声词 + 具体画面的方式，让宝宝把名字和真实世界的东西对应起来。主要小节包括"认一认"和"一起玩"，既有词汇输入，也有亲子互动。`,
      suggestion: null,
    };
  }

  if (intent === 'expand' || /扩写|详细/.test(userMsg)) {
    return {
      text: `好的，我会在 <b>《${docName}》</b> 里再补一段 <b>「小游戏」</b> 建议，让爸爸妈妈知道怎么和宝宝一起玩。`,
      suggestion: {
        label: '建议添加的段落',
        original: null,
        replacement: `<h2>小游戏 / Little Game</h2><p>准备几张图片或者实物，让宝宝指一指"在哪里"。重复 3 次以后，换成"你来说，我来指"——宝宝会非常开心。</p>`,
        apply: 'append-to-end',
      },
    };
  }

  if (intent === 'ask') {
    return {
      text: `我看到你在 <b>《${docName}》</b> 里选中了：<span class="quote-echo">${quote}</span>告诉我你想做什么——润色、改得更简单，或者直接问问题都可以。`,
      suggestion: null,
    };
  }

  // Default fallback
  const preview = entry.content.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim().slice(0, 80);
  return {
    text: `我正在看 <b>《${docName}》</b>这一条。${quote ? `你选中的是：<span class="quote-echo">${quote}</span>` : `开头是："${preview}…"`}你想让我帮你做什么？可以点下面的快捷按钮，或者直接告诉我。`,
    suggestion: null,
  };
}

function ChatMessage({ msg, isStreaming, onApply, onDismiss }) {
  const suggestion = msg.suggestion;
  return (
    <div className={'msg ' + msg.role}>
      <div className="msg-avatar">{msg.role === 'ai' ? 'AI' : '我'}</div>
      <div className="msg-bubble">
        <div className="msg-name">{msg.role === 'ai' ? 'Wiki Agent' : '你'}</div>
        <div className="msg-text" dangerouslySetInnerHTML={{ __html: msg.text + (isStreaming ? '<span class="cursor-blink"></span>' : '') }} />
        {!isStreaming && suggestion && (
          <div className="ai-suggestion">
            <div className="ai-sugg-head">
              <Icon.Sparkle size={11} /> {suggestion.label}
            </div>
            <div className="ai-sugg-body" dangerouslySetInnerHTML={{ __html: suggestion.replacement }} />
            <div className="ai-sugg-actions">
              <button
                className="sugg-btn apply"
                disabled={suggestion.applied}
                onClick={() => onApply(msg.id, suggestion)}
              >
                {suggestion.applied ? <><Icon.Check size={12}/> 已应用</> : '一键应用到正文'}
              </button>
              <button className="sugg-btn dismiss" onClick={() => onDismiss(msg.id)}>忽略</button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function Chat({
  entry, messages, onMessagesChange,
  quote, onClearQuote,
  allChatsIndex, onJumpToEntry,
  onApplySuggestion,
  onAIFocus,
  registerSender,
}) {
  const [input, setInput] = React.useState('');
  const [streaming, setStreaming] = React.useState(null); // {id, fullText, shown, suggestion}
  const [showHistory, setShowHistory] = React.useState(false);
  const bodyRef = React.useRef(null);
  const taRef = React.useRef(null);

  // auto-scroll on new message / stream tick
  React.useEffect(() => {
    const el = bodyRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [messages, streaming]);

  // auto-grow textarea
  React.useEffect(() => {
    const ta = taRef.current;
    if (!ta) return;
    ta.style.height = 'auto';
    ta.style.height = Math.min(ta.scrollHeight, 160) + 'px';
  }, [input]);

  // expose send() to parent for floating-toolbar intents
  React.useEffect(() => {
    if (registerSender) registerSender((intent) => send('', intent));
  }, [registerSender, entry.id, quote, messages]);

  const send = (overrideText, intent) => {
    const text = (overrideText ?? input).trim();
    if (!text && !intent) return;
    const userMsg = {
      id: 'u-' + Date.now(),
      role: 'user',
      text: text || `（快捷操作：${intent}）`,
      quote: quote || null,
      ts: Date.now(),
    };
    const newMsgs = [...messages, userMsg];
    onMessagesChange(newMsgs);
    setInput('');

    // trigger AI focus pulse
    onAIFocus(entry.id);

    // fake streaming
    const reply = fakeAI({ userMsg: text, entry, quote, intent });
    const aiId = 'a-' + Date.now();
    setStreaming({ id: aiId, fullText: reply.text, shown: '', suggestion: reply.suggestion });

    // Clear the quote chip as soon as we send
    onClearQuote();
  };

  // Fake streaming: reveal characters with some grouping for HTML tags
  React.useEffect(() => {
    if (!streaming) return;
    const { fullText, shown } = streaming;
    if (shown.length >= fullText.length) {
      // commit message
      const finalMsg = {
        id: streaming.id,
        role: 'ai',
        text: fullText,
        suggestion: streaming.suggestion ? { ...streaming.suggestion, applied: false } : null,
        ts: Date.now(),
      };
      onMessagesChange([...messages, finalMsg]);
      setStreaming(null);
      onAIFocus(null);
      return;
    }
    // Advance: skip over any HTML tag as one chunk
    let next;
    if (fullText[shown.length] === '<') {
      const end = fullText.indexOf('>', shown.length);
      next = fullText.slice(0, end + 1);
    } else {
      // 2-3 chars per tick feels natural for CJK
      next = fullText.slice(0, shown.length + 2);
    }
    const t = setTimeout(() => {
      setStreaming(s => s ? { ...s, shown: next } : null);
    }, 22);
    return () => clearTimeout(t);
  }, [streaming, messages, onMessagesChange, onAIFocus]);

  const streamingMsg = streaming ? {
    id: streaming.id, role: 'ai', text: streaming.shown, suggestion: null,
  } : null;

  return (
    <aside className="chat" style={{ position: 'relative' }}>
      <div className="chat-head">
        <div className="chat-head-row">
          <div className="chat-avatar">A</div>
          <div className="chat-title-group">
            <div className="chat-title">Wiki Agent</div>
            <div className="chat-sub">正在查看此条目 · 会读到你的选中</div>
          </div>
          <button className="chat-hist-btn" title="聊天历史" onClick={() => setShowHistory(v => !v)}>
            <Icon.History />
          </button>
        </div>
        <div className="context-chip">
          <Icon.Book size={11} />
          <span className="ctx-doc">{entry.title} · {entry.titleEn}</span>
        </div>
      </div>

      {showHistory && (
        <div className="history-pop">
          <h4>按条目分组的会话</h4>
          <div className="history-list">
            {allChatsIndex.length === 0 ? (
              <div className="history-empty">还没有其它聊天记录</div>
            ) : allChatsIndex.map(h => (
              <div
                key={h.entryId}
                className={'history-item' + (h.entryId === entry.id ? ' active' : '')}
                onClick={() => { onJumpToEntry(h.entryId); setShowHistory(false); }}
              >
                <div className="history-title">{h.title}</div>
                <div className="history-meta">{h.count} 条消息 · {h.preview}</div>
              </div>
            ))}
          </div>
        </div>
      )}

      <div className="chat-body" ref={bodyRef}>
        {messages.length === 0 && !streamingMsg && (
          <div className="msg ai">
            <div className="msg-avatar">AI</div>
            <div className="msg-bubble">
              <div className="msg-name">Wiki Agent</div>
              <div className="msg-text">
                你好呀 👋 我正在看 <b>《{entry.title}》</b>。
                <p>你可以：</p>
                <p>· 在正文里选中一段文字，我会帮你润色 / 改得更简单<br/>· 直接告诉我你想修改什么<br/>· 或者点下面的快捷按钮试试</p>
              </div>
            </div>
          </div>
        )}
        {messages.map(m => (
          <ChatMessage
            key={m.id}
            msg={m}
            isStreaming={false}
            onApply={(id, sugg) => {
              onApplySuggestion(sugg);
              onMessagesChange(messages.map(x =>
                x.id === id ? { ...x, suggestion: { ...x.suggestion, applied: true } } : x
              ));
            }}
            onDismiss={(id) => {
              onMessagesChange(messages.map(x =>
                x.id === id ? { ...x, suggestion: null } : x
              ));
            }}
          />
        ))}
        {streamingMsg && (
          <ChatMessage msg={streamingMsg} isStreaming={true} onApply={() => {}} onDismiss={() => {}} />
        )}
      </div>

      <div className="chat-foot">
        {quote && (
          <div className="quote-preview">
            <Icon.Quote />
            <div className="quote-preview-text">{quote}</div>
            <button className="quote-preview-close" onClick={onClearQuote} title="取消引用">
              <Icon.Close size={12} />
            </button>
          </div>
        )}
        <div className="prompt-chips">
          {QUICK_PROMPTS.map(p => (
            <button key={p.id} className="prompt-chip" onClick={() => send(p.label, p.id)}>
              {p.label}
            </button>
          ))}
        </div>
        <div className="chat-input-wrap">
          <textarea
            ref={taRef}
            className="chat-input"
            placeholder={quote ? '针对选中的内容，告诉我你想做什么…' : `对《${entry.title}》说点什么…`}
            value={input}
            onChange={e => setInput(e.target.value)}
            onKeyDown={e => {
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                send();
              }
            }}
            rows={1}
          />
          <button
            className={'send-btn' + (input.trim() ? ' ready' : '')}
            disabled={!input.trim()}
            onClick={() => send()}
          >
            <Icon.Send size={13} />
          </button>
        </div>
      </div>
    </aside>
  );
}
window.Chat = Chat;
