/* Right-side AI chat panel. Sends prompts to the /proxyAI function and
   streams responses back. Tool calls dispatch through the parent app's
   handleSend callback, which routes them to handleEdit + auto-checkpoint. */
{
  const { useEffect, useMemo, useRef, useState } = React;

  /* Configure marked once. GFM tables/strikethrough, breaks: true so a single
     newline becomes <br> (the model often streams mid-paragraph), and headerIds
     off because we don't need anchors for ephemeral chat. */
  if (window.marked && !window.__chatMarkedConfigured) {
    window.marked.setOptions({ gfm: true, breaks: true, headerIds: false, mangle: false });
    window.__chatMarkedConfigured = true;
  }

  function renderMarkdown(src) {
    if (!src) return "";
    if (!window.marked || !window.DOMPurify) return src;
    const html = window.marked.parse(src, { async: false });
    return window.DOMPurify.sanitize(html, { USE_PROFILES: { html: true } });
  }

  function MarkdownText({ source }) {
    const html = useMemo(() => renderMarkdown(source), [source]);
    return <div className="chat-text markdown" dangerouslySetInnerHTML={{ __html: html }} />;
  }

  function MessageBubble({ message }) {
    const { role, text, toolCalls, error } = message;
    if (role === "user") {
      return (
        <div className="chat-msg user">
          <div className="chat-bubble">{text}</div>
        </div>
      );
    }
    return (
      <div className="chat-msg assistant">
        <div className="chat-bubble">
          {text && <MarkdownText source={text} />}
          {toolCalls && toolCalls.length > 0 && (
            <ul className="chat-toolcalls">
              {toolCalls.map((tc, i) => (
                <li key={i} className={`chat-toolcall ${tc.error ? "error" : ""}`}>
                  <span className="chat-toolcall-label">
                    {(window.AITools && window.AITools.LABEL_BY_NAME[tc.name]) || tc.name}
                  </span>
                  <code className="chat-toolcall-args">{tc.summary}</code>
                  {tc.error && <span className="chat-toolcall-err">{tc.error}</span>}
                </li>
              ))}
            </ul>
          )}
          {error && <div className="chat-error">{error}</div>}
        </div>
      </div>
    );
  }

  function ChatPanel({
    open,
    messages,
    onSend,
    onStop,
    onClear,
    onClose,
    busy,
    canEdit,
    user,
    onSignIn,
  }) {
    const [input, setInput] = useState("");
    const listRef = useRef(null);
    const inputRef = useRef(null);

    // Autoscroll to bottom on new messages / streaming updates.
    useEffect(() => {
      const el = listRef.current;
      if (el) el.scrollTop = el.scrollHeight;
    }, [messages, busy]);

    // Focus input on open.
    useEffect(() => {
      if (open && inputRef.current && canEdit) inputRef.current.focus();
    }, [open, canEdit]);

    if (!open) return null;

    function submit(e) {
      if (e) e.preventDefault();
      const trimmed = input.trim();
      if (!trimmed || busy || !canEdit) return;
      onSend(trimmed);
      setInput("");
    }

    function onKeyDown(e) {
      if (e.key === "Enter" && !e.shiftKey) {
        e.preventDefault();
        submit();
      }
    }

    return (
      <div className="panel chat-panel">
        <div className="panel-head">
          <Icon.sparkles />
          <h2>AI</h2>
          <span className="count">{messages.length || 0}</span>
          {messages.length > 0 && (
            <button className="iconbtn" onClick={onClear} title="Clear chat history" style={{ marginLeft: 4 }}>
              <Icon.trash />
            </button>
          )}
          <button className="iconbtn" onClick={onClose} title="Hide panel" style={{ marginLeft: 4 }}>
            <Icon.close />
          </button>
        </div>

        <div className="chat-list" ref={listRef}>
          {messages.length === 0 && (
            <div className="chat-empty">
              <Icon.sparkles />
              <p>Describe diagram changes in plain English.</p>
              <p className="chat-empty-hint">
                e.g. "Add a Customer class with id (UUID) and email (String), and make it inherit from Person."
              </p>
            </div>
          )}
          {messages.map((m, i) => <MessageBubble key={i} message={m} />)}
          {busy && (
            <div className="chat-msg assistant">
              <div className="chat-bubble streaming"><Icon.spinner /> thinking…</div>
            </div>
          )}
        </div>

        <form className="chat-input-bar" onSubmit={submit}>
          {!user ? (
            <div className="chat-signin">
              <span>Sign in to use the AI assistant.</span>
              <button type="button" className="btn primary" onClick={onSignIn}>
                <Icon.googleG /> Sign in
              </button>
            </div>
          ) : !canEdit ? (
            <div className="chat-signin">
              <span>Open an editable diagram to chat.</span>
            </div>
          ) : (
            <>
              <textarea
                ref={inputRef}
                className="chat-input"
                value={input}
                onChange={(e) => setInput(e.target.value)}
                onKeyDown={onKeyDown}
                placeholder="Ask the AI to change the diagram…"
                rows={2}
                disabled={busy}
              />
              {busy ? (
                <button type="button" className="btn" onClick={onStop} title="Stop generation">
                  <Icon.stop /> Stop
                </button>
              ) : (
                <button type="submit" className="btn primary" disabled={!input.trim()} title="Send (Enter)">
                  <Icon.send /> Send
                </button>
              )}
            </>
          )}
        </form>
      </div>
    );
  }

  window.ChatPanel = ChatPanel;
}
